Redis 3.0版本以上開始支持cluster,採用的是hash slot(hash 槽),可以將多個Redis實例整個在一起,形成一個羣集,也就是將數據分散到羣集的多個機器上。
Redis羣集原理
當客戶端向羣集中任一節點發送與數據庫鍵有關的命令是,接受命令的節點會計算出命令要處理的數據庫鍵屬於哪個槽,並檢查這個槽是否指派給了自己。如果鍵所在的槽正好指派給了當前節點,那麼節點直接執行這個命令;如果鍵所在的槽並沒有指派給當前節點,那麼節點會向客戶端返回一個MOVED錯誤,指引客戶端轉向正確的節點,並再次發送之前想要執行的命令。
羣集角色有Master和Slave。Master之間分配slots,一共有16384個slot。Slave向它指定的Master同步數據,實現備份。當其中一個Master無法提供服務時,該Master的Slave將提升爲Master。以保證羣集鍵slot的完整性。當其中的某一個Master和它的Slave都失效,就會導致slot不完整,羣集失效,這是就需要人工參與修復。
羣集搭建好後,羣集中的每個節點都會定期地想其他節點發送PING消息,如果接收PING消息的節點沒有在規定的時間內返回PONG消息,那麼發送PING消息的節點就會將其標記爲疑似下線(PFAIL)。各個節點會通過互相發送消息的方式來交換羣集中各個節點的狀態信息。如果在一個羣集裏,半數以上的主節點都將某個節點 X 報告爲疑似下線,那麼這個主節點 X 將被標記爲已下線(FAIL),同時會向羣集廣播一條關於主節點 X 的FAIL消息,所有收到這條FAIL消息的節點都會立即將主節點 X 標記爲已下線。
當需要減少或增加羣集中的機器時,我們需要將已經指派給某個節點(源節點)的槽改爲指派給另一個節點(目標節點),並且將相關槽所屬的鍵值對從源節點移動到目標節點。
Redis羣集的重新分片操作是由Redis的羣集管理軟件redis-trib負責執行的,不支持自動的分片,而且需要自己計算從哪些節點上遷移多少Slot。在重新分片的過程中,羣集不需要下線,並且源節點和目標節點都可以繼續處理命令請求。
細節架構
- 1.所有的redis節點彼此互聯,內部使用二進制協議優化傳輸速度和帶寬
- 2.節點的失效在羣集中超過半數的主節點檢測失效才失效
- 3.客戶端與redis節點直連,不需要中間代理層,客戶端不需要連接羣集所有節點,連接羣集中任何一個可用節點即可
- 4.redis-cluster把所有的物理節點映射到【0-16383】slot上,cluster 負責維護node<->slot<->key
Redis-cluster選舉
選舉過程是羣集中所有master參與,如果半數以上master節點與當前master節點通信超時,認爲當前master節點掛掉。(如上圖)以下兩種情況出現則爲羣集不可用。
- 如果羣集任意master掛掉,且當前master沒有slave,則羣集進入fail狀態,也可以理解爲羣集的slot映射【0-16383】不完整時進入的fail狀態。
- 如果羣集中出現半數的master掛掉,無論是否有slave,羣集都進入fail狀態。
默認情況下,每個羣集的節點都使用兩個TCP端口,一個是6379,一個是16379,6379端口服務於客戶端的連接,16379端口用於羣集總線。
即使用二進制協議的節點到節點通信通道。節點使用羣集總線進行故障檢測,配置更新、故障轉移授權等。如果開啓了防火牆,需要開放這個端口
Redis羣集部署
理解了Redis羣集原理之後,搭建redis羣集就變得非常簡單了。本次實驗採用6臺服務器搭建Redis羣集,其中3臺爲master,3臺爲salve。6臺服務器的IP地址爲192.168.1.1/24——192.168.1.6/24
1.安裝Redis並修改配置文件
網盤下載:https://pan.baidu.com/s/1tiHpDwy3nAy7EszY7jjgWg
在每一臺上都要安裝Redis,然後修改配置文件如下,其中每臺都要修改,只是ip不同(1-6),其他配置都一樣
1)在192.168.1.1-1.6上安裝Redis
[root@localhost ~]# tar zxf redis-3.2.9.tar.gz -C /usr/src/
[root@localhost ~]# cd /usr/src/
[root@localhost src]# cd redis-3.2.9/
[root@localhost redis-3.2.9]# make && make install //編譯安裝
[root@localhost redis-3.2.9]# cd utils/
[root@localhost utils]# ./install_server.sh
Welcome to the redis service installer
This script will help you easily set up a running redis server
Please select the redis port for this instance: [6379]
Selecting default: 6379
Please select the redis config file name [/etc/redis/6379.conf]
Selected default - /etc/redis/6379.conf
Please select the redis log file name [/var/log/redis_6379.log]
Selected default - /var/log/redis_6379.log
Please select the data directory for this instance [/var/lib/redis/6379]
Selected default - /var/lib/redis/6379
Please select the redis executable path [/usr/local/bin/redis-server]
Selected config:
Port : 6379
Config file : /etc/redis/6379.conf //設置默認配置文件
Log file : /var/log/redis_6379.log //日誌文件
Data dir : /var/lib/redis/6379 //數據目錄
Executable : /usr/local/bin/redis-server //執行命令
Cli Executable : /usr/local/bin/redis-cli //客戶端命令
Is this ok? Then press ENTER to go on or Ctrl-C to abort.
Copied /tmp/6379.conf => /etc/init.d/redis_6379
Installing service...
Successfully added to chkconfig!
Successfully added to runlevels 345!
Starting Redis server...
Installation successful!
[root@localhost utils]# netstat -anput | grep redis
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 7012/redis-server 1
2)在192.168.1.1-1.6修改配置文件 (演示的是1.1)
[root@localhost ~]# vim /etc/redis/6379.conf
bind 192.168.1.1 //改爲本機的IP地址
daemonize yes
logfile /var/log/redis_6379.log
cluster-enabled yes //啓用羣集
cluster-config-file nodes-6379.conf
cluster-node-timeout 15000
cluster-require-full-coverage no
[root@localhost ~]# /etc/init.d/redis_6379 restart //重啓
Stopping ...
Redis stopped
Starting Redis server...
[root@localhost ~]# netstat -anpt | grep 6379
tcp 0 0 192.168.1.1:6379 0.0.0.0:* LISTEN 6497/redis-server 1
tcp 0 0 192.168.1.1:16379 0.0.0.0:* LISTEN 6497/redis-server 1
tcp 0 0 127.0.0.1:6379 127.0.0.1:43304 TIME_WAIT -
2.使用腳本創建羣集
創建羣集要用到ruby的一個腳本,在創建羣集之前,需要先安裝ruby的運行環境和ruby的Redis客戶端,該操作在其中一臺服務器進行即可。(這裏使用1.1演示)gem命令是提前下載的redis-3.2.0 gem軟件包提供的,上面網盤下載提供了相應的軟件包。
[root@localhost ~]# yum -y install ruby rubygems //安裝ruby的運行環境
[root@localhost ~]# gem install redis --version 3.2.0
Successfully installed redis-3.2.0
Parsing documentation for redis-3.2.0
Installing ri documentation for redis-3.2.0
1 gem installed
使用腳本創建羣集
[root@localhost ~]# cd /usr/src/redis-3.2.9/src
[root@localhost src]# ./redis-trib.rb create --replicas 1 192.168.1.1:6379 192.168.1.2:6379 192.168.1.3:6379 192.168.1.4:6379 192.168.1.5:6379 192.168.1.6:6379
//省略內容
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.
測試
[root@localhost src]# ./redis-trib.rb check 192.168.1.1:6379 //查看羣集狀態
>>> Performing Cluster Check (using node 192.168.1.1:6379)
M: afb2a0876b9c4c1c19e2bc492e398765bed0a311 192.168.1.1:6379
slots:0-5460 (5461 slots) master
1 additional replica(s)
S: 00ed4b0da4f0444c7e2a54a44c2060dd2c51a19a 192.168.1.4:6379
slots: (0 slots) slave
replicates afb2a0876b9c4c1c19e2bc492e398765bed0a311
S: 081d87a0d26895605e4c237c5429d3ae6e01f7b2 192.168.1.5:6379
slots: (0 slots) slave
replicates 050d71e6ad9bbf0a2a90b743d5a9bb9fb77052bb
S: 00bf8cb3a48a696d9bfc4b124234335633dc14d0 192.168.1.6:6379
slots: (0 slots) slave
replicates bec4c3401ced5a43439568f5530d79dd2a911512
M: 050d71e6ad9bbf0a2a90b743d5a9bb9fb77052bb 192.168.1.2:6379
slots:5461-10922 (5462 slots) master
1 additional replica(s)
M: bec4c3401ced5a43439568f5530d79dd2a911512 192.168.1.3:6379
slots:10923-16383 (5461 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.
登錄羣集,設置鍵值測試,需要用到“-c”參數來激活羣集,具體操作如下:
[root@localhost ~]# redis-cli -h 192.168.1.1 -p 6379 -c
192.168.1.1:6379> set qzt 1000
-> Redirected to slot [12706] located at 192.168.1.4:6379 //可以看到1.4上
OK
192.168.1.3:6379> get qzt
"100"