一、簡介
1.1 Redis是什麼
Redis是一個開源的,使用ANSI C 編寫,高性能的Key-Value的NoSQL資料庫。
1.2 Redis特點
(1)基于記憶體
(2)可持久化資料
(3)具有豐富的資料結構類型,适應非關系型資料的存儲需求
(4)支援絕大多數主流開發語言,如C、C++、Java、Python、R、JavaScript等。
(5)支援叢集模式,高效、穩定。
1.3 資料模型(重點)
(1)鍵值對形式。
(2)Redis的資料結構類型,指的就是Redis值的結構類型。
1.4 Redis作用
(1)本質是資料庫,能存儲資料。
Redis能靈活處理非關系型資料的讀、寫問題,是對MySQL等關系型資料庫的補充。
新浪微網誌就是使用Redis叢集做資料庫。
(2)緩存資料。
所謂緩存,就是将資料加載到記憶體中後直接使用,而不是每次都通過IO流從磁盤上讀取。好處:讀寫效率高。
而Redis則是将資料直接存儲在記憶體中,隻有當記憶體空間不足時,将部分資料持久化到磁盤上。
二、安裝
1.1 說明
Redis官方隻提供了源碼,并沒有提供經過編譯之後的安裝包。
是以,安裝Redis,要先編譯、後安裝。(即源碼安裝方式)
1.2 redis安裝步驟
# 安裝步驟
cd /usr/local/src
wget http://download.redis.io/releases/redis-5.0.4.tar.gz
tar -zxv -f redis-5.0.4.tar.gz
cd /usr/local/src/redis-5.0.4/
make MALLOC=libc (或者直接make,不用./configure)
make install (安裝到指定目錄:make PREFIX=/usr/local/redis install,不指定的話預設安裝到/usr/local/bin目錄下,也可以執行該步驟,也就是安裝)
# 不安裝的話指令執行檔案路徑是:/usr/local/src/redis-5.0.4/src
# 配置檔案:/usr/local/src/redis-5.0.4/redis.conf
# 優化配置,使用root賬号操作
# vim /etc/sysctl.conf
vm.overcommit_memory = 1
net.core.somaxconn = 2048
# sysctl -p
# echo never > /sys/kernel/mm/transparent_hugepage/enabled
# vim /etc/rc.d/rc.local
if test -f /sys/kernel/mm/transparent_hugepage/enabled; then
echo never > /sys/kernel/mm/transparent_hugepage/enabled
fi
if test -f /sys/kernel/mm/transparent_hugepage/defrag; then
echo never > /sys/kernel/mm/transparent_hugepage/defrag
fi
# chmod +x /etc/rc.d/rc.local
# vim /etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535
# 啟動
[sandu@bogon ~]# ./src/redis-server ./redis.conf
1270:C 02 Aug 2019 16:27:19.274 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1270:C 02 Aug 2019 16:27:19.275 # Redis version=5.0.4, bits=64, commit=00000000, modified=0, pid=1270, just started
1270:C 02 Aug 2019 16:27:19.275 # Configuration loaded
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 5.0.4 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in standalone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
| `-._ `._ / _.-' | PID: 1270
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
1270:M 02 Aug 2019 16:27:19.277 # Server initialized
1270:M 02 Aug 2019 16:27:19.277 * Ready to accept connections
# 使用自帶的用戶端連接配接,預設沒有密碼直接連接配接
[sandu@bogon ~]# ./src/redis-cli
127.0.0.1:6379> ping # 檢測redis服務是否啟動
PONG
127.0.0.1:6379> set a 1111
OK
127.0.0.1:6379> get a
"1111"
127.0.0.1:6379> quit # 退出
# 密碼連接配接
# redis-cli -h host -p port -a password
[sandu@bogon ~]# ./src/redis-cli
127.0.0.1:6379> auth foobar2000
OK
127.0.0.1:6379> set b 222222
OK
127.0.0.1:6379> get b
"222222"
127.0.0.1:6379> exit
1.3 redis.conf常用配置說明
- bind:允許通路該redis的主機
-
protected-mode:保護模式,預設開啟。若設定外部網絡連接配接redis服務,設定方式如下:
1、關閉protected-mode模式,此時外部網絡可以直接通路
2、開啟protected-mode保護模式,需配置bind ip或者設定通路密碼,或者bind ip和密碼都設定
- requirepass:設定密碼
- databases:Redis預設有16個資料庫,尋址角标從0開始。預設連接配接db0。用戶端使用select指令,切換資料庫
- port :指定redis的服務端口,預設6379.
- daemonize:Redis預設關閉背景程序模式,改成yes,redis服務在背景啟動。
- loglevel :日志等級
- logfile:Redis日志輸出目錄,預設不輸出日志到檔案。
- dbfilename:指定資料持久化的檔案名
- dir :指定資料持久化的檔案存放目錄,也是叢集node.con檔案存放目錄
- cluster-enabled:是否啟用叢集
- cluster-config-file:叢集檔案
1.4 redis啟動方式
- 直接啟動
進入redis根目錄,執行指令,加上‘&’号使redis以背景程式方式運作
./src/redis-server &
-
通過指定配置檔案啟動
可以為redis服務啟動指定配置檔案,例如配置為/etc/redis/6379.conf
./src/redis-server /etc/redis/6379.conf
進入redis根目錄,輸入指令,如果更改了端口,使用
redis-cli
用戶端連接配接時,也需要指定端口,例如:
redis-cli -p 6380
# redis-cli -h host -p port -a password
- 使用redis啟動腳本設定開機自啟動,有問題,隻能啟動和停止,不能檢視狀态,也不能重載,還有就是關閉的話貌似關不掉,不予考慮該腳本
啟動腳本 redis_init_script 位于位于Redis的 /utils/ 目錄下,redis_init_script腳本代碼如下:
#!/bin/sh
#
# Simple Redis init.d script conceived to work on Linux systems
# as it does use of the /proc filesystem.
# chkconfig: 2345 90 10
### BEGIN INIT INFO
# Provides: redis_6379
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Redis data structure server
# Description: Redis data structure server. See https://redis.io
### END INIT INFO
#redis伺服器監聽的端口
REDISPORT=6379
#服務端所處位置
EXEC=/usr/local/bin/redis-server
#用戶端位置
CLIEXEC=/usr/local/bin/redis-cli
#redis的PID檔案位置,根據實際情況修改
PIDFILE=/var/run/redis_${REDISPORT}.pid
#redis的配置檔案位置,需将${REDISPORT}修改為檔案名
CONF="/etc/redis/${REDISPORT}.conf"
case "$1" in
start)
if [ -f $PIDFILE ]
then
echo "$PIDFILE exists, process is already running or crashed"
else
echo "Starting Redis server..."
$EXEC $CONF
fi
;;
stop)
if [ ! -f $PIDFILE ]
then
echo "$PIDFILE does not exist, process is not running"
else
PID=$(cat $PIDFILE)
echo "Stopping ..."
$CLIEXEC -p $REDISPORT shutdown
while [ -x /proc/${PID} ]
do
echo "Waiting for Redis to shutdown ..."
sleep 1
done
echo "Redis stopped"
fi
;;
*)
echo "Please use start or stop as first argument"
;;
esac
将啟動腳本複制到/etc/init.d目錄下,本例将啟動腳本命名為redisd(通常都以d結尾表示是背景自啟動服務)
cd
cp redis_init_script /etc/init.d/redisd
chkconfig redisd on
service redisd start|stop
1.5 redis關閉
- 第一種關閉方式
# 斷電,非正常關閉,容易導緻資料丢失
ps -ef | grep redis
kill -9 PID
- 第二種關閉方式
# 正常關閉,資料儲存
redis-cli shutdown # 關閉redis服務,通過用戶端進行shutdown
# 如果redis設定了密碼,則需要先用用戶端登入,然後再進行shutdown
redis-cli -a password
127.0.0.1:6379> shutdown
# 重新啟動redis服務,使用用戶端連接配接,會發現資料還在
三、持久化
Redis持久化,就是将記憶體中的資料,永久儲存到磁盤上。
Redis持久化有兩種方式:RDB(Redis DB)、AOF(AppendOnlyFile)
Redis 可以同時使用 AOF 持久化和 RDB 持久化。 在這種情況下, 當 Redis 重新開機時, 它會優先使用 AOF 檔案來還原資料集, 因為 AOF 檔案儲存的資料集通常比 RDB 檔案所儲存的資料集更完整。
3.1 RDB(快照模式)
在預設情況下,Redis 将資料庫快照儲存在名字為dump.rdb的二進制檔案中,可以在redis.conf配置檔案中修改持久化資訊。
save 900 1 表示在900秒内,至少更新了1條資料。Redis就将資料持久化到硬碟
save 300 10 表示在300内,至少更新了10條資料,Redis就會觸發将資料持久化到硬碟
save 60 10000 表示60秒内,至少更新了10000條資料,Redis就會觸發将資料持久化到硬碟
3.1.1 政策
- 自動:BGSAVE
按照配置檔案中的條件滿足就執行BGSAVE;
非阻塞,Redis服務正常接收處理用戶端請求;
Redis會folk()一個新的子程序來建立RDB檔案,子程序處理完後會向父程序發送一個信号,通知它處理完畢;
父程序用新的dump.rdb替代舊檔案。
- 手動:SAVE
用戶端(redis-cli)發起SAVE指令;
阻塞Redis服務,無法響應用戶端請求;
建立新的dump.rdb替代舊檔案。
3.1.2 優點
- 執行效率高;
- 恢複大資料集速度較AOF快。
3.1.3 缺點
- 會丢失最近寫入、修改的而未能持久化的資料;
- folk過程非常耗時,會造成毫秒級不能響應用戶端請求。
3.2 AOF(追加模式、文本重演)
AOF預設關閉,需要在配置檔案中手動開啟。
記錄所有的寫操作指令,在服務啟動的時候使用這些指令就可以還原資料庫。
Append only file,采用追加的方式儲存,預設檔案appendonly.aof。
3.2.1 寫入機制
AOF機制,添加了一個記憶體緩沖區(buffer):
- 将内容寫入緩沖區
- 當緩沖區被填滿、或者使用者手動執行fsync、或者系統根據指定的寫入磁盤政策自動調用fdatasync指令,才将緩沖區裡的内容真正寫入磁盤裡
- 在緩沖區裡的内容未寫入磁盤之前,可能會丢失
3.2.2 寫入磁盤的政策
appendfsync選項,這個選項的值可以是always、everysec或者no
- always:伺服器每寫入一個指令,就調用一次fdatasync,将緩沖區裡面的指令寫入到硬碟。這種模式下,伺服器出現故障,也不會丢失任何已經成功執行的指令資料
- everysec(預設):伺服器每一秒重調用一次fdatasync,将緩沖區裡面的指令寫入到硬碟。這種模式下,伺服器出現故障,最多隻丢失一秒鐘内的執行的指令資料
- no:伺服器不主動調用fdatasync,由作業系統決定何時将緩沖區裡面的指令寫入到硬碟。這種模式下,伺服器遭遇意外停機時,丢失指令的數量是不确定的,no 選項并不能給伺服器性能帶來多大的提升,而且也會增加系統奔潰時資料丢失的數量。
運作速度:always的速度慢,everysec和no都很快
3.2.3 重寫機制
AOF檔案過大,合并重複的操作,AOF會使用盡可能少的指令來記錄
- 重寫過程
(1)folk一個子程序負責重寫AOF檔案
(2)子程序會建立一個臨時檔案寫入AOF資訊
(3)父程序會開辟一個記憶體緩沖區接收新的寫指令
(4)子程序重寫完成後,父程序會獲得一個信号,将父程序接收到的新的寫操作由子程序寫入到臨時檔案中
(5)新檔案替代舊檔案
重寫的本質:就是将操作同一個鍵的指令,合并。進而減小AOF檔案的體積
- 重寫觸發機制
(1)手動:
用戶端向伺服器發送BGREWRITEAOF指令
(2)自動:
配置檔案中的選項,自動執行BGREWRITEAOF指令
- auto-aof-rewrite-min-size :觸發AOF重寫所需的最小體積:隻要在AOF檔案的體積大于等于size時,才會考慮是否需要進行AOF重寫,這個選項用于避免對體積過小的AOF檔案進行重寫
-
auto-aof-rewrite-percentage
:指定觸發重寫所需的AOF檔案體積百分比:當AOF檔案的體積大于auto-aof-rewrite-min-size指定的體積,并且超過上一次重寫之後的AOF檔案體積的percent %時,就會觸發AOF重寫。(如果伺服器剛剛啟動不久,還沒有進行過AOF重寫,那麼使用伺服器啟動時載入的AOF檔案的體積來作為基準值)。将這個值設定為0表示關閉自動AOF重寫。
- 優點
- 寫入機制,預設fysnc(手工同步)每秒執行,性能很好不阻塞服務,最多丢失一秒的資料;
- 重寫機制,優化AOF檔案;
- 如果誤操作了(FLUSHALL等),隻要AOF未被重寫,停止服務移除AOF檔案尾部FLUSHALL指令,重新開機Redis,可以将資料集恢複到FLUSHALL 執行之前的狀态。
- 缺點
- 相同資料集,AOF檔案體積較RDB大了很多;
- 恢複資料庫速度較RDB慢(文本,指令重演)
四、叢集
4.1 redis叢集簡介
4.1.1 叢集的概念
所謂的叢集,就是通過添加伺服器的數量,提供相同的服務,進而讓伺服器達到一個穩定、高效的狀态。
4.1.1.1 使用redis叢集的必要性
問題:我們已經部署好了redis,并且能啟動一個redis,實作資料的讀寫,為什麼還要學習redis叢集?
答:(1)單個redis存在不穩定性。當redis服務當機了,就沒有可用的服務了。
(2)單個redis的讀寫能力是有限的。
總結:redis叢集是為了強化redis的讀寫能力。
4.1.1.2 如何學習redis叢集
說明:(1)redis叢集中,每一個redis稱之為一個節點。
(2)redis叢集中,有兩種類型的節點:主節點(master)、從節點(slave)。
(3)redis叢集,是基于redis主從複制實作。
是以,學習redis叢集,就是從學習redis主從複制模型開始的。
4. 2 redis主從複制
4.2.1 概念
主從複制模型中,有多個redis節點。
其中,有且僅有一個為主節點Master。從節點Slave可以有多個。
隻要網絡連接配接正常,Master會一直将自己的資料更新同步給Slaves,保持主從同步。
4.2.2 特點
(1)主節點Master可讀、可寫.
(2)從節點Slave隻讀。(read-only)
是以,主從模型可以提高讀的能力,在一定程度上緩解了寫的能力。因為能寫仍然隻有Master節點一個,可以将讀的操作全部移交到從節點上,變相提高了寫能力。
4.2.3 基于配置實作
- 需求
- 主節點:6380
- 從節點:6381、6382
- 配置步驟
(1)在/usr/local目錄下,建立一個/redis/master-slave目錄
mkdir -p /usr/local/redis/master-slave
(2)在master-slave目錄下,建立三個子目錄6380、6381、6382
mkdir 6380 6381 6382
(3)依次拷貝redis解壓目錄下的redis.conf配置檔案,到這三個子目錄中
cp /usr/local/src/redis-5.0.4/redis.conf 6380/
cp /usr/local/src/redis-5.0.4/redis.conf 6381/
cp /usr/local/src/redis-5.0.4/redis.conf 6382/
(4)進入6380目錄,修改redis.conf,将port端口修改成6380即可
(5)進入6381目錄,修改redis.conf,将port端口改成6381,同時指定開啟主從複制
# 主節點ip 主節點端口
replicaof 127.0.0.1 6380
(6)進入6382目錄,修改redis.conf,将port端口改成6382,同時指定開啟主從複制
- 測試
(1)打開三個shell視窗,在每一個視窗中,啟動一個redis節點。檢視日志輸出。(不要改成背景模式啟動,看不到日志,不直覺)
(2)另外再打開三個shell視窗,在每一個視窗中,登陸一個redis節點
(3)在主節點6380上,進行讀寫操作,操作成功
(4)在從節點6381上,讀操作執行成功,并且成功從6380上同步了資料;寫操作執行失敗。(從節點,隻能讀,不能寫)
# 寫操作執行失敗提示
(error) READONLY You can't write against a read only replica.
4.3 Sentinel哨兵模式
4.3.1 主從模式的缺陷
當主節點當機了,整個叢集就沒有可寫的節點了。
問:由于從節點上備份了主節點的所有資料,那在主節點當機的情況下,如果能夠将從節點變成一個主節點,是不是就可以解決這個問題了呢?
答:是的,這個就是Sentinel哨兵的作用。
4.3.2 哨兵的任務
Redis 的 Sentinel 系統用于管理多個 Redis 伺服器(instance), 該系統執行以下三個任務:
- 監控(Monitoring): Sentinel 會不斷地檢查你的主伺服器和從伺服器是否運作正常。
- 提醒(Notification): 當被監控的某個 Redis 伺服器出現問題時, Sentinel 可以通過 API 向管理者或者其他應用程式發送通知。
- 自動故障遷移(Automatic failover): 當一個主伺服器不能正常工作時, Sentinel 會開始一次自動故障遷移操作, 它會進行選舉,将其中一個從伺服器更新為新的主伺服器, 并讓失效主伺服器的其他從伺服器改為複制新的主伺服器; 當用戶端試圖連接配接失效的主伺服器時, 叢集也會向用戶端傳回新主伺服器的位址, 使得叢集可以使用新主伺服器代替失效伺服器。
4.3.2.1 監控(Monitoring)
(1)Sentinel可以監控任意多個Master和該Master下的Slaves。(即多個主從模式)
(2)同一個哨兵下的、不同主從模型,彼此之間互相獨立。
(3)Sentinel會不斷檢查Master和Slaves是否正常。
4.3.2.1 自動故障切換(Automatic failover)
監控同一個Master的Sentinel會自動連接配接,組成一個分布式的Sentinel網絡,互相通信并交換彼此關于被監視伺服器的資訊。
疑問:為什麼要使用sentinel網絡呢?
答:當隻有一個sentinel的時候,如果這個sentinel挂掉了,那麼就無法實作自動故障切換了。
在sentinel網絡中,隻要還有一個sentinel活着,就可以實作故障切換。
4.3.2.2 故障切換的過程
(1)投票(半數原則)
當任何一個Sentinel發現被監控的Master下線時,會通知其它的Sentinel開會,投票确定該Master是否下線(半數以上,是以sentinel通常配奇數個)。
(2)選舉
當Sentinel确定Master下線後,會在所有的Slaves中,選舉一個新的節點,更新成Master節點。
其它Slaves節點,轉為該節點的從節點。
(3)原Master重新上線
當原Master節點重新上線後,自動轉為目前Master節點的從節點。
4.3.3 哨兵模式部署
4.3.3.1 需求
前提:已經存在一個正在運作的主從模式。
另外,配置三個Sentinel執行個體,監控同一個Master節點
4.3.3.2 配置Sentinel
(1)在/usr/local目錄下,建立/redis/sentinels/目錄
cd /usr/local/redis
mkdir sentinels
(2)在sentinels目錄下,依次建立s1、s2、s3三個子目錄中
cd sentinels
mkdir s1 s2 s3
(3)依次拷貝redis解壓目錄下的sentinel.conf檔案,到這三個子目錄中
cp /usr/local/src/redis-5.0.4/sentinel.conf s1/
cp /usr/local/src/redis-5.0.4/sentinel.conf s2/
cp /usr/local/src/redis-5.0.4/sentinel.conf s3/
(4)依次修改s1、s2、s3子目錄中的sentinel.conf檔案,修改端口,并指定要監控的主節點。(從節點不需要指定,sentinel會自動識别)
# s1 哨兵配置
port 26379
sentinel monitor mymaster 127.0.0.1 6380 2
# mymaster為主節點别名,127.0.0.1為主節點IP,6380為主節點端口,2為觸發故障切換的最少哨兵數量
# s2 哨兵配置
port 26380
sentinel monitor mymaster 127.0.0.1 6380 2
# s3 哨兵配置
port 26381
sentinel monitor mymaster 127.0.0.1 6380 2
(5)再打開三個shell視窗,在每一個視窗中,啟動一個哨兵執行個體,并觀察日志輸出
進入redis的安裝目錄,/usr/local/bin/,也可以不用進,因為前面的那個目錄在環境變量中。
對于用redis-server啟動哨兵的方式如下:
核心日志輸出:
4.3.4 測試
(1)先關閉6380節點(kill掉)。發現,确實重新指定了一個主節點
(2)再次上線6380節點。發現,6380節點成為了新的主節點的從節點。
4.3.5 結論
Sentinel哨兵模式,确實能實作自動故障切換。提供穩定的服務。
4.3.6 注意事項
如果哨兵和redis節點不在同一台伺服器上,注意IP綁定的問題。
(1)主從模型,所有的節點,使用ip綁定
(2)所有的哨兵,也都使用ip去綁定主機
(3)所有的哨兵,都是通過主節點的ip,去監控主從模型
五、 Redis-cluster叢集
5.1 哨兵模式的缺陷
在哨兵模式中,仍然隻有一個Master節點。當并發寫請求較大時,哨兵模式并不能緩解寫壓力。
我們知道隻有主節點才具有寫能力,那如果在一個叢集中,能夠配置多個主節點,是不是就可以緩解寫壓力了呢?
答:是的。這個就是redis-cluster叢集模式。
5.2 Redis-cluster叢集概念
(1)由多個Redis伺服器組成的分布式網絡服務叢集;
(2)叢集之中有多個Master主節點,每一個主節點都可讀可寫;
(3)節點之間會互相通信,兩兩相連;
(4)Redis叢集無中心節點。
5.3 叢集節點複制
在Redis-Cluster叢集中,可以給每一個主節點添加從節點,主節點和從節點直接遵循主從模型的特性。
當使用者需要處理更多讀請求的時候,添加從節點可以擴充系統的讀性能。
5.4 故障轉移
Redis叢集的主節點内置了類似Redis Sentinel的節點故障檢測和自動故障轉移功能,當叢集中的某個主節點下線時,叢集中的其他線上主節點會注意到這一點,并對已下線的主節點進行故障轉移。
叢集進行故障轉移的方法和Redis Sentinel進行故障轉移的方法基本一樣,不同的是,在叢集裡面,故障轉移是由叢集中其他線上的主節點負責進行的,是以叢集不必另外使用Redis Sentinel。
5.5 叢集分片政策
Redis-cluster分片政策,是用來解決key存儲位置的。
叢集将整個資料庫分為16384個槽位slot,所有key-value資料都存儲在這些slot中的某一個上。一個slot槽位可以存放多個資料,key的槽位計算公式為:slot_number=crc16(key)%16384,其中crc16為16位的循環備援校驗和函數。
叢集中的每個主節點都可以處理0個至16383個槽,當16384個槽都有某個節點在負責處理時,叢集進入上線狀态,并開始處理用戶端發送的資料指令請求。
5.6 叢集redirect轉向
由于Redis叢集無中心節點,請求會随機發給任意主節點;
主節點隻會處理自己負責槽位的指令請求,其它槽位的指令請求,該主節點會傳回用戶端一個轉向錯誤;
用戶端根據錯誤中包含的位址和端口重新向正确的負責的主節點發起指令請求。
5.7 叢集搭建
5.7.1 準備工作
redis5.0版本之後可以直接使用
redis-cli
指令建立叢集,不使用
redis-trib.rb
指令了。
5.7.2 叢集規劃
(1)Redis叢集最少需要6個節點,3主3從,可以分布在一台或者多台主機上。
真叢集:6台主機,每台主機的redis服務使用的IP不同,端口号随意,一樣不一樣都可以
假叢集,一台主機,redis服務使用的IP相同,端口号不同
本例子是在一台主機上建立假叢集,不同的端口表示不同的redis節點,如下:
主節點:127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003
從節點:127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006
後期新加的主節點:127.0.0.1:7007
後期新家的從節點:127.0.0.1:7008
(2)在/usr/local/src/redis-5.0.4/下建立cluster目錄,其下建立7001、7002…7006目錄,如下:
(3)将redis解壓路徑下的配置檔案redis.conf,依次拷貝到每個700X目錄内,并修改每個700X目錄下的redis.conf配置檔案:
# cd /usr/local/src/redis-5.0.4/cluster
# mkdir {7001,7002,7003,7004,7005,7006}
# mkdir -p /var/log/redis/{7001,7002,7003,7004,7005,7006}
# redis.conf檔案示例
bind 127.0.0.1
port 7001
daemonize yes
pidfile /var/run/redis_7001.pid
dir "./" # node.conf檔案儲存路徑
logfile "/var/log/redis/7001/redis.log"
appendonly yes
appendfsync always
cluster-enabled yes
cluster-config-file nodes-7001.conf # 該檔案中包含叢集資訊
# 其他配置檔案類似,把端口号修改一下就行了
5.7.3 啟動每個節點redis服務
批量啟動腳本:
# vim s/usr/local/src/redis-5.0.4/cluster/ctart_cluster.sh
#!/bin/bash
cd ./7001 && /usr/local/src/redis-5.0.4/src/redis-server ./redis.conf
cd ../7002 && /usr/local/src/redis-5.0.4/src/redis-server ./redis.conf
cd ../7003 && /usr/local/src/redis-5.0.4/src/redis-server ./redis.conf
cd ../7004 && /usr/local/src/redis-5.0.4/src/redis-server ./redis.conf
cd ../7005 && /usr/local/src/redis-5.0.4/src/redis-server ./redis.conf
cd ../7006 && /usr/local/src/redis-5.0.4/src/redis-server ./redis.conf
cd ..
# chmod +x start_cluster.sh
注意:一定要進入700X目錄中啟動,因為它會自動在目前目錄中建立cluster-config,即nodes.conf。因為你在哪個目錄下執行這個指令,則node.conf檔案就會在該目錄下建立。
但是若是在配置檔案中配置
dir
為其他目錄,則該檔案會建立在
dir
指定目錄下
或者把redis-server程式檔案依次拷貝到每個700x目錄下,然後使用不同目錄的redis-server程式檔案啟動
關閉腳本:
# vim /usr/local/src/redis-5.0.4/cluster/shutdown_cluster.sh
#!/bin/bash
pgrep redis-server | xargs -exec kill -9
# chmod +x shutdown_cluster.sh
執行啟動腳本批量啟動:
# ./start_cluster.sh
5.7.4 執行建立叢集指令
進入到redis源碼存放目錄/usr/local/src/redis-5.0.4/src下,把redis-cli檔案拷貝到/usr/local/bin/目錄下
cd /usr/local/src/redis-5.0.4/cluster
/usr/local/src/redis-5.0.4/src/redis-cli --cluster create 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006 --cluster-replicas 1
# --cluster-replicas 1 表示主從配置比,1表示的是1:1,前三個是主,後三個是從
# 若配置檔案中設定的密碼,則還需要加上-a passwod
......
Can I set the above configuration? (type 'yes' to accept): yes
......
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
5.7.5 查詢叢集資訊
注意:查詢叢集資訊需要加上
-c
參數
或者直接執行指令查詢,如下面所示;或者登陸到其中一個叢集節點,使用指令
cluster nodes
進行查詢
# /usr/local/src/redis-5.0.4/src/redis-cli -c -h 127.0.0.1 -p 7001 cluster nodes
7d388cc31df969d3e1715ce9644318bfd48317b1 127.0.0.1:7004@17004 slave 59b6597448b668a355d85dcc7a0623bc36263e5f 0 1564918712465 4 connected
bbe8b7035bfd31c47bec7d612acc112cd2869368 127.0.0.1:7003@17003 master - 0 1564918714483 3 connected 10923-16383
456921ae96af71d8183101f798cf5ceda4b0381e 127.0.0.1:7005@17005 slave bbe8b7035bfd31c47bec7d612acc112cd2869368 0 1564918713000 5 connected
5612ffbb0407dbda50828b505a16b39ede51168b 127.0.0.1:7006@17006 slave 4dad696ede24995a57c5fd790faa95c72c187a22 0 1564918713474 6 connected
4dad696ede24995a57c5fd790faa95c72c187a22 127.0.0.1:7001@17001 myself,master - 0 1564918713000 1 connected 0-5460
59b6597448b668a355d85dcc7a0623bc36263e5f 127.0.0.1:7002@17002 master - 0 1564918712000 2 connected 5461-10922
參數說明:
- -c:表示以叢集方式連接配接惹redis
- -h:指定IP位址
- -p:指定端口
- cluster nodes:查詢叢集節點資訊
- cluster info:查詢叢集狀态資訊
其他查詢方法:
# /usr/local/src/redis-5.0.4/src/redis-cli --cluster check 127.0.0.1:7001
127.0.0.1:7001 (4dad696e...) -> 0 keys | 5461 slots | 1 slaves.
127.0.0.1:7003 (bbe8b703...) -> 0 keys | 5461 slots | 1 slaves.
127.0.0.1:7002 (59b65974...) -> 0 keys | 5462 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 127.0.0.1:7001)
M: 4dad696ede24995a57c5fd790faa95c72c187a22 127.0.0.1:7001
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: 7d388cc31df969d3e1715ce9644318bfd48317b1 127.0.0.1:7004
slots: (0 slots) slave
replicates 59b6597448b668a355d85dcc7a0623bc36263e5f
M: bbe8b7035bfd31c47bec7d612acc112cd2869368 127.0.0.1:7003
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: 456921ae96af71d8183101f798cf5ceda4b0381e 127.0.0.1:7005
slots: (0 slots) slave
replicates bbe8b7035bfd31c47bec7d612acc112cd2869368
S: 5612ffbb0407dbda50828b505a16b39ede51168b 127.0.0.1:7006
slots: (0 slots) slave
replicates 4dad696ede24995a57c5fd790faa95c72c187a22
M: 59b6597448b668a355d85dcc7a0623bc36263e5f 127.0.0.1:7002
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
# /usr/local/src/redis-5.0.4/src/redis-cli --cluster info 127.0.0.1:7001
127.0.0.1:7001 (4dad696e...) -> 0 keys | 5461 slots | 1 slaves.
127.0.0.1:7003 (bbe8b703...) -> 0 keys | 5461 slots | 1 slaves.
127.0.0.1:7002 (59b65974...) -> 0 keys | 5462 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
5.7.6 redis cluster叢集重新啟動
因為叢集已經建立過了,若是關機等原因關閉了redis服務,則隻需要執行批量啟動腳本即可,就會自動開啟叢集,因為有node.conf檔案的存在
5.7.7 redis-cli叢集指令幫助
# /usr/local/src/redis-5.0.4/src/redis-cli --cluster help
Cluster Manager Commands:
create host1:port1 ... hostN:portN
--cluster-replicas <arg>
check host:port
--cluster-search-multiple-owners
info host:port
fix host:port
--cluster-search-multiple-owners
reshard host:port
--cluster-from <arg>
--cluster-to <arg>
--cluster-slots <arg>
--cluster-yes
--cluster-timeout <arg>
--cluster-pipeline <arg>
--cluster-replace
rebalance host:port
--cluster-weight <node1=w1...nodeN=wN>
--cluster-use-empty-masters
--cluster-timeout <arg>
--cluster-simulate
--cluster-pipeline <arg>
--cluster-threshold <arg>
--cluster-replace
add-node new_host:new_port existing_host:existing_port
--cluster-slave
--cluster-master-id <arg>
del-node host:port node_id
call host:port command arg arg .. arg
set-timeout host:port milliseconds
import host:port
--cluster-from <arg>
--cluster-copy
--cluster-replace
help
For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.
5.8 叢集管理
5.8.1 添加新主節點
redis-cli --cluster add-node new_host:new_port existing_host:existing_port --cluster-master-id node_id
5.8.2 hash槽重新配置設定
添加完新節點後,需要對新添加的主節點進行hash槽重新配置設定,這樣該主節點才能存儲資料,redis共有16384個槽。
redis-cli --cluster reshard host:port --cluster-from node_id --cluster-to node_id --cluster-slots <args> --cluster-yes
5.8.2 添加新從節點
redis-cli --cluster add-node new_host:new_port existing_host:existing_port --cluster-slave --cluster-master-id node_id
5.8.3 删除節點
redis-cli --cluster del-node host:port node_id
5.8.4 叢集常用指令
# 建立叢集
redis-cli --cluster create host1:port1 ... hostN:portN --cluster-replicas <arg>
# 例子
redis-cli --cluster create 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006 --cluster-replicas 1
# 例子說明
host1:port1 ... hostN:portN表示的是要添加的叢集的節點IP和端口,
--cluster-replicas <arg>表示的是主從節點比例,參數1表示前三個是主節點,後三個是從節點
也就是說7001,7002,7003端口對應的節點是主節點,7004,7005,7006對應的節點是從節點
# 查詢叢集節點資訊
redis-cli -c -p 7001 cluster nodes
7d388cc31df969d3e1715ce9644318bfd48317b1 127.0.0.1:7004@17004 slave 59b6597448b668a355d85dcc7a0623bc36263e5f 0 1564923261350 4 connected
bbe8b7035bfd31c47bec7d612acc112cd2869368 127.0.0.1:7003@17003 master - 0 1564923263366 3 connected 10923-16383
456921ae96af71d8183101f798cf5ceda4b0381e 127.0.0.1:7005@17005 slave bbe8b7035bfd31c47bec7d612acc112cd2869368 0 1564923262000 5 connected
5612ffbb0407dbda50828b505a16b39ede51168b 127.0.0.1:7006@17006 slave 4dad696ede24995a57c5fd790faa95c72c187a22 0 1564923260000 6 connected
4dad696ede24995a57c5fd790faa95c72c187a22 127.0.0.1:7001@17001 myself,master - 0 1564923263000 1 connected 0-5460
59b6597448b668a355d85dcc7a0623bc36263e5f 127.0.0.1:7002@17002 master - 0 1564923262358 2 connected 5461-10922
# 說明:以下的操作均是以上面這個為參數示例
# 給叢集添加一個新主節點
redis-cli --cluster add-node new_host:new_port existing_host:existing_port --cluster-master-id node_id
# 例子
redis-cli --cluster add-node 127.0.0.1:7007 127.0.0.1:7003 --cluster-master-id bbe8b7035bfd31c47bec7d612acc112cd2869368
# 例子說明
new_host:new_port為要新添加的主節點IP和端口,此處是127.0.0.1:7007
existing_host:existing_port表示的是已存在的最後一個主節點的IP和端口,這個可以從上述的節點資訊中檢視到,根據slots槽數,7003端口對應的節點槽數是10923-16383,16383表示的是最後的槽數
--cluster-master-id表示的是最後一個主節點的節點id,表示的是新添加的主節點要在這個節點後面
# 再次檢視叢集資訊
redis-cli -c -p 7001 cluster nodes
7d388cc31df969d3e1715ce9644318bfd48317b1 127.0.0.1:7004@17004 slave 59b6597448b668a355d85dcc7a0623bc36263e5f 0 1564923261350 4 connected
bbe8b7035bfd31c47bec7d612acc112cd2869368 127.0.0.1:7003@17003 master - 0 1564923263366 3 connected 10923-16383
7020c8df9423686727783c60bd2f0e367634ba84 127.0.0.1:7007@17007 master - 0 1564923260344 0 connected
456921ae96af71d8183101f798cf5ceda4b0381e 127.0.0.1:7005@17005 slave bbe8b7035bfd31c47bec7d612acc112cd2869368 0 1564923262000 5 connected
5612ffbb0407dbda50828b505a16b39ede51168b 127.0.0.1:7006@17006 slave 4dad696ede24995a57c5fd790faa95c72c187a22 0 1564923260000 6 connected
4dad696ede24995a57c5fd790faa95c72c187a22 127.0.0.1:7001@17001 myself,master - 0 1564923263000 1 connected 0-5460
59b6597448b668a355d85dcc7a0623bc36263e5f 127.0.0.1:7002@17002 master - 0 1564923262358 2 connected 5461-10922
# 會發現7007端口對應的節點已經加入到叢集中,是主節點,但是沒有從節點,也沒有配置設定槽數
# 給新添加的主節點配置設定slots槽數
redis-cli --cluster reshard host:port --cluster-from node_id --cluster-to node_id --cluster-slots 500 --cluster-yes
# 例子
redis-cli --cluster reshard 127.0.0.1:7007 --cluster-from 4dad696ede24995a57c5fd790faa95c72c187a22 --cluster-to 7020c8df9423686727783c60bd2f0e367634ba84 --cluster-slots 500
# 例子說明
host:port表示的是新添加的那個主節點IP和端口,此處表示的是127.0.0.1:7007
--cluster-from node_id表示的是叢集第一個主節點的節點id,這個可以現有叢集的slots槽數配置設定看出,此處表示的是7001端口對應的節點
--cluster-to node_id表示的是叢集最後一個主節點的節點id,也就是新添加的那個主節點id,此處表示的是7007端口對應的節點
--cluster-slots 500表示的是給新主節點配置設定多少,此處500表示是配置設定從0-499個slots槽數,若不加上這個會讓手動輸入
--cluster-yes表示的是自動應答為yes,若不加上這個會讓手動輸入yes,表示同意此次配置設定
# 再次檢視叢集資訊
/redis-cli -c -p 7001 cluster nodes 7d388cc31df969d3e1715ce9644318bfd48317b1 127.0.0.1:7004@17004 slave 59b6597448b668a355d85dcc7a0623bc36263e5f 0 1564924042000 4 connected
bbe8b7035bfd31c47bec7d612acc112cd2869368 127.0.0.1:7003@17003 master - 0 1564924042157 3 connected 10923-16383
7020c8df9423686727783c60bd2f0e367634ba84 127.0.0.1:7007@17007 master - 0 1564924040140 7 connected 0-499
456921ae96af71d8183101f798cf5ceda4b0381e 127.0.0.1:7005@17005 slave bbe8b7035bfd31c47bec7d612acc112cd2869368 0 1564924040000 5 connected
5612ffbb0407dbda50828b505a16b39ede51168b 127.0.0.1:7006@17006 slave 4dad696ede24995a57c5fd790faa95c72c187a22 0 1564924041149 6 connected
4dad696ede24995a57c5fd790faa95c72c187a22 127.0.0.1:7001@17001 myself,master - 0 1564924040000 1 connected 500-5460
59b6597448b668a355d85dcc7a0623bc36263e5f 127.0.0.1:7002@17002 master - 0 1564924043166 2 connected 5461-10922
# 會發現7007端口對應的主節點已經有slots槽數了,并且是從0開始的
# 給叢集中某個主節點再添加一個從節點
redis-cli --cluster add-node new_host:new_port existing_host:existing_port --cluster-slave --cluster-master-id node_id
# 例子
redis-cli --cluster add-node 127.0.0.1:7007 127.0.0.1:7008 --cluster-slave --cluster-master-id 7020c8df9423686727783c60bd2f0e367634ba84
# 例子說明
new_host:new_port表示的是要添加的那個從節點的IP和端口,此處表示的是127.0.0.1:7008
existing_host:existing_port表示的是要給哪個主節點添加從節點,此處表示的是127.0.0.1:7007
--cluster-slave表示的是要添加從節點,否則則是添加主節點了
--cluster-master-id node_id表示要給哪個主節點添加從節點的該主節點節點id
# 再次檢視叢集資訊
redis-cli -c -p 7001 cluster nodes 7020c8df9423686727783c60bd2f0e367634ba84 127.0.0.1:7007@17007 master - 0 1564924845000 7 connected 0-499
4dad696ede24995a57c5fd790faa95c72c187a22 127.0.0.1:7001@17001 myself,master - 0 1564924843000 1 connected 500-5460
5612ffbb0407dbda50828b505a16b39ede51168b 127.0.0.1:7006@17006 slave 4dad696ede24995a57c5fd790faa95c72c187a22 0 1564924845214 6 connected
7d388cc31df969d3e1715ce9644318bfd48317b1 127.0.0.1:7004@17004 slave 59b6597448b668a355d85dcc7a0623bc36263e5f 0 1564924843195 4 connected
bbe8b7035bfd31c47bec7d612acc112cd2869368 127.0.0.1:7003@17003 master - 0 1564924844205 3 connected 10923-16383
456921ae96af71d8183101f798cf5ceda4b0381e 127.0.0.1:7005@17005 slave bbe8b7035bfd31c47bec7d612acc112cd2869368 0 1564924845000 5 connected
415db07121ba946b202bca98e15cbdffc60bc18a 127.0.0.1:7008@17008 slave 7020c8df9423686727783c60bd2f0e367634ba84 0 1564924846224 7 connected
c3e04f0e8710c25d59703374a224ee8bec776e43 :0@0 master,fail,noaddr - 1564924804548 1564924802833 0 disconnected
59b6597448b668a355d85dcc7a0623bc36263e5f 127.0.0.1:7002@17002 master - 0 1564924844000 2 connected 5461-10922
# 會發現7008端口對應的節點已經是7007端口對應的從節點
# 從叢集中删除一個從節點
redis-cli --cluster del-node host:port node_id
# 例子
redis-cli --cluster del-node 127.0.0.1:7008 415db07121ba946b202bca98e15cbdffc60bc18a
# 例子說明
host:port表示的是要删除的那個節點的IP和端口,此處是127.0.0.1:7008
node_id表示的是删除的那個節點的節點id
# 其他指令有待補充
5.9 注意事項
5.9.1 防火牆端口放行
若是允許Redis叢集被外網使用者通路,除了需要修改配置檔案外,還需要修改防火牆,開放叢集中reids節點的端口。
說明:如果要開放一個範圍的端口,可以使用冒号來分割,即: 7001:7004,表示開放7001-7004之間所有的端口
5.9.2 登入節點問題
若是登入的是叢集中的節點,需要加上
-c
參數;否則不用加該參數
# 登入叢集節點的指令
redis-cli -c -h ip -p port -a password
# 登入一般節點或者從節點的指令
redis-cli -h ip -p port -a password
5.9.3 如何删除叢集中無效的節點
redis-cli -c -p 7001 cluster nodes
7020c8df9423686727783c60bd2f0e367634ba84 127.0.0.1:7007@17007 master - 0 1564925352648 7 connected 0-499
4dad696ede24995a57c5fd790faa95c72c187a22 127.0.0.1:7001@17001 myself,master - 0 1564925349000 1 connected 500-5460
5612ffbb0407dbda50828b505a16b39ede51168b 127.0.0.1:7006@17006 slave 4dad696ede24995a57c5fd790faa95c72c187a22 0 1564925351000 6 connected
7d388cc31df969d3e1715ce9644318bfd48317b1 127.0.0.1:7004@17004 slave 59b6597448b668a355d85dcc7a0623bc36263e5f 0 1564925354665 4 connected
bbe8b7035bfd31c47bec7d612acc112cd2869368 127.0.0.1:7003@17003 master - 0 1564925353657 3 connected 10923-16383
456921ae96af71d8183101f798cf5ceda4b0381e 127.0.0.1:7005@17005 slave bbe8b7035bfd31c47bec7d612acc112cd2869368 0 1564925349000 5 connected
c3e04f0e8710c25d59703374a224ee8bec776e43 :0@0 master,fail,noaddr - 1564924804548 1564924802833 0 disconnected
59b6597448b668a355d85dcc7a0623bc36263e5f 127.0.0.1:7002@17002 master - 0 1564925352000 2 connected 5461-10922
# 如上叢集中有一個無效的節點資訊,要如何删除,這個還不知道咋操作。