Redis 5.0.7 講解,單機、集群模式搭建


Redis 5.0.7 講解,單機、集群模式搭建

一、Redis 介紹

不管你是從事 Python、Java、Go、PHP、Ruby等等... Redis都應該是一個比較熟悉的中間件。而大部分經常寫業務代碼的程序員,實際工作中或許只用到了 set value、get value 兩個操作。

Redis 概念

Redis 是一個開源的底層使用 C 語言編寫的 key-value 存儲數據庫。可用於緩存、事件發布訂閱、高速隊列等場景。而且支持豐富的數據類型:string(字符串)、hash(哈希)、list(列表)、set(無序集合)、zset(有序集合)

Redis 在 3.0 版本前只支持單實例模式,雖然支持主從模式、哨兵模式部署來解決單點故障,但是現在互聯網企業動輒大幾百 G 的數據,可完全是沒法滿足業務的需求,所以,Redis 在 3.0 版本以后就推出了集群模式。

Redis 應用場景

  1. 緩存數據:最常用,對經常需要查詢且變動不是很頻繁的數據。
  2. 消息隊列:相當於消息訂閱系統,類似與 RabbitMQ、ActiveMQ、RocketMQ。如果對數據有較高一致性要求時,還是建議使用 MQ。
  3. 計數器:比如統計點擊率、點贊率,Redis 具有原子性,可以避免並發問題。
  4. 電商網站信息:大型電商平台初始化頁面數據的緩存。比如去哪兒網購買機票的時候首頁的價格和你點進去的價格會有差異。
  5. 熱點數據:比如新聞網站實時熱點、微博熱搜等,需要頻繁更新。總數據量比較大的時候直接從數據庫查詢會影響性能。
  6. 分布式鎖:分布式程序可以用 Redis 來存儲鎖信息。

Redis 數據類型

類型 說明
string(字符串) string 是 Redis 最基本的類型,你可以理解成與 Memcached 一模一樣的類型,一個 key 對應一個 value。string 類型是二進制安全的。意思是 Redis 的 string 可以包含任何數據。比如 jpg 圖片或者序列化的對象 。string 類型是 Redis 最基本的數據類型,一個鍵最大能存儲 512MB。
hash(哈希) Redis hash 是一個鍵值對集合。Redis hash 是一個 string 類型的 field 和 value 的映射表,hash 特別適合用於存儲對象。每個 hash 可以存儲 2 * 32 - 1 鍵值對(4294967295, 每個哈希可存儲 40 多億個成員)。
list(列表) Redis 列表是簡單的字符串列表,按照插入順序排序。你可以添加一個元素導列表的頭部(左邊)或者尾部(右邊)。列表最多可存儲 2 * 32 - 1元素 (4294967295, 每個列表可存儲 40 多億個成員)。
set(無序集合) Redis 的 set 是 string 類型的無序集合。集合是通過哈希表實現的,所以添加,刪除,查找的復雜度都是O(1)。集合中最大的成員數為 2 * 32 - 1 (4294967295, 每個集合可存儲 40 多億個成員)。
zset(有序集合) Redis zset 和 set 一樣也是 string 類型元素的集合,且不允許重復的成員。不同的是每個元素都會關聯一個double 類型的分數。Redis 正是通過分數來為集合中的成員進行從小到大的排序。 zset 的成員是唯一的,但分數(score)卻可以重復。

Redis 數據類型應用場景

前面提到了 Redis 支持五種豐富的數據類型,那么在不同場景下的選擇

string

字符串是最常用的數據類型,他能夠存儲任何類型的字符串,當然也包括二進制、JSON化的對象、甚至是base64編碼之后的圖片。在Redis中一個字符串最大的容量為512MB,可以說是無所不能了。

hash

常用作存儲結構化數據、比如論壇系統中可以用來存儲用戶的Id、昵稱、頭像、積分等信息。如果需要修改其中的信息,只需要通過Key取出Value進行反序列化修改某一項的值,再序列化存儲到Redis中,Hash結構存儲,由於Hash結構會在單個Hash元素在不足一定數量時進行壓縮存儲,所以可以大量節約內存。這一點在String結構里是不存在的。

list

List的實現為一個雙向鏈表,即可以支持反向查找和遍歷,更方便操作,不過帶來了部分額外的內存開銷,Redis 內部的很多實現,包括發送緩沖隊列等也都是用的這個數據結構。另外,可以利用 lrange 命令,做基於 Redis 的分頁功能,性能極佳,用戶體驗好。

set

set 對外提供的功能與 list 類似是一個列表的功能,特殊之處在於 set 是可以自動排重的,當你需要存儲一個列表數據,又不希望出現重復數據時,這個時候就可以選擇使用set。

zset

可以按照某個條件的權重進行排序,比如可以通過點擊數做出排行榜的數據應用。

Redis 優勢和缺點

優勢:

  1. 速度快,因為數據存在內存中,類似於HashMap,HashMap的優勢就是查找和操作的時間復雜度都是O(1)。
  2. 支持豐富數據類型,支持string,list,set,sorted set,hash。
  3. 支持事務,操作都是原子性,所謂的原子性就是對數據的更改要么全部執行,要么全部不執行。
  4. 豐富的特性:可用於緩存,消息,按key設置過期時間,過期后將會自動刪除。

