驚呆了,竟然可以用這種方式秒建 Redis 集群?

驚呆了,竟然可以用這種方式秒建 Redis 集群?

作者 | 老王

來源 | Java 中文社區

前面我們講了《Redis 性能優化的 13 條軍規!》,其中最重要的一條就是使用 Redis 的集群功能,那麼本文我們就來看看,如何用 1s 鐘的時間來創建一個 Redis 集群。

Redis Cluster 是 Redis 3.0 版本推出的 Redis 集群方案,它將數據分佈在不同的服務區上,以此來降低系統對單主節點的依賴,並且可以大大的提高 Redis 服務的讀寫性能。

Redis 將所有的數據分為 16384 個 slots(槽),每個節點負責其中的一部分槽位,當有 Redis 客戶端連接集群時,會得到一份集群的槽位配置信息,這樣它就可以直接把請求命令發送給對應的節點進行處理。

Redis Cluster 是無代理模式去中心化的運行模式,客戶端發送的絕大數命令會直接交給相關節點執行,這樣大部分情況請求命令無需轉發,或僅轉發一次的情況下就能完成請求與響應,所以集群單個節點的性能與單機 Redis 服務器的性能是非常接近的,因此在理論情況下,當水平擴展一倍的主節點就相當於請求處理的性能也提高了一倍,所以 Redis Cluster 的性能是非常高的。

Redis Cluster 架構圖如下所示:

惊呆了,竟然可以用这种方式秒建 Redis 集群?
惊呆了,竟然可以用这种方式秒建 Redis 集群?

秒建 Redis 集群

Redis Cluster 的搭建方式有兩種,一種是使用 Redis 源碼中提供的 create-cluster 工具快速的搭建 Redis 集群環境,另一種是配置文件的方式手動創建 Redis 集群環境。

1.快速搭建 Redis Cluster

create-cluster 工具在 utils/create-cluster 目錄下,如下圖所示:

惊呆了,竟然可以用这种方式秒建 Redis 集群?

使用命令 ./create-cluster start 就可以急速創建一個 Redis 集群,執行如下:

<code>1$ ./create-cluster start # 創建集群
2Starting 30001
3Starting 30002
4Starting 30003
5Starting 30004
6Starting 30005
7Starting 30006
/<code>

接下來我們需要把以上創建的 6 個節點節點通過 create 命令組成一個集群,執行如下:

<code> 1[@iZ2ze0nc5n41zomzyqtksmZ:create-cluster]$ ./create-cluster create # 組建集群
2>>> Performing hash slots allocation on 6 nodes...
3Master[0] -> Slots 0 - 5460
4Master[1] -> Slots 5461 - 10922
5Master[2] -> Slots 10923 - 16383
6Adding replica 127.0.0.1:30005 to 127.0.0.1:30001
7Adding replica 127.0.0.1:30006 to 127.0.0.1:30002
8Adding replica 127.0.0.1:30004 to 127.0.0.1:30003
9>>> Trying to optimize slaves allocation for anti-affinity
10[WARNING] Some slaves are in the same host as their master
11M: 445f2a86fe36d397613839d8cc1ae6702c976593 127.0.0.1:30001
12 slots:[0-5460] (5461 slots) master
13M: 63bb14023c0bf58926738cbf857ea304bff8eb50 127.0.0.1:30002
14 slots:[5461-10922] (5462 slots) master
15M: 864d4dfe32e3e0b81a64cec8b393bbd26a65cbcc 127.0.0.1:30003
16 slots:[10923-16383] (5461 slots) master
17S: 64828ab44566fc5ad656e831fd33de87be1387a0 127.0.0.1:30004
18 replicates 445f2a86fe36d397613839d8cc1ae6702c976593
19S: 0b17b00542706343583aa73149ec5ff63419f140 127.0.0.1:30005
20 replicates 63bb14023c0bf58926738cbf857ea304bff8eb50
21S: e35f06ca9b700073472d72001a39ea4dfcb541cd 127.0.0.1:30006
22 replicates 864d4dfe32e3e0b81a64cec8b393bbd26a65cbcc
23Can I set the above configuration? (type 'yes' to accept): yes
24>>> Nodes configuration updated
25>>> Assign a different config epoch to each node
26>>> Sending CLUSTER MEET messages to join the cluster
27Waiting for the cluster to join
28.
29>>> Performing Cluster Check (using node 127.0.0.1:30001)
30M: 445f2a86fe36d397613839d8cc1ae6702c976593 127.0.0.1:30001

