1、Redis羣集架構細節:node
一、全部的Redis節點彼此互聯(PING-PONG機制)內部使用二進制協議優先傳輸速度和帶寬。redis
二、節點的失效(fail)在羣集中超過半數的主(master)節點檢測失效時纔會生效。算法
三、客戶端與redis節點直連,不須要中間代理(proxy)層,客戶端不須要鏈接羣集全部節點,鏈接羣集中任何一個可用節點便可。數據庫
四、redis-cluster把全部的物理節點映射到 [ 0-1638 ] slot 上,cluster負責維護node< - >slot< - > key。
2、redis-cluster選舉:
選舉過程是羣集中全部master參與,若是半數以上master節點與當前master節點通訊超時(cluster-node-timeout),認爲當前master節點掛掉。如下兩種狀況爲整個羣集不可用(cluster_state:fail),當羣集不可用時,全部對羣集的操做都不可用,收到((error)CLUSTERDOWN Thecluster is down)錯誤:vim
若是羣集中任意master掛掉,且當前master沒有slave,則羣集進入fail狀態,也能夠理解成羣集的slot映射 [ 0-16383 ]不完整時進入fail狀態。centos
默認狀況下,每一個羣集的節點都是用兩個TCP端口,一個是6379,一個是16379;6379服務於客戶端的鏈接,16379用於羣集總線,就是使用二進制協議的節點到節點通訊通道。節點使用羣集總線進行故障檢測、配置更新、故障轉移受權等。
Redis羣集原理:ruby
一、Redis集羣架構:服務器
Redis Cluster採用虛擬槽分區,將全部的數據根據算法映射到0~16384整數槽內
Redis Cluster是一個無中心的結構
每一個節點都保存數據和整個集羣的狀態
二、集羣角色:
Master:Master之間分配slots
Slave:Slave向它指定的Master同步數據
三、集羣節點使用的TCP端口
6379端口用於客戶端的鏈接
16379端口用於羣集總線架構
Redis3.0版本以上開始支持羣集,採用的是hash slot(哈希槽),能夠將多個Redis實例整合在一塊兒,造成一個羣集,也就是將數據分散到羣集的多臺服務器上。
.
Redis cluster(Redis 羣集)是一個無中心的結構,以下圖所示,每一個節點都會保存數據和整個羣集的狀態。每一個節點都會保存其餘節點的信息,知道其餘節點所負責的槽,而且會與其餘節點定時發送心跳信息,可以及時感知羣集中異常的節點。
當客戶端向羣集中任一節點發送與數據庫鍵有關的命令時,接受命令的節點會計算出命令要處理的數據屬於哪一個槽,並檢查這個槽是否指派給了本身,若是鍵所在的槽正好指派給了當前節點,那麼節點直接執這個命令;若是鍵值所在的槽並無指派給當前節點,那麼節點會向客戶端返回一個MOVED錯誤,指引客戶端轉向(redirect)正確的節點,並再次發送以前想要執行的命令。
.
羣集角色有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。在從新分片的過程當中,羣集無需下線,而且源節點和目標節點均可以繼續處理命令請求。
準備工做:
一、六臺服務器,三臺爲master、三臺爲slave,這裏均爲centos 7,IP地址依次爲192.168.1.10--60(參與羣集的服務器數量最好爲偶數,每一個master會自動對應一個slave,若爲奇數,羣集沒法實現冗餘,由於一定有一個master沒有對應的slave,一旦這個master宕機,整個羣集就會丟失一部分數據);
二、所需源碼包: https://pan.baidu.com/s/12L6jNOBrXeLH4I445_uUtQ 提取碼: smn6
三、全部redis服務器必須保證無任何數據,最好是全新安裝的,由於若是有數據存在,在後面進行羣集時會報錯。
四、配置防火牆放行流量,本人較懶,這裏直接關閉了
開始部署:
192.168.1.10 上的配置:運維
[root@localhost media]# ls redis-3.2.0.gem redis-3.2.9.tar.gz [root@localhost media]# cp * /usr/src/ # 將軟件包複製 [root@localhost media]# cd /usr/src/ [root@localhost src]# ls # 確認都在呢 debug kernels redis-3.2.0.gem redis-3.2.9.tar.gz [root@localhost src]# tar zxf redis-3.2.9.tar.gz [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 # 一路回車便可 # 由於make install 只是安裝了二進制文件到系統中,並無啓動腳本和配置文件,因此須要經過install_server.sh來設置 redis 服務所須要的相關配置文件。 [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 /]# vim /etc/redis/6379.conf # 修改配置文件,修改如下幾條 ....................... bind 192.168.1.10 // 設置監聽 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 // 將yes改成no port 6379 // 監聽端口 # 保存退出
主配置文件修改完畢後先彆着急啓服務,由於咱們須要在每一臺服務器上都要安裝 redis ,按照以前的方法安裝便可,而後修改配置文件。其中每臺服務器都要修改,只是監聽IP地址不一樣而已,其餘的配置都同樣。因此,嘿嘿嘿~
192.168.1.20 的配置:
# 安裝完畢redis後 [root@localhost utils]# scp root@192.168.1.10:/etc/redis/6379.conf /etc/redis/ # 咱們直接將第一臺的主配文件複製過來使用,修改一下監聽IP就能夠了 [root@localhost utils]# vim /etc/redis/6379.conf ........................ bind 192.168.1.20
而後將剩下的幾臺服務器依次配置完畢。
回到 192.168.1.1配置:
使用腳本建立羣集:
[root@localhost /]# yum -y install ruby rubygems # 建立羣集會用到ruby的一個腳本,在建立羣集前,須要先安裝ruby的運行環境和客戶端,在任何一臺服務器安裝均可以 [root@localhost src]# gem install redis --version 3.2.0 # 執行這條命令須要此文件redis-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 [root@localhost src]# ./redis-trib.rb create --replicas 1 \ > 192.168.1.10:6379 \ > 192.168.1.20:6379 \ > 192.168.1.30:6379 \ > 192.168.1.40:6379 \ > 192.168.1.50:6379 \ > 192.168.1.60:6379 .20:6379 192.168.1.30:6379 192.168.1.40:6379 192.168.1.50:6379 192.168.1.60:6379 >>> Creating cluster >>> Performing hash slots allocation on 6 nodes... Using 3 masters: 192.168.1.10:6379 192.168.1.20:6379 192.168.1.30:6379 Adding replica 192.168.1.40:6379 to 192.168.1.10:6379 Adding replica 192.168.1.50:6379 to 192.168.1.20:6379 Adding replica 192.168.1.60:6379 to 192.168.1.30:6379 M: 4234dad1a041a91401d6e635c800581172e850dc 192.168.1.10:6379 slots:0-5460 (5461 slots) master M: b386e4089c6f45a59d371549cda306669dd6938f 192.168.1.20:6379 slots:5461-10922 (5462 slots) master M: c1d6d14364e8c5db2ae1ea3ee07360a8b17127d8 192.168.1.30:6379 slots:10923-16383 (5461 slots) master S: e772a17543efb1e11cd05d792c11319b0fbfee5f 192.168.1.40:6379 replicates 4234dad1a041a91401d6e635c800581172e850dc S: f0a387bf5f366de0e25c575588349bd424a0ff90 192.168.1.50:6379 replicates b386e4089c6f45a59d371549cda306669dd6938f S: abc2fef19988e6626243feff831bced36b83b642 192.168.1.60:6379 replicates c1d6d14364e8c5db2ae1ea3ee07360a8b17127d8 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.10:6379) M: 4234dad1a041a91401d6e635c800581172e850dc 192.168.1.10:6379 slots:0-5460 (5461 slots) master 1 additional replica(s) M: c1d6d14364e8c5db2ae1ea3ee07360a8b17127d8 192.168.1.30:6379 slots:10923-16383 (5461 slots) master 1 additional replica(s) M: b386e4089c6f45a59d371549cda306669dd6938f 192.168.1.20:6379 slots:5461-10922 (5462 slots) master 1 additional replica(s) S: f0a387bf5f366de0e25c575588349bd424a0ff90 192.168.1.50:6379 slots: (0 slots) slave replicates b386e4089c6f45a59d371549cda306669dd6938f S: e772a17543efb1e11cd05d792c11319b0fbfee5f 192.168.1.40:6379 slots: (0 slots) slave replicates 4234dad1a041a91401d6e635c800581172e850dc S: abc2fef19988e6626243feff831bced36b83b642 192.168.1.60:6379 slots: (0 slots) slave replicates c1d6d14364e8c5db2ae1ea3ee07360a8b17127d8 [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered.
測試一下羣集:
[root@localhost /]# redis-cli -h 192.168.1.20 -p 6379 -c
192.168.1.20:6379> set zhangsan 123123 # 建立一個值
-> Redirected to slot [12767] located at 192.168.1.30:6379 # 發現他跑另外一個服務器上了
OK
192.168.1.30:6379> get zhangsan # 也是能夠查到
"123123"
[root@localhost src]# ./redis-trib.rb check 192.168.1.10:6379 # 查看羣集狀態 >>> Performing Cluster Check (using node 192.168.1.10:6379) M: 4234dad1a041a91401d6e635c800581172e850dc 192.168.1.10:6379 slots:0-5460 (5461 slots) master 1 additional replica(s) M: c1d6d14364e8c5db2ae1ea3ee07360a8b17127d8 192.168.1.30:6379 slots:10923-16383 (5461 slots) master 1 additional replica(s) M: b386e4089c6f45a59d371549cda306669dd6938f 192.168.1.20:6379 slots:5461-10922 (5462 slots) master 1 additional replica(s) S: f0a387bf5f366de0e25c575588349bd424a0ff90 192.168.1.50:6379 slots: (0 slots) slave replicates b386e4089c6f45a59d371549cda306669dd6938f S: e772a17543efb1e11cd05d792c11319b0fbfee5f 192.168.1.40:6379 slots: (0 slots) slave replicates 4234dad1a041a91401d6e635c800581172e850dc S: abc2fef19988e6626243feff831bced36b83b642 192.168.1.60:6379 slots: (0 slots) slave replicates c1d6d14364e8c5db2ae1ea3ee07360a8b17127d8 [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered.
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下,以便直接使用。若否則,須要在目錄下使用「./」執行該文件