缺點:

  1. 由於 Redis 是內存數據庫,所以,單台機器,存儲的數據量,跟機器本身的內存大小。雖然 Redis 本身有 Key 過期策略,但是還是需要提前預估和節約內存。如果內存增長過快,需要定期刪除數據。
  2. Redis 是單線程的,單台服務器無法充分利用多核服務器的 CPU。

Redis 相比同類型的 Memcached 有哪些優勢?

  1. Memcached 所有的值均是簡單的字符串,Redis 作為其替代者,支持更為豐富的數據類型。
  2. Redis 的速度比 Memcached 快很多
  3. Redis 可以持久化其數據到硬盤

Redis 常見性能問題和解決方案

  1. Master 最好不要做任何持久化工作,如 RDB 內存快照和 AOF 日志文件
  2. 如果數據比較重要,某個 Slave 開啟 AOF 備份數據,策略設置為每秒同步一次
  3. 為了主從復制的速度和連接的穩定性,Master 和 Slave 最好在同一個局域網內
  4. 盡量避免在壓力很大的主庫上增加從庫
  5. 主從復制不要用圖狀結構,用單向鏈表結構更為穩定,即:Master <- Slave1 <- Slave2 <- Slave3…這樣的結構方便解決單點故障問題,實現 Slave 對 Master 的替換。如果 Master 掛了,可以立刻啟用 Slave1 做 Master,其他不變。

二、Redis 單機安裝

服務器系統為 centos 7.5,Redis 版本為 5.0.7,采用源碼方式安裝。

安裝

yum install -y gcc
wget http://download.redis.io/releases/redis-5.0.7.tar.gz
tar xzf redis-5.0.7.tar.gz
cd redis-5.0.7
make
mkdir -p /usr/local/redis/bin
cp src/redis-server /usr/local/redis/bin
cp src/redis-cli /usr/local/redis/bin
cp src/redis-sentinel /usr/local/redis/bin
cp src/redis-trib.rb /usr/local/redis/bin
cp src/redis-check-aof /usr/local/redis/bin
cp src/redis-check-rdb /usr/local/redis/bin
cp src/redis-benchmark /usr/local/redis/bin
echo 'export PATH=$PATH:/usr/local/redis/bin' >> .bash_profile
. .bash_profile
cp ./redis.conf /etc

配置

vim /etc/redis.conf,修改其中配置:

bind 0.0.0.0	# 把 127.0.0.1 改為 0.0.0.0,監聽所有 IPV4 地址,可以根據需求設置
daemonize yes	# 把 no 修改為 yes,后台運行

啟動

$ redis-server /etc/redis.conf

驗證

$ redis-cli 
127.0.0.1:6379> 
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> 

也可以通過桌面客戶端驗證:redis desktop manager - https://github.com/uglide/RedisDesktopManager/releases

設置開機啟動

vim /usr/lib/systemd/system/redis.service:

[Unit]
Description=Redis Server
After=network.target

[Service]
Type=simple
# User=redis
# Group=redis
PIDFile=/var/run/redis.pid
ExecStart=/usr/local/redis/bin/redis-server /etc/redis.conf --daemonize no
# ExecStop=/usr/local/redis/bin/redis-cli shutdown
ExecStop=/usr/local/redis/bin/redis-cli -p 6379 shutdown
Restart=always
 
[Install]
WantedBy=multi-user.target
systemctl daemon-reload 
systemctl start redis
systemctl enable redis

三、Redis 集群安裝

2018 年 10 月 Redis 發布了穩定版本的 5.0 版本,推出了各種新特性,其中一點是放棄 Ruby 的集群方式,改為 使用 C 語言編寫的 redis-cli 的方式,是集群的構建方式復雜度大大降低。

服務器系統為 centos 7.5,Redis 版本為 5.0.7,采用源碼方式安裝。在一台服務器上搭建有 6 個節點的 Redis 集群。(因為Redis 集群最低 6 個節點,不然無法創建)

安裝

yum install -y gcc
wget http://download.redis.io/releases/redis-5.0.7.tar.gz
tar xzf redis-5.0.7.tar.gz
cd redis-5.0.7
make
mkdir -p /usr/local/redis/bin
cp src/redis-server /usr/local/redis/bin
cp src/redis-cli /usr/local/redis/bin
cp src/redis-sentinel /usr/local/redis/bin
cp src/redis-trib.rb /usr/local/redis/bin
cp src/redis-check-aof /usr/local/redis/bin
cp src/redis-check-rdb /usr/local/redis/bin
cp src/redis-benchmark /usr/local/redis/bin
echo 'export PATH=$PATH:/usr/local/redis/bin' >> .bash_profile
. .bash_profile

創建 6 個配置文件並配置

mkdir /etc/redis-cluster
cp redis.conf /etc/redis-cluster/redis-7001.conf
cp redis.conf /etc/redis-cluster/redis-7002.conf
cp redis.conf /etc/redis-cluster/redis-7003.conf
cp redis.conf /etc/redis-cluster/redis-7004.conf
cp redis.conf /etc/redis-cluster/redis-7005.conf 
cp redis.conf /etc/redis-cluster/redis-7006.conf
mkdir /opt/redis-7001
mkdir /opt/redis-7002
mkdir /opt/redis-7003
mkdir /opt/redis-7004
mkdir /opt/redis-7005
mkdir /opt/redis-7006

修改所有的配置文件 (端口以及目錄依次類推)

port 7001	# 監聽端口
bind 0.0.0.0  # 監聽 ip
dir /opt/redis-7001		# 指定文件存放路徑 ( .rdb .aof nodes-xxxx.conf 這樣的文件都會在此路徑下)
cluster-enabled yes   # 啟動集群模式 
cluster-config-file nodes-7001.conf		# 集群節點配置文件
daemonize yes		# 后台啟動
cluster-node-timeout 5000		# 集群節點超時時間​
appendonly yes		# 指定持久化方式,開啟 AOF 模式
protected-mode no	# 非保護模式

啟動節點

redis-server /etc/redis-cluster/redis-7001.conf
redis-server /etc/redis-cluster/redis-7002.conf
redis-server /etc/redis-cluster/redis-7003.conf
redis-server /etc/redis-cluster/redis-7004.conf
redis-server /etc/redis-cluster/redis-7005.conf
redis-server /etc/redis-cluster/redis-7006.conf

創建集群

redis-cli --cluster create 192.168.223.111:7001 192.168.223.111:7002 192.168.223.111:7003 192.168.223.111:7004 192.168.223.111:7005 192.168.223.111:7006 --cluster-replicas 1
  • --replicas 1 表示為集群中的每個主節點創建一個從節點,6 個節點就是 3 主 3 從。

結果

>>> 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.223.111:7005 to 192.168.223.111:7001
Adding replica 192.168.223.111:7006 to 192.168.223.111:7002
Adding replica 192.168.223.111:7004 to 192.168.223.111:7003
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001
   slots:[0-5460] (5461 slots) master
M: 9a347d87b115ab8be8662771aa2d0579465ae6ff 192.168.223.111:7002
   slots:[5461-10922] (5462 slots) master
M: 15e768a013d6042de80b82aa2274ffcf30381085 192.168.223.111:7003
   slots:[10923-16383] (5461 slots) master
S: 70b40a69c2ee564cf1e1ff59f26b1a754443509e 192.168.223.111:7004
   replicates 9a347d87b115ab8be8662771aa2d0579465ae6ff
S: 478491a5f75d8fbceeaa7a61bbc4866b5893b99c 192.168.223.111:7005
   replicates 15e768a013d6042de80b82aa2274ffcf30381085
S: ec514db1730a466cf10d3ee54f32003c7690602a 192.168.223.111:7006
   replicates b3919787aa7bc4123e5f87b8995680e2187bf4cc
Can I set the above configuration? (type 'yes' to accept): 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.223.111:7001)
M: b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: ec514db1730a466cf10d3ee54f32003c7690602a 192.168.223.111:7006
   slots: (0 slots) slave
   replicates b3919787aa7bc4123e5f87b8995680e2187bf4cc
M: 15e768a013d6042de80b82aa2274ffcf30381085 192.168.223.111:7003
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 70b40a69c2ee564cf1e1ff59f26b1a754443509e 192.168.223.111:7004
   slots: (0 slots) slave
   replicates 9a347d87b115ab8be8662771aa2d0579465ae6ff
S: 478491a5f75d8fbceeaa7a61bbc4866b5893b99c 192.168.223.111:7005
   slots: (0 slots) slave
   replicates 15e768a013d6042de80b82aa2274ffcf30381085
M: 9a347d87b115ab8be8662771aa2d0579465ae6ff 192.168.223.111:7002
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

查看集群信息

$ redis-cli -c -h 192.168.223.111 -p 7001
192.168.223.111: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_ping_sent:371
cluster_stats_messages_pong_sent:382
cluster_stats_messages_sent:753
cluster_stats_messages_ping_received:377
cluster_stats_messages_pong_received:371
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:753
192.168.223.111:7001> 

查看節點信息

$ redis-cli -c -h 192.168.223.111 -p 7001
192.168.223.111:7001> cluster nodes
ec514db1730a466cf10d3ee54f32003c7690602a 192.168.223.111:7006@17006 slave b3919787aa7bc4123e5f87b8995680e2187bf4cc 0 1575617014596 6 connected
15e768a013d6042de80b82aa2274ffcf30381085 192.168.223.111:7003@17003 master - 0 1575617015504 3 connected 10923-16383
70b40a69c2ee564cf1e1ff59f26b1a754443509e 192.168.223.111:7004@17004 slave 9a347d87b115ab8be8662771aa2d0579465ae6ff 0 1575617014496 4 connected
478491a5f75d8fbceeaa7a61bbc4866b5893b99c 192.168.223.111:7005@17005 slave 15e768a013d6042de80b82aa2274ffcf30381085 0 1575617014000 5 connected
b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001@17001 myself,master - 0 1575617013000 1 connected 0-5460
9a347d87b115ab8be8662771aa2d0579465ae6ff 192.168.223.111:7002@17002 master - 0 1575617015000 2 connected 5461-10922
192.168.223.111:7001> 

或者

$ redis-cli --cluster check 192.168.223.111:7001
192.168.223.111:7001 (b3919787...) -> 1 keys | 5461 slots | 1 slaves.
192.168.223.111:7003 (15e768a0...) -> 0 keys | 5461 slots | 1 slaves.
192.168.223.111:7002 (9a347d87...) -> 1 keys | 5462 slots | 1 slaves.
[OK] 2 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 192.168.223.111:7001)
M: b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: ec514db1730a466cf10d3ee54f32003c7690602a 192.168.223.111:7006
   slots: (0 slots) slave
   replicates b3919787aa7bc4123e5f87b8995680e2187bf4cc
M: 15e768a013d6042de80b82aa2274ffcf30381085 192.168.223.111:7003
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 70b40a69c2ee564cf1e1ff59f26b1a754443509e 192.168.223.111:7004
   slots: (0 slots) slave
   replicates 9a347d87b115ab8be8662771aa2d0579465ae6ff
S: 478491a5f75d8fbceeaa7a61bbc4866b5893b99c 192.168.223.111:7005
   slots: (0 slots) slave
   replicates 15e768a013d6042de80b82aa2274ffcf30381085
M: 9a347d87b115ab8be8662771aa2d0579465ae6ff 192.168.223.111:7002
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

集群測試

[root@k8s1 ~]# redis-cli -c -h 192.168.223.111 -p 7001
192.168.223.111:7001> set name test
-> Redirected to slot [5798] located at 192.168.223.111:7002
OK
192.168.223.111:7002> set age 18
-> Redirected to slot [741] located at 192.168.223.111:7001
OK
192.168.223.111:7001> get name
-> Redirected to slot [5798] located at 192.168.223.111:7002
"test"
192.168.223.111:7002> get age
-> Redirected to slot [741] located at 192.168.223.111:7001
"18"
192.168.223.111:7001> 

可以看到,客戶端連接加 -c 選項的時候,存儲和提取 key 的時候不斷在 7001 和 7002 之間跳轉,這個稱為客戶端重定向。之所以發生客戶端重定向,是因為
Redis Cluster在設計的時候,就考慮到了去中心化,去中間件,也就是說,集群中的每個節點都是平等的關系,都是對等的,每個節點都保存各自的數據和整個集群的狀態。每個節點都和其他所有節點連接,而且這些連接保持活躍,這樣就保證了只需要連接集群中的任意一個節點,就可以獲取到其他節點的數據。Redis 集群沒有並使用傳統的一致性哈希來分配數據,而是采用另外一種叫做哈希槽(hash slot)的方式來分配的。Redis Cluster 默認分配了 16384 個 slot,當 set 一個 key 時,會用 CRC16 算法來取模得到所屬的 slot,然后將這個 key 分到哈希槽區間的節點上,具體算法就是:CRC16(key) % 16384。所以在測試的時候看到set 和 get 的時候,會跳轉節點。Redis 集群會把數據存在一個 Master 節點,然后在這個 Master 節點和其對應的 Salve 節點之間進行數據同步。當讀取數據時,也根據一致性哈希算法到對應的 master 節點獲取數據。只有當一個 Master 節點掛掉之后,才會啟動一個對應的 Salve 節點,充當 Master 節點。

擴充:客戶端默認只能從 Master 節點上獲取數據,不能從 Slave 節點獲取;如果需要直接從 Slave 節點獲取數據,客戶端可以設置為 readonly 模式,具體參考官方文檔。

集群故障切換測試

首先查看當前主節點信息:

$ redis-cli -p 7001 cluster nodes | grep master 
15e768a013d6042de80b82aa2274ffcf30381085 192.168.223.111:7003@17003 master - 0 1575618684601 3 connected 10923-16383
70b40a69c2ee564cf1e1ff59f26b1a754443509e 192.168.223.111:7004@17004 master - 0 1575618685000 7 connected 5461-10922
b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001@17001 myself,master - 0 1575618685000 1 connected 0-5460

模擬崩潰主節點 7003:

$ redis-cli -p 7003 debug segfault
Error: Server closed the connection

debug segfault 命令執行一個非法的內存訪問從而讓 Redis 崩潰,僅在開發時用於 bug 調試。

再次查看當前主節點信息:

$ redis-cli -p 7001 cluster nodes | grep master 
15e768a013d6042de80b82aa2274ffcf30381085 192.168.223.111:7003@17003 master,fail - 1575618827980 1575618827074 3 disconnected
70b40a69c2ee564cf1e1ff59f26b1a754443509e 192.168.223.111:7004@17004 master - 0 1575618873502 7 connected 5461-10922
478491a5f75d8fbceeaa7a61bbc4866b5893b99c 192.168.223.111:7005@17005 master - 0 1575618875000 9 connected 10923-16383
b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001@17001 myself,master - 0 1575618873000 1 connected 0-5460

可以看到 7003 已是 fail 狀態,並且 7005 已經成為新的 Master 節點

重新啟動 7003:

$ redis-server /etc/redis-cluster/redis-7003.conf  
81882:C 06 Dec 2019 15:57:17.086 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
81882:C 06 Dec 2019 15:57:17.086 # Redis version=5.0.7, bits=64, commit=00000000, modified=0, pid=81882, just started
81882:C 06 Dec 2019 15:57:17.086 # Configuration loaded

$ redis-cli -p 7001 cluster nodes
ec514db1730a466cf10d3ee54f32003c7690602a 192.168.223.111:7006@17006 slave b3919787aa7bc4123e5f87b8995680e2187bf4cc 0 1575619045171 6 connected
15e768a013d6042de80b82aa2274ffcf30381085 192.168.223.111:7003@17003 slave 478491a5f75d8fbceeaa7a61bbc4866b5893b99c 0 1575619044666 9 connected
70b40a69c2ee564cf1e1ff59f26b1a754443509e 192.168.223.111:7004@17004 master - 0 1575619044000 7 connected 5461-10922
478491a5f75d8fbceeaa7a61bbc4866b5893b99c 192.168.223.111:7005@17005 master - 0 1575619045000 9 connected 10923-16383
b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001@17001 myself,master - 0 1575619045000 1 connected 0-5460
9a347d87b115ab8be8662771aa2d0579465ae6ff 192.168.223.111:7002@17002 slave 70b40a69c2ee564cf1e1ff59f26b1a754443509e 0 1575619044565 7 connected

可以看到重新啟動的 7003 已經成為 7005 的 Slave 節點

注意: 當存活的 Master 節點小於總節點數的一半時,整個集群就無法提供服務了。

添加節點

兩種情況,添加一個 Master 節點或者 Slave 節點。

添加 Master 節點

redis-cli --cluster add-node 192.168.223.111:7007 192.168.223.111:7001
  • 第一個參數(192.168.223.111:7007) 為新加入的節點,具體配置參照前面部分。
  • 第二個參數(192.168.223.111:7001)為集群中任一正常節點。
$ redis-cli -p 7001 cluster nodes
ec514db1730a466cf10d3ee54f32003c7690602a 192.168.223.111:7006@17006 slave b3919787aa7bc4123e5f87b8995680e2187bf4cc 0 1575619906900 6 connected
15e768a013d6042de80b82aa2274ffcf30381085 192.168.223.111:7003@17003 slave 478491a5f75d8fbceeaa7a61bbc4866b5893b99c 0 1575619907405 9 connected
70b40a69c2ee564cf1e1ff59f26b1a754443509e 192.168.223.111:7004@17004 master - 0 1575619906601 7 connected 5461-10922
0be08034ff73657bb525158821ab0210894af917 192.168.223.111:7007@17007 master - 0 1575619906000 0 connected
478491a5f75d8fbceeaa7a61bbc4866b5893b99c 192.168.223.111:7005@17005 master - 0 1575619907908 9 connected 10923-16383
b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001@17001 myself,master - 0 1575619907000 1 connected 0-5460
9a347d87b115ab8be8662771aa2d0579465ae6ff 192.168.223.111:7002@17002 slave 70b40a69c2ee564cf1e1ff59f26b1a754443509e 0 1575619906000 7 connected

可以看到已經成功的向集群中添加了 Master 節點 7007,但是這個 Master 節點還沒有成為真正的 Master 節點,因為還沒有分配槽(slot),也沒有從節點,現在要給它分配槽(slot)。

[root@k8s1 ~]# redis-cli --cluster reshard 192.168.223.111:7001
>>> Performing Cluster Check (using node 192.168.223.111:7001)
M: b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: ec514db1730a466cf10d3ee54f32003c7690602a 192.168.223.111:7006
   slots: (0 slots) slave
   replicates b3919787aa7bc4123e5f87b8995680e2187bf4cc
S: 15e768a013d6042de80b82aa2274ffcf30381085 192.168.223.111:7003
   slots: (0 slots) slave
   replicates 478491a5f75d8fbceeaa7a61bbc4866b5893b99c
M: 70b40a69c2ee564cf1e1ff59f26b1a754443509e 192.168.223.111:7004
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
M: 0be08034ff73657bb525158821ab0210894af917 192.168.223.111:7007
   slots: (0 slots) master
M: 478491a5f75d8fbceeaa7a61bbc4866b5893b99c 192.168.223.111:7005
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 9a347d87b115ab8be8662771aa2d0579465ae6ff 192.168.223.111:7002
   slots: (0 slots) slave
   replicates 70b40a69c2ee564cf1e1ff59f26b1a754443509e
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
How many slots do you want to move (from 1 to 16384)? 2048   # 指定分配多少個槽
What is the receiving node ID? 0be08034ff73657bb525158821ab0210894af917		# 分配到哪個節點(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: all		# 選擇 all

Ready to move 2048 slots.
  Source nodes:
    M: b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001
       slots:[0-5460] (5461 slots) master
       1 additional replica(s)
    M: 70b40a69c2ee564cf1e1ff59f26b1a754443509e 192.168.223.111:7004
       slots:[5461-10922] (5462 slots) master
       1 additional replica(s)
    M: 478491a5f75d8fbceeaa7a61bbc4866b5893b99c 192.168.223.111:7005
       slots:[10923-16383] (5461 slots) master
       1 additional replica(s)
  Destination node:
    M: 0be08034ff73657bb525158821ab0210894af917 192.168.223.111:7007
       slots: (0 slots) master
  Resharding plan:
    Moving slot 5461 from 70b40a69c2ee564cf1e1ff59f26b1a754443509e
...
...
...
Moving slot 11604 from 192.168.223.111:7005 to 192.168.223.111:7007: 

$ redis-cli --cluster check 192.168.223.111:7001
192.168.223.111:7001 (b3919787...) -> 1 keys | 4779 slots | 1 slaves.
192.168.223.111:7004 (70b40a69...) -> 0 keys | 4779 slots | 1 slaves.
192.168.223.111:7007 (0be08034...) -> 1 keys | 2047 slots | 0 slaves.
192.168.223.111:7005 (478491a5...) -> 0 keys | 4779 slots | 1 slaves.
[OK] 2 keys in 4 masters.
...
...
...
[OK] All 16384 slots covered.

可以看到新的 Master 節點 7007 已經獲取到了新分配的槽,並且其目前還沒有 Slave 節點。

添加 Slave 節點

redis-cli --cluster add-node 192.168.223.111:7008 192.168.223.111:7001 --cluster-slave --cluster-master-id 0be08034ff73657bb525158821ab0210894af917
  • 如果不指定 --cluster-master-id 參數, Redis Cluster 會將新加入的 Slave 節點隨機分配給一個 Master 節點,這里指定 Master 節點 7007。
$ redis-cli -p 7001 cluster nodes
ec514db1730a466cf10d3ee54f32003c7690602a 192.168.223.111:7006@17006 slave b3919787aa7bc4123e5f87b8995680e2187bf4cc 0 1575621163000 6 connected
15e768a013d6042de80b82aa2274ffcf30381085 192.168.223.111:7003@17003 slave 478491a5f75d8fbceeaa7a61bbc4866b5893b99c 0 1575621163562 9 connected
70b40a69c2ee564cf1e1ff59f26b1a754443509e 192.168.223.111:7004@17004 master - 0 1575621164067 7 connected 6144-10922
0be08034ff73657bb525158821ab0210894af917 192.168.223.111:7007@17007 master - 0 1575621163057 10 connected 0-681 5461-6143 10923-11604
478491a5f75d8fbceeaa7a61bbc4866b5893b99c 192.168.223.111:7005@17005 master - 0 1575621164572 9 connected 11605-16383
b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001@17001 myself,master - 0 1575621162000 1 connected 682-5460
629a4e7bafac9522b974b0a12f7cd28d7be51cfd 192.168.223.111:7008@17008 slave 0be08034ff73657bb525158821ab0210894af917 0 1575621165077 10 connected
9a347d87b115ab8be8662771aa2d0579465ae6ff 192.168.223.111:7002@17002 slave 70b40a69c2ee564cf1e1ff59f26b1a754443509e 0 1575621163000 7 connected

可以看到 7008 已經成為 7007 的 Slave 節點。

平衡各節點槽數量

當前新加 Master 節點后各節點的槽可能會分配不均勻。

$ redis-cli --cluster info 192.168.223.111:7001
192.168.223.111:7001 (b3919787...) -> 1 keys | 4779 slots | 1 slaves.
192.168.223.111:7004 (70b40a69...) -> 0 keys | 4779 slots | 1 slaves.
192.168.223.111:7007 (0be08034...) -> 1 keys | 2047 slots | 1 slaves.
192.168.223.111:7005 (478491a5...) -> 0 keys | 4779 slots | 1 slaves.
[OK] 2 keys in 4 masters.
0.00 keys per slot on average.

可以重新分配

$ redis-cli --cluster rebalance --cluster-threshold 1 192.168.223.111:7001
>>> Performing Cluster Check (using node 192.168.223.111:7001)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Rebalancing across 4 nodes. Total weight = 4.00
...
...
...

$ redis-cli --cluster info 192.168.223.111:7001
192.168.223.111:7001 (b3919787...) -> 0 keys | 4096 slots | 1 slaves.
192.168.223.111:7004 (70b40a69...) -> 0 keys | 4096 slots | 1 slaves.
192.168.223.111:7007 (0be08034...) -> 2 keys | 4096 slots | 1 slaves.
192.168.223.111:7005 (478491a5...) -> 0 keys | 4096 slots | 1 slaves.
[OK] 2 keys in 4 masters.
0.00 keys per slot on average.

可以看到已重新分配。

Slave 節點重新分配

首先查看集群信息

$ redis-cli -p 7001 cluster nodes
ec514db1730a466cf10d3ee54f32003c7690602a 192.168.223.111:7006@17006 slave b3919787aa7bc4123e5f87b8995680e2187bf4cc 0 1575622162000 6 connected
15e768a013d6042de80b82aa2274ffcf30381085 192.168.223.111:7003@17003 slave 478491a5f75d8fbceeaa7a61bbc4866b5893b99c 0 1575622162506 9 connected
70b40a69c2ee564cf1e1ff59f26b1a754443509e 192.168.223.111:7004@17004 master - 0 1575622162000 7 connected 6827-10922
0be08034ff73657bb525158821ab0210894af917 192.168.223.111:7007@17007 master - 0 1575622162706 10 connected 0-1364 5461-6826 10923-12287
478491a5f75d8fbceeaa7a61bbc4866b5893b99c 192.168.223.111:7005@17005 master - 0 1575622162000 9 connected 12288-16383
b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001@17001 myself,master - 0 1575622161000 1 connected 1365-5460
629a4e7bafac9522b974b0a12f7cd28d7be51cfd 192.168.223.111:7008@17008 slave 0be08034ff73657bb525158821ab0210894af917 0 1575622161000 10 connected
9a347d87b115ab8be8662771aa2d0579465ae6ff 192.168.223.111:7002@17002 slave 70b40a69c2ee564cf1e1ff59f26b1a754443509e 0 1575622162202 7 connected
[root@k8s1 ~]# 
[root@k8s1 ~]# 

可以看到當前 7002 是 7004 的 Slave 節點,如果想把 7002 變成 7001 的 Slave 節點,則首先登陸 7002 節點執行以下操作:

$ redis-cli -c -h 192.168.223.111 -p 7002
192.168.223.111:7002> cluster replicate b3919787aa7bc4123e5f87b8995680e2187bf4cc
OK
192.168.223.111:7002> exit

$ redis-cli -p 7001 cluster nodes        
ec514db1730a466cf10d3ee54f32003c7690602a 192.168.223.111:7006@17006 slave b3919787aa7bc4123e5f87b8995680e2187bf4cc 0 1575622409000 6 connected
15e768a013d6042de80b82aa2274ffcf30381085 192.168.223.111:7003@17003 slave 478491a5f75d8fbceeaa7a61bbc4866b5893b99c 0 1575622410891 9 connected
70b40a69c2ee564cf1e1ff59f26b1a754443509e 192.168.223.111:7004@17004 master - 0 1575622410588 7 connected 6827-10922
0be08034ff73657bb525158821ab0210894af917 192.168.223.111:7007@17007 master - 0 1575622409881 10 connected 0-1364 5461-6826 10923-12287
478491a5f75d8fbceeaa7a61bbc4866b5893b99c 192.168.223.111:7005@17005 master - 0 1575622410083 9 connected 12288-16383
b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001@17001 myself,master - 0 1575622410000 1 connected 1365-5460
629a4e7bafac9522b974b0a12f7cd28d7be51cfd 192.168.223.111:7008@17008 slave 0be08034ff73657bb525158821ab0210894af917 0 1575622409000 10 connected
9a347d87b115ab8be8662771aa2d0579465ae6ff 192.168.223.111:7002@17002 slave b3919787aa7bc4123e5f87b8995680e2187bf4cc 0 1575622410000 7 connected
[root@k8s1 ~]# 
  • b3919787aa7bc4123e5f87b8995680e2187bf4cc 為 7001 的 ID。
  • 可以看到 7002 已經變成 7001 的 Slave 節點。

刪除節點

分兩種情況:刪除 Master 節點和 Slave 節點。

刪除 Slave 節點

比較簡單

$ redis-cli  --cluster del-node 192.168.223.111:7001 629a4e7bafac9522b974b0a12f7cd28d7be51cfd
>>> Removing node 629a4e7bafac9522b974b0a12f7cd28d7be51cfd from cluster 192.168.223.111:7001
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.
  • 629a4e7bafac9522b974b0a12f7cd28d7be51cfd 為 Slave 節點 7008 的 ID。
$ redis-cli -p 7001 cluster nodes
ec514db1730a466cf10d3ee54f32003c7690602a 192.168.223.111:7006@17006 slave b3919787aa7bc4123e5f87b8995680e2187bf4cc 0 1575622972929 6 connected
15e768a013d6042de80b82aa2274ffcf30381085 192.168.223.111:7003@17003 slave 478491a5f75d8fbceeaa7a61bbc4866b5893b99c 0 1575622972000 9 connected
70b40a69c2ee564cf1e1ff59f26b1a754443509e 192.168.223.111:7004@17004 master - 0 1575622972525 7 connected 6827-10922
0be08034ff73657bb525158821ab0210894af917 192.168.223.111:7007@17007 master - 0 1575622971515 10 connected 0-1364 5461-6826 10923-12287
478491a5f75d8fbceeaa7a61bbc4866b5893b99c 192.168.223.111:7005@17005 master - 0 1575622971000 9 connected 12288-16383
b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001@17001 myself,master - 0 1575622972000 1 connected 1365-5460
9a347d87b115ab8be8662771aa2d0579465ae6ff 192.168.223.111:7002@17002 slave 70b40a69c2ee564cf1e1ff59f26b1a754443509e 0 1575622973030 7 connected

可以看出 7008 已被刪除。

刪除 Master 節點

刪除 Master 節點相對來說就是復雜一點,主要步驟:

  1. 如果 Master 節點有 Slave 節點,則首先要將 Slave 節點重新分配到其他 Master 節點或者刪除。
  2. 如果 Master 節點有槽(slot),則需要去掉分配的槽(slot),然后再刪除主節點

Slave 節點重新分配與刪除 Slave 參考前面部分,這里主要講下怎么去掉分配的槽(slot),已 7007 節點為例:

$ redis-cli --cluster info 192.168.223.111:7001
192.168.223.111:7001 (b3919787...) -> 0 keys | 4096 slots | 1 slaves.
192.168.223.111:7004 (70b40a69...) -> 0 keys | 4096 slots | 1 slaves.
192.168.223.111:7007 (0be08034...) -> 2 keys | 4096 slots | 0 slaves.
192.168.223.111:7005 (478491a5...) -> 0 keys | 4096 slots | 1 slaves.
[OK] 2 keys in 4 masters.
0.00 keys per slot on average.
  • 7007 有槽
$ redis-cli --cluster reshard 192.168.223.111:7001
>>> Performing Cluster Check (using node 192.168.223.111:7001)
M: b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001
   slots:[1365-5460] (4096 slots) master
   1 additional replica(s)
S: ec514db1730a466cf10d3ee54f32003c7690602a 192.168.223.111:7006
   slots: (0 slots) slave
   replicates b3919787aa7bc4123e5f87b8995680e2187bf4cc
S: 15e768a013d6042de80b82aa2274ffcf30381085 192.168.223.111:7003
   slots: (0 slots) slave
   replicates 478491a5f75d8fbceeaa7a61bbc4866b5893b99c
M: 70b40a69c2ee564cf1e1ff59f26b1a754443509e 192.168.223.111:7004
   slots:[6827-10922] (4096 slots) master
   1 additional replica(s)
M: 0be08034ff73657bb525158821ab0210894af917 192.168.223.111:7007
   slots:[0-1364],[5461-6826],[10923-12287] (4096 slots) master
M: 478491a5f75d8fbceeaa7a61bbc4866b5893b99c 192.168.223.111:7005
   slots:[12288-16383] (4096 slots) master
   1 additional replica(s)
S: 9a347d87b115ab8be8662771aa2d0579465ae6ff 192.168.223.111:7002
   slots: (0 slots) slave
   replicates 70b40a69c2ee564cf1e1ff59f26b1a754443509e
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
How many slots do you want to move (from 1 to 16384)? 4096	# 7007 的槽個數
What is the receiving node ID? b3919787aa7bc4123e5f87b8995680e2187bf4cc		# 由誰來接手 7007 的槽
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: 0be08034ff73657bb525158821ab0210894af917	# 7007 節點 ID
Source node #2: done

Ready to move 4096 slots.
  Source nodes:
    M: 0be08034ff73657bb525158821ab0210894af917 192.168.223.111:7007
       slots:[0-1364],[5461-6826],[10923-12287] (4096 slots) master
  Destination node:
    M: b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001
       slots:[1365-5460] (4096 slots) master
       1 additional replica(s)
  Resharding plan:
    Moving slot 0 from 0be08034ff73657bb525158821ab0210894af917
    ...
    ...
    ...

$ redis-cli --cluster info 192.168.223.111:7001   
192.168.223.111:7001 (b3919787...) -> 2 keys | 8192 slots | 1 slaves.
192.168.223.111:7004 (70b40a69...) -> 0 keys | 4096 slots | 1 slaves.
192.168.223.111:7007 (0be08034...) -> 0 keys | 0 slots | 0 slaves.
192.168.223.111:7005 (478491a5...) -> 0 keys | 4096 slots | 1 slaves.
[OK] 2 keys in 4 masters.
0.00 keys per slot on average.

可以看到 7007 的槽個數已經為 0。執行刪除:

$ redis-cli  --cluster del-node 192.168.223.111:7001 0be08034ff73657bb525158821ab0210894af917
>>> Removing node 0be08034ff73657bb525158821ab0210894af917 from cluster 192.168.223.111:7001
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.

$ redis-cli -p 7001 cluster nodes
ec514db1730a466cf10d3ee54f32003c7690602a 192.168.223.111:7006@17006 slave b3919787aa7bc4123e5f87b8995680e2187bf4cc 0 1575623784000 11 connected
15e768a013d6042de80b82aa2274ffcf30381085 192.168.223.111:7003@17003 slave 478491a5f75d8fbceeaa7a61bbc4866b5893b99c 0 1575623785208 9 connected
70b40a69c2ee564cf1e1ff59f26b1a754443509e 192.168.223.111:7004@17004 master - 0 1575623784000 7 connected 6827-10922
478491a5f75d8fbceeaa7a61bbc4866b5893b99c 192.168.223.111:7005@17005 master - 0 1575623784703 9 connected 12288-16383
b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001@17001 myself,master - 0 1575623784000 11 connected 0-6826 10923-12287
9a347d87b115ab8be8662771aa2d0579465ae6ff 192.168.223.111:7002@17002 slave 70b40a69c2ee564cf1e1ff59f26b1a754443509e 0 1575623784198 7 connected

可以看到已刪除 7007 節點。

集群升級

分兩種情況:升級 Master 節點和 Slave 節點。

升級 Slave 節點

升級 Slave 節點比較簡單,只需要停止 Slave 節點,然后升級 Redis 程序,最后重啟即可。

升級 Master 節點

升級 Master 節點相對來說復雜一點,主要步驟:

  1. 使用 debug segfault 使 Master 節點發生故障轉換為 Slave 節點(參考前面部分)。
  2. 然后再照升級 Slave 節點的方法升級此節點。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM