微信公衆號: 愛問CTO
專業編程問答社區
www.askcto.com
(1)全部的redis節點彼此互聯(PING-PONG機制),內部使用二進制協議優化傳輸速度和帶寬.
(2)節點的fail是經過集羣中超過半數的節點檢測失效時才生效.
(3)客戶端與redis節點直連,不須要中間proxy層.客戶端不須要鏈接集羣全部節點,鏈接集羣中任何一個可用節點便可
(4)redis-cluster把全部的物理節點映射到[0-16383]slot上,cluster 負責維護node<->slot<->valuevue
Redis 集羣中內置了 16384 個哈希槽,當須要在 Redis 集羣中放置一個 key-value 時,redis 先對 key 使用 crc16 算法算出一個結果,而後把結果對 16384 求餘數,這樣每一個 key 都會對應一個編號在 0-16383 之間的哈希槽,redis 會根據節點數量大體均等的將哈希槽映射到不一樣的節點node
示例以下
redis
(1)集羣中全部master參與投票,若是半數以上master節點與其中一個master節點通訊超過(cluster-node-timeout),認爲該master節點掛掉.算法
(2):何時整個集羣不可用(cluster_state:fail)? 編程
若是集羣任意master掛掉,且當前master沒有slave,則集羣進入fail狀態。也能夠理解成集羣的[0-16383]slot映射不徹底時進入fail狀態。ruby
若是集羣超過半數以上master掛掉,不管是否有slave,集羣進入fail狀態。服務器
redis集羣須要使用技巧管理工具redis-trib.rb,它依賴ruby環境,首先須要安裝ruby環境。微信
第一步:安裝ruby架構
[root@ERAYT-01 erayt]# yum install ruby [root@ERAYT-01 erayt]# yum install rubygems
第二步:上傳redis-3.0.0.gem到Linux系統socket
第三步:安裝ruby和redis的接口程序redis-3.0.0.gem
[root@ERAYT-01 erayt]# gem install redis-3.0.0.gem
第四步:redis-3.0.0/src目錄,將redis-trib.rb文件複製到/usr/local/redis-cluster目錄下
[root@ERAYT-01 src]# cp redis-trib.rb /usr/local/redis-cluster/
Redis集羣最少須要三臺主服務器,三臺從服務器。
端口號分別爲:7001~7006
第一步:建立7001實例,並編輯redis.conf文件,修改port爲7001。
注意:建立實例,即拷貝單機版安裝時,生成的bin目錄,爲7001目錄。
[erayt@ERAYT-01 redis]$ cd /usr/local/ [erayt@ERAYT-01 local]$ ls bin etc games include lib libexec redis redis-cluster sbin share src [erayt@ERAYT-01 local]$ cp redis/bin/ redis-cluster/7001 -r
進入7001目錄,修改端口,打開Cluster-enable yes
# Accept connections on the specified port, default is 6379. # If port 0 is specified Redis will not listen on a TCP socket. port 7001 cluster-enabled yes
第三步:複製7001,建立7002~7006實例,注意端口修改。
[pcts@ERAYT-01 redis-cluster]$ ls 7001 redis-trib.rb [erayt@ERAYT-01 redis-cluster]$ cp 7001/ 7002 -r [erayt@ERAYT-01 redis-cluster]$ cp 7001/ 7003 -r [erayt@ERAYT-01 redis-cluster]$ cp 7001/ 7004 -r [erayt@ERAYT-01 redis-cluster]$ cp 7001/ 7005 -r [erayt@ERAYT-01 redis-cluster]$ cp 7001/ 7006 -r
第四步:啓動全部的實例
[erayt@ERAYT-01 7001]$ ./redis-server redis.conf [erayt@ERAYT-01 7001]$ cd ../7002 [erayt@ERAYT-01 7002]$ ./redis-server redis.conf [erayt@ERAYT-01 7002]$ cd ../7003 [erayt@ERAYT-01 7003]$ ./redis-server redis.conf [erayt@ERAYT-01 7003]$ cd ../7004 [erayt@ERAYT-01 7004]$ ./redis-server redis.conf [erayt@ERAYT-01 7004]$ cd ../7005 [erayt@ERAYT-01 7005]$ ./redis-server redis.conf [erayt@ERAYT-01 7005]$ cd ../7006 [erayt@ERAYT-01 7006]$ ./redis-server redis.conf
啓動後,查看redis
[erayt@ERAYT-01 7006]$ ps aux | grep redis erayt 3265 0.1 0.1 35548 1884 ? Ssl 02:38 0:00 ./redis-server *:7001 [cluster] erayt 3269 0.1 0.1 35548 1884 ? Ssl 02:38 0:00 ./redis-server *:7002 [cluster] erayt 3273 0.1 0.1 35548 1884 ? Ssl 02:38 0:00 ./redis-server *:7003 [cluster] erayt 3277 0.1 0.1 35548 1884 ? Ssl 02:38 0:00 ./redis-server *:7004 [cluster] erayt 3281 0.1 0.1 35548 1884 ? Ssl 02:38 0:00 ./redis-server *:7005 [cluster] erayt 3285 0.1 0.1 35548 1888 ? Ssl 02:38 0:00 ./redis-server *:7006 [cluster] erayt 3320 0.0 0.0 6052 788 pts/1 S+ 02:44 0:00 grep redis
第五步:建立集羣
[erayt@ERAYT-01 redis-cluster]$ ls 7001 7002 7003 7004 7005 7006 redis-trib.rb [erayt@ERAYT-01 redis-cluster]$ ./redis-trib.rb create --replicas 1 192.168.232.128:7001 192.168.232.128:7002 192.168.232.128:7003 192.168.232.128:7004 192.168.232.128:7005 192.168.232.128:7006
replicas 後面的1表示的是每一個主機都帶有1個從機
>>> Creating cluster Connecting to node 192.168.232.128:7001: OK Connecting to node 192.168.232.128:7002: OK Connecting to node 192.168.232.128:7003: OK Connecting to node 192.168.232.128:7004: OK Connecting to node 192.168.232.128:7005: OK Connecting to node 192.168.232.128:7006: OK >>> Performing hash slots allocation on 6 nodes... Using 3 masters: 192.168.232.128:7001 192.168.232.128:7002 192.168.232.128:7003 Adding replica 192.168.232.128:7004 to 192.168.232.128:7001 Adding replica 192.168.232.128:7005 to 192.168.232.128:7002 Adding replica 192.168.232.128:7006 to 192.168.232.128:7003 M: 1455dfd4f6ba95c94fb9b78219afe477eb449897 192.168.232.128:7001 slots:0-5460 (5461 slots) master M: 78912c846586d65c43a243eb1780426bf2e363f2 192.168.232.128:7002 slots:5461-10922 (5462 slots) master M: b9f0452e588df5eeec3ce9bc461f8327727b99c8 192.168.232.128:7003 slots:10923-16383 (5461 slots) master S: a88a707d4c8a2db36365c78d69b8450c1b5f201b 192.168.232.128:7004 replicates 1455dfd4f6ba95c94fb9b78219afe477eb449897 S: 1e88baa5c85261c7803f6b7e8dec086612bd3d23 192.168.232.128:7005 replicates 78912c846586d65c43a243eb1780426bf2e363f2 S: 8a130089dc3158b55a110b8957fac85d5d0917cb 192.168.232.128:7006 replicates b9f0452e588df5eeec3ce9bc461f8327727b99c8
日誌能夠看到7001 7002 7003是主節點 7004 7005 7006是從節點,還能夠看到redis 根據節點數量大體均等的將哈希槽映射到不一樣的節點。
命令:./redis-cli –h 127.0.0.1 –p 7001 –c
注意:-c 鏈接redis集羣
cluster info 查看集羣狀態
[erayt@ERAYT-01 7001]$ ./redis-cli -p 7001 -c 127.0.0.1:7001> cluster info cluster_state:ok cluster_slots_assigned:16384 cluster_slots_ok:16384 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:6 cluster_size:3 cluster_current_epoch:6 cluster_my_epoch:1 cluster_stats_messages_sent:267 cluster_stats_messages_received:267 127.0.0.1:7001>
查看集羣中的節點
127.0.0.1:7001> cluster nodes 8a130089dc3158b55a110b8957fac85d5d0917cb 192.168.232.128:7006 slave b9f0452e588df5eeec3ce9bc461f8327727b99c8 0 1563823021952 6 connected 1e88baa5c85261c7803f6b7e8dec086612bd3d23 192.168.232.128:7005 slave 78912c846586d65c43a243eb1780426bf2e363f2 0 1563823027004 5 connected 1455dfd4f6ba95c94fb9b78219afe477eb449897 192.168.232.128:7001 myself,master - 0 0 1 connected 0-5460 a88a707d4c8a2db36365c78d69b8450c1b5f201b 192.168.232.128:7004 slave 1455dfd4f6ba95c94fb9b78219afe477eb449897 0 1563823023969 4 connected 78912c846586d65c43a243eb1780426bf2e363f2 192.168.232.128:7002 master - 0 1563823025989 2 connected 5461-10922 b9f0452e588df5eeec3ce9bc461f8327727b99c8 192.168.232.128:7003 master - 0 1563823024979 3 connected 10923-16383 127.0.0.1:7001>
集羣建立成功後能夠向集羣中添加節點,下面是添加一個master主節點
添加7007結點做爲新節點
1.先依照上面的複製一個redis實例,修改端口爲7007,啓動該服務
[erayt@ERAYT-01 7007]$ ./redis-server redis.conf
2.添加7007結點做爲新節點
執行命令:./redis-trib.rb add-node 127.0.0.1:7007 127.0.0.1:7001
[erayt@ERAYT-01 redis-cluster]$ ./redis-trib.rb add-node 192.168.232.128:7007 192.168.232.128:7001
3.查看集羣結點發現7007已添加到集羣中
127.0.0.1:7001> cluster nodes d1c9dbe277c82b36831b01fe29a0cac1f45f0dd3 192.168.232.128:7007 master - 0 1563824280943 0 connected 8a130089dc3158b55a110b8957fac85d5d0917cb 192.168.232.128:7006 slave b9f0452e588df5eeec3ce9bc461f8327727b99c8 0 1563824284990 6 connected 1e88baa5c85261c7803f6b7e8dec086612bd3d23 192.168.232.128:7005 slave 78912c846586d65c43a243eb1780426bf2e363f2 0 1563824280340 5 connected 1455dfd4f6ba95c94fb9b78219afe477eb449897 192.168.232.128:7001 myself,master - 0 0 1 connected 0-5460 a88a707d4c8a2db36365c78d69b8450c1b5f201b 192.168.232.128:7004 slave 1455dfd4f6ba95c94fb9b78219afe477eb449897 0 1563824283975 4 connected 78912c846586d65c43a243eb1780426bf2e363f2 192.168.232.128:7002 master - 0 1563824279930 2 connected 5461-10922 b9f0452e588df5eeec3ce9bc461f8327727b99c8 192.168.232.128:7003 master - 0 1563824282964 3 connected 10923-16383 127.0.0.1:7001>
添加完主節點須要對主節點進行hash槽分配,這樣該主節才能夠存儲數據。
1.查看集羣中槽佔用狀況
127.0.0.1:7001> cluster nodes d1c9dbe277c82b36831b01fe29a0cac1f45f0dd3 192.168.232.128:7007 master - 0 1563824280943 0 connected 8a130089dc3158b55a110b8957fac85d5d0917cb 192.168.232.128:7006 slave b9f0452e588df5eeec3ce9bc461f8327727b99c8 0 1563824284990 6 connected 1e88baa5c85261c7803f6b7e8dec086612bd3d23 192.168.232.128:7005 slave 78912c846586d65c43a243eb1780426bf2e363f2 0 1563824280340 5 connected 1455dfd4f6ba95c94fb9b78219afe477eb449897 192.168.232.128:7001 myself,master - 0 0 1 connected 0-5460 a88a707d4c8a2db36365c78d69b8450c1b5f201b 192.168.232.128:7004 slave 1455dfd4f6ba95c94fb9b78219afe477eb449897 0 1563824283975 4 connected 78912c846586d65c43a243eb1780426bf2e363f2 192.168.232.128:7002 master - 0 1563824279930 2 connected 5461-10922 b9f0452e588df5eeec3ce9bc461f8327727b99c8 192.168.232.128:7003 master - 0 1563824282964 3 connected 10923-16383 127.0.0.1:7001>
redis集羣有16384個槽,集羣中的每一個結點分配自已槽,經過查看集羣結點能夠看到槽佔用狀況。
能夠看到7001分配的0-5460、7002分配的 5461-1092二、7003分配的10923-16383
2.鏈接上集羣(鏈接集羣中任意一個可用結點都行)
[erayt@ERAYT-01 redis-cluster]$ ./redis-trib.rb reshard 192.168.232.128:7001
2.1 輸入要分配的槽數量
>>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. How many slots do you want to move (from 1 to 16384)?
2.2 輸入:1000,表示要分配1000個槽 點擊回車 根據具體狀況定
How many slots do you want to move (from 1 to 16384)? 1000 What is the receiving node ID?
2.3 輸入接收槽的結點id 輸入7007對應的編號(cluster nodes命令查看)
What is the receiving node ID? d1c9dbe277c82b36831b01fe29a0cac1f45f0dd3 Please enter all the source node IDs. Type 'all' to use all the nodes as source nodes for the hash slots. Type 'done' once you entered all the source nodes IDs. Source node #1:
2.4 輸入源結點id,表示槽從哪裏分配來
Please enter all the source node IDs. Type 'all' to use all the nodes as source nodes for the hash slots. Type 'done' once you entered all the source nodes IDs. Source node #1:
槽的總量是必定的,以前都已經所有分配給了7001/7002/7003,如今要從新從分好的的節點拿出來一些分給7007節點。
能夠輸入多個節點的編號,每次輸完一個點擊回車,輸完因此的輸入done表示輸入完成。表示7007的槽來源這幾個節點
能夠輸入all,表示全部具備槽的節點都須要去分配一些給7007,我這裏輸入的是all
2.5 輸入yes開始移動槽到目標結點id
Do you want to proceed with the proposed reshard plan (yes/no)? yes
2.6 查看7007節點槽的分配
d1c9dbe277c82b36831b01fe29a0cac1f45f0dd3 192.168.232.128:7007 master - 0 1563826629735 7 connected 0-332 5461-5794 10923-11255
集羣建立成功後也能夠向集羣中添加從節點。
添加7008從結點,將7008做爲7007的從結點
命令:./redis-trib.rb add-node --slave --master-id 主節點id 新節點的ip和端口 舊節點ip和端口
[erayt@ERAYT-01 redis-cluster]$ ./redis-trib.rb add-node --slave --master-id d1c9dbe277c82b36831b01fe29a0cac1f45f0dd3 192.168.232.128:7008 192.168.101.3:7007
d1c9dbe277c82b36831b01fe29a0cac1f45f0dd3 是剛剛7007的id
[erayt@ERAYT-01 redis-cluster]$ ./redis-trib.rb del-node 192.168.232.128:7007 d1c9dbe277c82b36831b01fe29a0cac1f45f0dd3
刪除已經佔有hash槽的結點會失敗,報錯以下:
[ERR] Node 192.168.232.128:7007 is not empty! Reshard data away and try again.
須要將該結點佔用的hash槽分配出去