31 slots:[0-5460] (5461 slots) master
32 1 additional replica(s)
33M: 864d4dfe32e3e0b81a64cec8b393bbd26a65cbcc 127.0.0.1:30003
34 slots:[10923-16383] (5461 slots) master
35 1 additional replica(s)
36S: e35f06ca9b700073472d72001a39ea4dfcb541cd 127.0.0.1:30006
37 slots: (0 slots) slave
38 replicates 864d4dfe32e3e0b81a64cec8b393bbd26a65cbcc
39S: 0b17b00542706343583aa73149ec5ff63419f140 127.0.0.1:30005
40 slots: (0 slots) slave
41 replicates 63bb14023c0bf58926738cbf857ea304bff8eb50
42M: 63bb14023c0bf58926738cbf857ea304bff8eb50 127.0.0.1:30002
43 slots:[5461-10922] (5462 slots) master
44 1 additional replica(s)
45S: 64828ab44566fc5ad656e831fd33de87be1387a0 127.0.0.1:30004
46 slots: (0 slots) slave
47 replicates 445f2a86fe36d397613839d8cc1ae6702c976593
48[OK] All nodes agree about slots configuration.
49>>> Check for open slots...
50>>> Check slots coverage...
51[OK] All 16384 slots covered.
/<code>

在執行的過程中會詢問你是否通過把 30001、30002、30003 作為為主節點,把 30004、30005、30006 作為它們的從節點,輸入 yes 後會執行完成。

我們可以先使用 redis-cli 連接到集群,命令如下:


<code>1$ redis-cli -c -p 30001
/<code>

在使用 nodes 命令來查看集群的節點信息,命令如下:


<code>1127.0.0.1:30001> cluster nodes
2864d4dfe32e3e0b81a64cec8b393bbd26a65cbcc 127.0.0.1:30003@40003 master - 0 1585125835078 3 connected 10923-16383

3e35f06ca9b700073472d72001a39ea4dfcb541cd 127.0.0.1:30006@40006 slave 864d4dfe32e3e0b81a64cec8b393bbd26a65cbcc 0 1585125835078 6 connected
40b17b00542706343583aa73149ec5ff63419f140 127.0.0.1:30005@40005 slave 63bb14023c0bf58926738cbf857ea304bff8eb50 0 1585125835078 5 connected
563bb14023c0bf58926738cbf857ea304bff8eb50 127.0.0.1:30002@40002 master - 0 1585125834175 2 connected 5461-10922
6445f2a86fe36d397613839d8cc1ae6702c976593 127.0.0.1:30001@40001 myself,master - 0 1585125835000 1 connected 0-5460
764828ab44566fc5ad656e831fd33de87be1387a0 127.0.0.1:30004@40004 slave 445f2a86fe36d397613839d8cc1ae6702c976593 0 1585125835000 4 connected
/<code>

可以看出 30001、30002、30003 都為主節點,30001 對應的槽位是 0-5460,30002 對應的槽位是 5461-10922,30003 對應的槽位是 10923-16383,總共有槽位 16384 個 (0 ~ 16383)。

30002 對應的槽位是 5461-10922,30003 對應的槽位是 10923-16383,總共有槽位 16384 個 (0 ~ 16383)。

create-cluster 搭建的方式雖然速度很快,但是該方式搭建的集群主從節點數量固定以及槽位分配模式固定,並且安裝在同一臺服務器上,所以只能用於測試環境。

我們測試完成之後,可以使用以下命令,關閉並清理集群:


<code>1$ ./create-cluster stop # 關閉集群
2Stopping 30001
3Stopping 30002
4Stopping 30003
5Stopping 30004
6Stopping 30005
7Stopping 30006
8$ ./create-cluster clean # 清理集群
/<code>

2.手動搭建 Redis Cluster

由於 create-cluster 本身的限制,在實際生產環境中我們需要使用手動添加配置的方式搭建 Redis 集群,為此我們先要把 Redis 安裝包複製到 node1 到 node6 文件中,因為我們要安裝 6 個節點,3 主 3 從,如下圖所示:

惊呆了,竟然可以用这种方式秒建 Redis 集群?惊呆了,竟然可以用这种方式秒建 Redis 集群?

接下來我們進行配置並啟動 Redis 集群。

① 設置配置文件

我們需要修改每個節點內的 redis.conf 文件,設置 cluster-enabled yes 表示開啟集群模式,並且修改各自的端口,我們繼續使用 30001 到 30006,通過 port 3000X 設置。

② 啟動各個節點

redis.conf 配置好之後,我們就可以啟動所有的節點了,命令如下:


<code>1cd /usr/local/soft/mycluster/node1
2./src/redis-server redis.conf
/<code>

③ 創建集群並分配槽位

之前我們已經啟動了 6 個節點,但這些節點都在各自的集群之內並未互聯互通,因此接下來我們需要把這些節點串連成一個集群,併為它們指定對應的槽位,執行命令如下:

 

<code>1redis-cli --cluster create 127.0.0.1:30001 127.0.0.1:30002 127.0.0.1:30003 127.0.0.1:30004 127.0.0.1:30005 127.0.0.1:30006 --cluster-replicas 1
/<code>

其中 create 後面跟多個節點,表示把這些節點作為整個集群的節點,而 cluster-replicas 表示給集群中的主節點指定從節點的數量,1 表示為每個主節點設置一個從節點。

在執行了 create 命令之後,系統會為我們指定節點的角色和槽位分配計劃,如下所示:


<code> 1>>> Performing hash slots allocation on 6 nodes...
2Master[0] -> Slots 0 - 5460
3Master[1] -> Slots 5461 - 10922
4Master[2] -> Slots 10923 - 16383
5Adding replica 127.0.0.1:30005 to 127.0.0.1:30001
6Adding replica 127.0.0.1:30006 to 127.0.0.1:30002
7Adding replica 127.0.0.1:30004 to 127.0.0.1:30003
8>>> Trying to optimize slaves allocation for anti-affinity
9[WARNING] Some slaves are in the same host as their master
10M: bdd1c913f87eacbdfeabc71befd0d06c913c891c 127.0.0.1:30001
11 slots:[0-5460] (5461 slots) master
12M: bdd1c913f87eacbdfeabc71befd0d06c913c891c 127.0.0.1:30002
13 slots:[5461-10922] (5462 slots) master
14M: bdd1c913f87eacbdfeabc71befd0d06c913c891c 127.0.0.1:30003
15 slots:[10923-16383] (5461 slots) master
16S: bdd1c913f87eacbdfeabc71befd0d06c913c891c 127.0.0.1:30004
17 replicates bdd1c913f87eacbdfeabc71befd0d06c913c891c
18S: bdd1c913f87eacbdfeabc71befd0d06c913c891c 127.0.0.1:30005
19 replicates bdd1c913f87eacbdfeabc71befd0d06c913c891c
20S: bdd1c913f87eacbdfeabc71befd0d06c913c891c 127.0.0.1:30006
21 replicates bdd1c913f87eacbdfeabc71befd0d06c913c891c
22Can I set the above configuration? (type 'yes' to accept):
/<code>

從以上信息可以看出,Redis 打算把 30001、30002、30003 設置主節點,併為他們分配的槽位,30001 對應的槽位是 0-5460,30002 對應的槽位是 5461-10922,30003 對應的槽位是 10923-16383,並且把 30005 設置為 30001 的從節點、30006 設置為 30002 的從節點、30004 設置為 30003 的從節點,我們只需要輸入 yes 即可確認並執行分配,如下所示:

<code> 1Can I set the above configuration? (type 'yes' to accept): yes
2>>> Nodes configuration updated
3>>> Assign a different config epoch to each node
4>>> Sending CLUSTER MEET messages to join the cluster
5Waiting for the cluster to join
6....
7>>> Performing Cluster Check (using node 127.0.0.1:30001)
8M: 887397e6fefe8ad19ea7569e99f5eb8a803e3785 127.0.0.1:30001
9 slots:[0-5460] (5461 slots) master
10 1 additional replica(s)
11S: abec9f98f9c01208ba77346959bc35e8e274b6a3 127.0.0.1:30005
12 slots: (0 slots) slave
13 replicates 887397e6fefe8ad19ea7569e99f5eb8a803e3785
14S: 1a324d828430f61be6eaca7eb2a90728dd5049de 127.0.0.1:30004
15 slots: (0 slots) slave
16 replicates f5958382af41d4e1f5b0217c1413fe19f390b55f
17S: dc0702625743c48c75ea935c87813c4060547cef 127.0.0.1:30006
18 slots: (0 slots) slave
19 replicates 3da35c40c43b457a113b539259f17e7ed616d13d
20M: 3da35c40c43b457a113b539259f17e7ed616d13d 127.0.0.1:30002
21 slots:[5461-10922] (5462 slots) master
22 1 additional replica(s)
23M: f5958382af41d4e1f5b0217c1413fe19f390b55f 127.0.0.1:30003
24 slots:[10923-16383] (5461 slots) master
25 1 additional replica(s)
26[OK] All nodes agree about slots configuration.
27>>> Check for open slots...
28>>> Check slots coverage...
29[OK] All 16384 slots covered.
/<code>

顯示 OK 表示整個集群就已經成功啟動了。

接下來,我們使用 redis-cli 連接並測試一下集群的運行狀態,代碼如下:


<code> 1$ redis-cli -c -p 30001 # 連接到集群
2127.0.0.1:30001> cluster info # 查看集群信息
3cluster_state:ok # 狀態正常

4cluster_slots_assigned:16384 # 槽位數
5cluster_slots_ok:16384 # 正常的槽位數
6cluster_slots_pfail:0
7cluster_slots_fail:0
8cluster_known_nodes:6 # 集群的節點數
9cluster_size:3 # 集群主節點數
10cluster_current_epoch:6
11cluster_my_epoch:1
12cluster_stats_messages_ping_sent:130
13cluster_stats_messages_pong_sent:127
14cluster_stats_messages_sent:257
15cluster_stats_messages_ping_received:122
16cluster_stats_messages_pong_received:130
17cluster_stats_messages_meet_received:5
18cluster_stats_messages_received:257
/<code>

相關字段的說明已經標識在上述的代碼中了,這裡就不再贅述。

惊呆了,竟然可以用这种方式秒建 Redis 集群?

動態增刪節點

某些情況下,我們需要根據實際的業務情況,對已經在運行的集群進行動態的添加或刪除節點,那我們就需要進行以下操作。

1.增加主節點

添加方式一:cluster meet

使用 cluster meet ip:port 命令就可以把一個節點加入到集群中,執行命令如下:


<code> 1127.0.0.1:30001> cluster meet 127.0.0.1 30007
2OK
3127.0.0.1:30001> cluster nodes
4dc0702625743c48c75ea935c87813c4060547cef 127.0.0.1:30006@40006 slave 3da35c40c43b457a113b539259f17e7ed616d13d 0 1585142916000 6 connected
5df0190853a53d8e078205d0e2fa56046f20362a7 127.0.0.1:30007@40007 master - 0 1585142917740 0 connected
6f5958382af41d4e1f5b0217c1413fe19f390b55f 127.0.0.1:30003@40003 master - 0 1585142916738 3 connected 10923-16383
73da35c40c43b457a113b539259f17e7ed616d13d 127.0.0.1:30002@40002 master - 0 1585142913000 2 connected 5461-10922
8abec9f98f9c01208ba77346959bc35e8e274b6a3 127.0.0.1:30005@40005 slave 887397e6fefe8ad19ea7569e99f5eb8a803e3785 0 1585142917000 5 connected
9887397e6fefe8ad19ea7569e99f5eb8a803e3785 127.0.0.1:30001@40001 myself,master - 0 1585142915000 1 connected 0-5460
101a324d828430f61be6eaca7eb2a90728dd5049de 127.0.0.1:30004@40004 slave f5958382af41d4e1f5b0217c1413fe19f390b55f 0 1585142916000 4 connected
/<code>

可以看出端口為 30007 的節點並加入到集群中,並設置成了主節點。

添加方式二:add-node

使用 redis-cli --cluster add-node 添加節點ip:port 集群某節點ip:port 也可以把一個節點添加到集群中,執行命令如下:

<code> 1$ redis-cli --cluster add-node 127.0.0.1:30008 127.0.0.1:30001
2>>> Adding node 127.0.0.1:30008 to cluster 127.0.0.1:30001
3>>> Performing Cluster Check (using node 127.0.0.1:30001)
4M: 887397e6fefe8ad19ea7569e99f5eb8a803e3785 127.0.0.1:30001
5 slots:[0-5460] (5461 slots) master
6 1 additional replica(s)
7S: dc0702625743c48c75ea935c87813c4060547cef 127.0.0.1:30006
8 slots: (0 slots) slave
9 replicates 3da35c40c43b457a113b539259f17e7ed616d13d
10M: df0190853a53d8e078205d0e2fa56046f20362a7 127.0.0.1:30007
11 slots: (0 slots) master
12M: f5958382af41d4e1f5b0217c1413fe19f390b55f 127.0.0.1:30003
13 slots:[10923-16383] (5461 slots) master
14 1 additional replica(s)
15M: 1d09d26fd755298709efe60278457eaa09cefc26 127.0.0.1:30008
16 slots: (0 slots) master
17M: 3da35c40c43b457a113b539259f17e7ed616d13d 127.0.0.1:30002
18 slots:[5461-10922] (5462 slots) master
19 1 additional replica(s)
20S: abec9f98f9c01208ba77346959bc35e8e274b6a3 127.0.0.1:30005
21 slots: (0 slots) slave
22 replicates 887397e6fefe8ad19ea7569e99f5eb8a803e3785
23S: 1a324d828430f61be6eaca7eb2a90728dd5049de 127.0.0.1:30004
24 slots: (0 slots) slave
25 replicates f5958382af41d4e1f5b0217c1413fe19f390b55f
26[OK] All nodes agree about slots configuration.
27>>> Check for open slots...
28>>> Check slots coverage...
29[OK] All 16384 slots covered.
30[ERR] Node 127.0.0.1:30008 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.
/<code>

從以上結果可以看出 30008 節點也被設置成了主節點。

2.添加從節點

使用 cluster replicate nodeId 命令就可以把當前節點設置為目標節點的從節點,執行命令如下:

<code> 1127.0.0.1:30008> cluster replicate df0190853a53d8e078205d0e2fa56046f20362a7
2OK
3127.0.0.1:30008> cluster nodes
4df0190853a53d8e078205d0e2fa56046f20362a7 127.0.0.1:30007@40007 master - 0 1585147827000 0 connected
5abec9f98f9c01208ba77346959bc35e8e274b6a3 127.0.0.1:30005@40005 slave 887397e6fefe8ad19ea7569e99f5eb8a803e3785 0 1585147827000 1 connected
61a324d828430f61be6eaca7eb2a90728dd5049de 127.0.0.1:30004@40004 slave f5958382af41d4e1f5b0217c1413fe19f390b55f 0 1585147823000 3 connected
7887397e6fefe8ad19ea7569e99f5eb8a803e3785 127.0.0.1:30001@40001 master - 0 1585147826000 1 connected 0-5460
8dc0702625743c48c75ea935c87813c4060547cef 127.0.0.1:30006@40006 slave 3da35c40c43b457a113b539259f17e7ed616d13d 0 1585147826930 2 connected
9f5958382af41d4e1f5b0217c1413fe19f390b55f 127.0.0.1:30003@40003 master - 0 1585147826000 3 connected 10923-16383
101d09d26fd755298709efe60278457eaa09cefc26 127.0.0.1:30008@40008 myself,slave df0190853a53d8e078205d0e2fa56046f20362a7 0 1585147823000 7 connected
113da35c40c43b457a113b539259f17e7ed616d13d 127.0.0.1:30002@40002 master - 0 1585147827933 2 connected 5461-10922
/<code>

可以看出 30008 已經變為 30007 的從節點了。

3.刪除節點

使用 cluster forget nodeId 命令就可以把一個節點從集群中移除。此命令和 meet 命令不同的時,刪除節點需要是使用節點的 Id 進行刪除,可以通過 cluster nodes 命令查看所有節點的 Id 信息,其中每一行的最前面的 40 位字母和數組的組合就是該節點的 Id,如下圖所示:

惊呆了,竟然可以用这种方式秒建 Redis 集群?

執行命令如下:


<code>1127.0.0.1:30001> cluster forget df0190853a53d8e078205d0e2fa56046f20362a7
2OK
/<code>

此時我們使用 cluster nodes 命令查看集群的所有節點信息:


<code>1127.0.0.1:30001> cluster nodes
2dc0702625743c48c75ea935c87813c4060547cef 127.0.0.1:30006@40006 slave 3da35c40c43b457a113b539259f17e7ed616d13d 0 1585143789940 6 connected
3f5958382af41d4e1f5b0217c1413fe19f390b55f 127.0.0.1:30003@40003 master - 0 1585143791000 3 connected 10923-16383
43da35c40c43b457a113b539259f17e7ed616d13d 127.0.0.1:30002@40002 master - 0 1585143789000 2 connected 5461-10922
5abec9f98f9c01208ba77346959bc35e8e274b6a3 127.0.0.1:30005@40005 slave 887397e6fefe8ad19ea7569e99f5eb8a803e3785 0 1585143789000 5 connected
6887397e6fefe8ad19ea7569e99f5eb8a803e3785 127.0.0.1:30001@40001 myself,master - 0 1585143786000 1 connected 0-5460
71a324d828430f61be6eaca7eb2a90728dd5049de 127.0.0.1:30004@40004 slave f5958382af41d4e1f5b0217c1413fe19f390b55f 0 1585143791945 4 connected
/<code>

可以看出之前的端口為 30007 的節點已經被我們成功的移除了。

惊呆了,竟然可以用这种方式秒建 Redis 集群?

小結

本文講了 Redis 集群的兩種搭建方式:create-cluster start 和 cluster create,前一種方式雖然速度比較快,但它只能創建數量固定的主從節點,並且所有節點都在同一臺服務器上,因此只能用於測試環境。我們還講了 Redis 集群動態添加主、從節點和刪除任意節點的功能。

希望本文對你有幫助,動手實踐起來吧~


分享到:


相關文章: