Redis集群搭建(基于6.2.6版本)
前言
Redis 在我們工作中使用非常廣泛,之前在掘金平臺上寫過一篇Redis集群的搭建,但是是基于4.0.14版本的,使用的是redis-trib.rb進行搭建的,Redis5之后 推薦使用 redis-cli 命令進行集群搭建,因此本篇使用redis6.2.6在進行一下集群搭建。其他內容基本相同,因此我把文章進行搬運,原文請訪問Redis進群搭建(基于Redis4版本)
簡介
Redis 集群是一個提供在多個Redis節點間共享數據的程序集。
Redis 集群通過分區來提供一定程度的高可用性,在實際環境中,當某個節點宕機或者不可達的情況下能夠繼續提供服務;
Redis 集群的優勢:
1、自動分割數據到不同的節點上。
2、在整個集群的部分節點宕機或者不可達的情況下能夠繼續處理命令對外提供服務。
集群的數據分片
Redis 集群沒有使用一致性hash, 而是引入了 哈希槽的概念。
Redis 集群有16384個哈希槽,每個key通過CRC16算法校驗后對16384取模來決定放置在哪個槽。公式為 CRC16(Key) % 16384 , 集群的每個節點負責一部分hash槽,舉個例子,比如當前集群有3個節點,那么:
- 節點 A 包含 0 到 5500號哈希槽;
- 節點 B 包含5501 到 11000 號哈希槽;
- 節點 C 包含11001 到 16384號哈希槽;
這種結構很容易添加或者刪除節點. 比如如果我想新添加個節點D, 我需要從節點 A, B, C中得部分槽移動到D上. 如果我想移除節點A,需要將A中的槽移動到B和C節點上,然后將沒有任何槽的A節點從集群中移除即可。 由于從一個節點將哈希槽移動到另一個節點并不會停止服務,所以無論添加刪除或者改變某個節點的哈希槽的數量都不會造成集群不可用的狀態。
redis集群的架構是這樣的:
細節描述:
(1) 所有的redis節點彼此互聯(PING-PONG機制),內部使用二進制協議優化傳輸速度和帶寬。
(2) 節點的fail是通過集群中超過半數的節點檢測失效時才生效。
(3) 客戶端與redis節點直連,不需要中間proxy層.客戶端不需要連接集群所有節點,連接集群中任何一個可用節點即可。
(4) redis-cluster把所有的物理節點映射到[0-16383]slot上,cluster 負責維護node–>slot–>value
Redis 集群的主從復制模型
為了使在部分節點失敗或者大部分節點無法通信的情況下集群仍然可用,所以集群使用了主從復制模型,每個節點都會有N-1個復制品.
在我們例子中具有A,B,C三個節點的集群,在沒有復制模型的情況下,如果節點B失敗了,那么整個集群就會以為缺少5501-11000這個范圍的槽而不可用.
然而如果在集群創建的時候(或者過一段時間)我們為每個節點添加一個從節點A1,B1,C1,那么整個集群便有三個master節點和三個slave節點組成,這樣在節點B失敗后,集群便會選舉B1為新的主節點繼續服務,整個集群便不會因為槽找不到而不可用了。
不過當B和B1 都失敗后,集群是不可用的。
集群投票:容錯
(1)、集群中所有master參與投票,如果半數以上master節點與其中一個master節點通信超過(cluster-node-timeout),認為該master節點掛掉。
(2)、什么時候整個集群不可用(cluster_state:fail)
如果集群任意master掛掉,且當前master沒有slave,則集群進入fail狀態。也可以理解成集群的[0-16383]slot映射不完全時進入fail狀態。
如果集群超過半數以上master掛掉,無論是否有slave,集群進入fail狀態。
Redis 一致性保證
Redis 并不能保證數據的強一致性。 這意味這在實際中集群在特定的條件下可能會丟失寫操作。
第一個原因是因為集群是采用了異步復制。 寫操作過程:
- 客戶端向主節點B寫入一條命令;
- 主節點B向客戶端回復命令狀態;
- 主節點將寫操作復制給他得從節點 B1, B2 和 B3;
主節點對命令的復制工作發生在返回命令回復之后, 因為如果每次處理命令請求都需要等待復制操作完成的話, 那么主節點處理命令請求的速度將極大地降低 —— 我們必須在性能和一致性之間做出權衡。 注意:Redis 集群可能會在將來提供同步寫的方法。 Redis 集群另外一種可能會丟失命令的情況是集群出現了網絡分區, 并且一個客戶端與至少包括一個主節點在內的少數實例被孤立。
舉個例子 假設集群包含 A 、 B 、 C 、 A1 、 B1 、 C1 六個節點, 其中 A 、B 、C 為主節點, A1 、B1 、C1 為A,B,C的從節點, 還有一個客戶端 Z1 假設集群中發生網絡分區,那么集群可能會分為兩方,大部分的一方包含節點 A 、C 、A1 、B1 和 C1 ,小部分的一方則包含節點 B 和客戶端 Z1 .
Z1仍然能夠向主節點B中寫入, 如果網絡分區發生時間較短,那么集群將會繼續正常運作,如果分區的時間足夠讓大部分的一方將B1選舉為新的master,那么Z1寫入B中得數據便丟失了。
注意, 在網絡分裂出現期間, 客戶端 Z1 可以向主節點 B 發送寫命令的最大時間是有限制的, 這一時間限制稱為節點超時時間(node timeout), 是 Redis 集群的一個重要的配置選項。
注意, 在網絡分裂出現期間, 客戶端 Z1 可以向主節點 B 發送寫命令的最大時間是有限制的, 這一時間限制稱為節點超時時間(node timeout), 是 Redis 集群的一個重要的配置選項。
搭建Redis集群
說明
根據官網,搭建Redis集群需要三個主節點和三個從節點,即至少6個Redis節點。因為本人并沒有那么多的機器,所以只能通過設置不同的端口號啟動6個Redis節點來模擬Redis集群搭建。不過和生產上其實沒有分別。
下載安裝Redis
wget https://download.redis.io/releases/redis-6.2.6.tar.gz下載完成后進行解壓安裝:
tar -zxvf redis-6.2.6.tar.gz cd redis-6.2.6 make install PREFIX=/usr/local/redis/redis-6.2.6 #指定自己的安裝路徑為了方便管理,我們創建一個集群目錄cluster,進入到redis目錄:
cd /usr/local/redis/redis-6.2.6 mkdir cluster cd cluster # 官網端口從7000~7005 mkdir 7000 7001 7002 7003 7004 7005拷貝并修改配置文件
將redis目錄下的redix.conf文件拷貝到7000~7005目錄中并修改配置文件中的如下內容:
# 端口 98行 port 7000 # 后臺啟動 257行 daemonize yes #pid 文件路徑 289行 為了方便管理,創建了redis-data/pidfile目錄 pidfile /var/run/redis-data/pidfile/redis_7000.pid # 日志文件 302行 為了方便管理,創建了redis-data/logfile目錄 logfile "/var/run/redis-data/logfile/7000.log" # rdb文件 431行 dbfilename dump7000.rdb # 開啟aof 1252行 appendonly yes # append only file 文件 1256行 appendfilename "appendonly7000.aof" # 開啟集群 1385行 cluster-enabled yes #集群節點配置文件 1393行 cluster-config-file nodes-7000.conf # 開啟集群節點超時時間 1399行 cluster-node-timeout 15000每個端口的配置文件都需要修改以上10項,根據行數進行查找修改,很快就能修改完成。
為了方便啟動,我們在/usr/local/redis/redis-6.2.6目錄下編寫啟動腳本 redis-start.sh:
停止腳本:
#!/bin/bash src/redis-cli -p 7000 shutdown src/redis-cli -p 7001 shutdown src/redis-cli -p 7002 shutdown src/redis-cli -p 7003 shutdown src/redis-cli -p 7004 shutdown src/redis-cli -p 7005 shutdown賦予腳本可執行的能力
#啟動腳本 chmod 544 redis-start.sh #關閉腳本 chmod 544 redis-stop.sh # 運行啟動腳本 sh redis-start.sh # 查看redis進程 ps -ef | grep redis |grep -v grep如果能看到如下信息。說明redis6個節點啟動成功。注意:必須是以集群【cluster】方式啟動
root 28493 1 0 16:47 ? 00:00:00 src/redis-server *:7000 [cluster] root 28495 1 0 16:47 ? 00:00:00 src/redis-server *:7001 [cluster] root 28497 1 0 16:47 ? 00:00:00 src/redis-server *:7002 [cluster] root 28503 1 0 16:47 ? 00:00:00 src/redis-server *:7005 [cluster] root 28505 1 0 16:47 ? 00:00:00 src/redis-server *:7003 [cluster] root 28515 1 0 16:47 ? 00:00:00 src/redis-server *:7004 [cluster]開啟集群
因為我們的redis版本是6.2.6,根據redis官網,redis5及以上的版本可以使用redis-cli --cluster 命令創建集群:
redis-cli --cluster create 127.0.0.1:7000 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 \ --cluster-replicas 1如果你的redis設置的有密碼,在以上命令的后邊加上密碼即可
redis-cli --cluster create 127.0.0.1:7000 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 \ --cluster-replicas 1 -a 密碼如果要對集群設置密碼:requirepass和masterauth 都需要進行設置,并且需要每個節點的密碼都保持相同;
出現如上信息,說明16284個哈希槽已經全部分配完畢,此時集群搭建成功。
進行測試
通過如下命令進行連接:
./redis-cli -c -p 7000 -a 密碼
經過測試,redis集群可以正常提供服務;
總結
以上是生活随笔為你收集整理的Redis集群搭建(基于6.2.6版本)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: High Dimensional Con
- 下一篇: Google Earth Engine(