基於centos 7的Redis羣集原理及配置

博文大綱:
1、Redis羣集原理
2、Redis羣集架構細節
3、redis-cluster選舉
4、部署Redis羣集環境node

關於Redis的性能調優參數的說明,能夠參考博文:centos 7之Redis數據庫詳解及參數調優
1、Redis羣集原理: redis

1)Redis集羣架構:算法

  • Redis Cluster採用虛擬槽分區,將全部的數據根據算法映射到0~16384整數槽內
  • Redis Cluster是一個無中心的結構
  • 每一個節點都保存數據和整個集羣的狀態
    2)集羣角色
  • Master:Master之間分配slots
  • Slave:Slave向它指定的Master同步數據
    3)集羣節點使用的TCP端口
  • 6379端口用於客戶端的鏈接
  • 16379端口用於羣集總線

Redis3.0版本以上開始支持羣集,採用的是hash slot(哈希槽),能夠將多個Redis實例整合在一塊兒,造成一個羣集,也就是將數據分散到羣集的多臺服務器上。數據庫

Redis cluster(Redis 羣集)是一個無中心的結構,以下圖所示,每一個節點都會保存數據和整個羣集的狀態。每一個節點都會保存其餘節點的信息,知道其餘節點所負責的槽,而且會與其餘節點定時發送心跳信息,可以及時感知羣集中異常的節點。vim

基於centos 7的Redis羣集原理及配置

當客戶端向羣集中任一節點發送與數據庫鍵有關的命令時,接受命令的節點會計算出命令要處理的數據屬於哪一個槽,並檢查這個槽是否指派給了本身,若是鍵所在的槽正好指派給了當前節點,那麼節點直接執這個命令;若是鍵值所在的槽並無指派給當前節點,那麼節點會向客戶端返回一個MOVED錯誤,指引客戶端轉向(redirect)正確的節點,並再次發送以前想要執行的命令。centos

羣集角色有master和slave。master之間分配slots,一共16384個slot。slave向它指定的master同步數據,實現備份。當其中一個master沒法提供服務時,該master的slave將提高爲master,以保證羣集間slot的完整性。當其中的某一個master和它的slave都失效,致使了slot不完整,羣集失效,這時就須要運維人員去處理了。ruby

羣集搭建好後,羣集中的每一個節點都會按期地向其餘節點發送PING消息,若是接收PING消息的節點沒有在規定的時間內返回PONG消息,那麼發送PING消息的節點就會將其標記爲疑似下線(PFAIL)。各個節點會經過互相發送消息的方式來交換羣集中各個節點的狀態信息。若是已經在一個羣集裏面,半數以上的主節點都將某個主節點x報告爲疑似下線,那麼這個主節點x將被標記爲已下線(FAIL),同時會向羣集廣播一條關於主節點x的FAIL消息,全部收到這條FAIL消息的節點都會當即將主節點x標記爲已下線。服務器

當須要減小或者增長羣集中的服務器時,咱們須要將已經指派給某個節點(源節點)的槽改成指派給另外一個節點(目標節點),而且將相關槽所包含的鍵值對從源節點移動到目標節點。網絡

Redis羣集的從新分片操做時由Redis的羣集管理軟件redis-trib負責執行的,不支持自動分片,並且須要本身計算從哪些節點遷移多少Slot。在從新分片的過程當中,羣集無需下線,而且源節點和目標節點均可以繼續處理命令請求。架構

2、Redis羣集架構細節:

一、全部的Redis節點彼此互聯(PING-PONG機制)內部使用二進制協議優先傳輸速度和帶寬。

二、節點的失效(fail)在羣集中超過半數的主(master)節點檢測失效時纔會生效。

三、客戶端與redis節點直連,不須要中間代理(proxy)層,客戶端不須要鏈接羣集全部節點,鏈接羣集中任何一個可用節點便可。

四、redis-cluster把全部的物理節點映射到 [ 0-1638 ] slot 上,cluster負責維護node< - >slot< - > key。

3、redis-cluster選舉:

選舉過程是羣集中全部master參與,若是半數以上master節點與當前master節點通訊超時(cluster-node-timeout),認爲當前master節點掛掉。如下兩種狀況爲整個羣集不可用(cluster_state:fail),當羣集不可用時,全部對羣集的操做都不可用,收到((error)CLUSTERDOWN Thecluster is down)錯誤:

錯誤1:若是羣集中任意master掛掉,且當前master沒有slave,則羣集進入fail狀態,也能夠理解成羣集的slot映射 [ 0-16383 ]不完整時進入fail狀態。

錯誤2:若是羣集中超過半數的master掛掉,不管是否有slave,羣集都進入fail狀態。

默認狀況下,每一個羣集的節點都是用兩個TCP端口,一個是6379,一個是16379;6379服務於客戶端的鏈接,16379用於羣集總線,就是使用二進制協議的節點到節點通訊通道。節點使用羣集總線進行故障檢測、配置更新、故障轉移受權等。

4、部署Redis羣集環境:

一、環境準備:

1)六臺服務器,三臺爲master、三臺爲slave,我這裏均爲centos 7,IP地址依次爲192.168.1.1--6(參與羣集的服務器數量最好爲偶數,每一個master會自動對應一個slave,若爲奇數,羣集沒法實現冗餘,由於一定有一個master沒有對應的slave,一旦這個master宕機,整個羣集就會丟失一部分數據);
2)準備所需源碼包:下載連接,提取碼:4kky,配置本地yum,須要系統映像安裝ruby的運行環境。
3)自行配置網絡及防火牆,放行TCP的6379和16379這兩個端口的流量,我這裏直接關閉了防火牆。
4)全部redis服務器必須保證無任何數據,最好是全新安裝的,由於若是有數據存在,在後面進行羣集時會報錯,關於錯誤如何解決,我沒有深究。

二、開始部署:

①192.168.1.1:

[root@localhost ~]# mount /root/redis-5.0.iso /media 
mount: /dev/loop1 寫保護,將以只讀方式掛載
[root@localhost ~]# cd /media
[root@localhost media]# cp * /usr/src/           #將iso中的文件都複製到指定目錄
[root@localhost media]# cd /usr/src
[root@localhost src]# ls               #查看相關包有沒有複製過來
debug  kernels  redis-3.2.0.gem  redis-5.0.5.tar.gz
[root@localhost src]# tar zxf redis-5.0.5.tar.gz       #解包
[root@localhost src]# cd redis-5.0.5/       #切換至解壓後的目錄
[root@localhost redis-5.0.5]# make && make install      #編譯安裝
[root@localhost redis-5.0.5]# cd utils/        #切換至子目錄
[root@localhost utils]# ./install_server.sh       #生成服務相關配置文件
#接下來是在指定相關配置文件的存放位置,直接一路按回車鍵便可。
[root@localhost utils]# cd /etc/init.d/      #優化redis控制啓停方式
[root@localhost init.d]# mv redis_6379 redis     
[root@localhost init.d]# chkconfig --add redis          #將redis添加爲系統服務
[root@localhost init.d]# systemctl restart redis          #重啓服務,以測試是否生效
[root@localhost init.d]# systemctl restart redis
[root@localhost init.d]# vim /etc/redis/6379.conf    #編輯主配置文件,改動如下幾個配置項
bind 127.0.0.1 192.168.1.1   #添加本機IP。
appendonly yes  #改成「yes」,以便在每次更新操做後進行日誌記錄,進行數據同步寫入
daemonize yes       #查看是否爲「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          #將默認的「yes」改成「no」
port 6379                  #默認監聽的端口號
[root@localhost init.d]# systemctl restart redis        #重啓服務,使配置生效
[root@localhost init.d]# netstat -anpt | grep redis       #只要6379和16379在監聽,就OK了。
tcp        0      0 192.168.1.1:6379        0.0.0.0:*       LISTEN      7139/redis-server 1 
tcp        0      0 192.168.1.1:16379       0.0.0.0:*       LISTEN      7139/redis-server 1 
[root@localhost ~]# yum -y install ruby rubygems            #安裝ruby的運行環境及客戶端
[root@localhost ~]# cd /usr/src/
[root@localhost src]# ls             #切換至包含redis-3.2.0.gem的目錄下
debug  kernels  redis-3.2.0.gem  redis-5.0.5  redis-5.0.5.tar.gz
[root@localhost src]# gem install redis --version 3.2.0      #執行gem命令
Successfully installed redis-3.2.0
Parsing documentation for redis-3.2.0
Installing ri documentation for redis-3.2.0
1 gem installed

②192.168.1.2:

[root@localhost ~]# scp root@192.168.1.1:/usr/src/redis-5.0.5.tar.gz /usr/src
#將主機1.1的redis源碼包複製過來
The authenticity of host  192.168.1.1 (192.168.1.1) can t be established.
ECDSA key fingerprint is SHA256:3U5q5gBxEOkHLFZZueGnEXGV/LZA9M4+1rM1lLvkD1g.
ECDSA key fingerprint is MD5:ad:a1:9b:f7:e3:41:bf:5f:da:cd:5e:3f:74:e0:8a:b9.
Are you sure you want to continue connecting (yes/no)? yes #輸入yes
Warning: Permanently added '192.168.1.1' (ECDSA) to the list of known hosts.
root@192.168.1.1 s password:         #輸入主機1.1的用戶密碼
redis-5.0.5.tar.gz                              100% 1929KB  68.5MB/s   00:00   
[root@localhost ~]# cd /usr/src                 
[root@localhost src]# tar zxf redis-5.0.5.tar.gz         #解包
[root@localhost src]# cd redis-5.0.5/          #進入解壓後的目錄
[root@localhost redis-5.0.5]# make && make install       #編譯安裝
[root@localhost redis-5.0.5]# cd utils/        #切換至子目錄
[root@localhost utils]# ./install_server.sh       #生成服務相關配置文件
#接下來是在指定相關配置文件的存放位置,直接一路按回車鍵便可。
[root@localhost utils]# cd /etc/init.d/      #優化redis控制啓停方式
[root@localhost init.d]# mv redis_6379 redis     
[root@localhost init.d]# chkconfig --add redis          #將redis添加爲系統服務
[root@localhost init.d]# systemctl restart redis          #重啓服務,以測試是否生效
[root@localhost init.d]# scp root@192.168.1.1:/etc/redis/6379.conf /etc/redis/ 
#將主機1.1的redis配置文件複製過來
root@192.168.1.1 s password: 
6379.conf                                       100%   60KB  34.5MB/s   00:00    
[root@localhost init.d]# scp root@192.168.1.1:/etc/redis/6379.conf /etc/redis/    #編輯配置redis配置文件
bind 127.0.0.1 192.168.1.2         #將原有的1.1改成1.2便可
[root@localhost init.d]# systemctl restart redis          #重啓服務,使配置文件生效
[root@localhost init.d]# netstat -natp | grep redis      #查看6379和16379是否在監聽
tcp        0      0 192.168.1.2:6379        0.0.0.0:*       LISTEN      7479/redis-server 1 
tcp        0      0 192.168.1.2:16379       0.0.0.0:*     LISTEN      7479/redis-server 1

如今192.168.1.2也配置完成了,如今去192.168.1.3-6重複執行一下192.168.1.2這臺主機的配置便可。須要注意的是,更改從1.1複製過來的主配置文件時,將對應的IP地址換成本機的IP地址便可,其餘配置命令都同樣。

剩下的全部服務器都配置完成後,回過頭接着配置主機192.168.1.1:

[root@localhost src]# redis-cli --cluster create 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  \
--cluster-replicas 1
#建立羣集,將全部節點添加到羣集。「\」表示折行繼續輸入,能夠省略「\」,但要空格
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 192.168.1.5:6379 to 192.168.1.1:6379
Adding replica 192.168.1.6:6379 to 192.168.1.2:6379
Adding replica 192.168.1.4:6379 to 192.168.1.3:6379
M: 758dc679fc1d46df195b4c16abcfde1d743b8008 192.168.1.1:6379
   slots:[0-5460] (5461 slots) master
M: 4b1d119d0a8179afcc10bf5891e5c04e6a7054ba 192.168.1.2:6379
   slots:[5461-10922] (5462 slots) master
M: 58d342b59e98c9f9f469332b08c36b6ddd456bf6 192.168.1.3:6379
   slots:[10923-16383] (5461 slots) master
S: bb95619aff3d613137733eeb55ff2d303a8720a1 192.168.1.4:6379
   replicates 58d342b59e98c9f9f469332b08c36b6ddd456bf6
S: 22d77a79272847f29e5db381b98ef6ccc4a169a7 192.168.1.5:6379
   replicates 758dc679fc1d46df195b4c16abcfde1d743b8008
S: ebc138bbea070c6496ae266b1a84936754603ad2 192.168.1.6:6379
   replicates 4b1d119d0a8179afcc10bf5891e5c04e6a7054ba
Can I set the above configuration? (type 'yes' to accept): yes            #輸入「yes」
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
.....
>>> Performing Cluster Check (using node 192.168.1.1:6379)
M: 758dc679fc1d46df195b4c16abcfde1d743b8008 192.168.1.1:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: ebc138bbea070c6496ae266b1a84936754603ad2 192.168.1.6:6379
   slots: (0 slots) slave
   replicates 4b1d119d0a8179afcc10bf5891e5c04e6a7054ba
M: 4b1d119d0a8179afcc10bf5891e5c04e6a7054ba 192.168.1.2:6379
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
M: 58d342b59e98c9f9f469332b08c36b6ddd456bf6 192.168.1.3:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: bb95619aff3d613137733eeb55ff2d303a8720a1 192.168.1.4:6379
   slots: (0 slots) slave
   replicates 58d342b59e98c9f9f469332b08c36b6ddd456bf6
S: 22d77a79272847f29e5db381b98ef6ccc4a169a7 192.168.1.5:6379
   slots: (0 slots) slave
   replicates 758dc679fc1d46df195b4c16abcfde1d743b8008
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
[root@localhost src]# redis-cli --cluster check 192.168.1.1:6379   
#查看羣集狀態
192.168.1.1:6379 (758dc679...) -> 0 keys | 5461 slots | 1 slaves.
192.168.1.2:6379 (4b1d119d...) -> 0 keys | 5462 slots | 1 slaves.
192.168.1.3:6379 (58d342b5...) -> 0 keys | 5461 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 192.168.1.1:6379)
M: 758dc679fc1d46df195b4c16abcfde1d743b8008 192.168.1.1:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: ebc138bbea070c6496ae266b1a84936754603ad2 192.168.1.6:6379
   slots: (0 slots) slave
   replicates 4b1d119d0a8179afcc10bf5891e5c04e6a7054ba
M: 4b1d119d0a8179afcc10bf5891e5c04e6a7054ba 192.168.1.2:6379
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
M: 58d342b59e98c9f9f469332b08c36b6ddd456bf6 192.168.1.3:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: bb95619aff3d613137733eeb55ff2d303a8720a1 192.168.1.4:6379
   slots: (0 slots) slave
   replicates 58d342b59e98c9f9f469332b08c36b6ddd456bf6
S: 22d77a79272847f29e5db381b98ef6ccc4a169a7 192.168.1.5:6379
   slots: (0 slots) slave
   replicates 758dc679fc1d46df195b4c16abcfde1d743b8008
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
[root@localhost src]# redis-cli -h 192.168.1.1 -p 6379 -c          #登陸到羣集需加「-c」選項
192.168.1.1:6379> set lv 11         #插入數據
OK
192.168.1.1:6379> get lv         
"11"
192.168.1.1:6379> exit
[root@localhost src]# redis-cli -h 192.168.1.3 -p 6379 -c          #登陸到其餘master
192.168.1.3:6379> get lv           #查看在1.1插入的數據,照樣能夠查詢到,說明羣集生效
-> Redirected to slot [4118] located at 192.168.1.1:6379
"11"

redis-3.x.x和redis-5.x.x建立羣集的區別:

使用命令不同,redis-3.x.x使用redis-trib.rb命令,語法以下:

[root@localhost ~]#redis-trib.rb create --replicas 1 192.168.1.1:6379 ..192.168.1.6:6379
#redis-3.x.x建立羣集。
[root@localhost src]# redis-trib.rb check 192.168.1.1:6379
#查看羣集狀態
# redis-trib.rb不能夠直接使用,須要執行如下操做纔可直接使用
[root@localhost src]# cd /usr/src/redis-5.0.5/src/           
[root@localhost src]# cp redis-trib.rb /usr/local/bin/  
#將該腳本複製到本地../bin下,以便直接使用。若否則,須要在目錄下使用「./」執行該文件
相關文章
相關標籤/搜索