Redis資料型別, Redis主從哨兵和叢集(將資料匯入叢集) ubuntu使用

战斗小人發表於2024-10-05

2.5 Redis 常用命令

2.5.1 INFO

顯示當前節點redis執行狀態資訊(可以做監控用)

#列出所有
127.0.0.1:6379> info
#列出具體塊
127.0.0.1:6379> info Memory

2.5.3 SELECT

切換資料庫,相當於在MySQL的 USE DBNAME 指令

注意: 在Redis cluster 模式下不支援多個資料庫,會出現下面錯誤

127.0.0.1:6379> info cluster
# Cluster
cluster_enabled:1
127.0.0.1:6379> select 0
OK
127.0.0.1:6379> select 1
(error) ERR SELECT is not allowed in cluster mode

2.5.4 KEYS

檢視當前庫下的所有key,此命令慎用! (生產中不要執行keys帶*的操作,造成redis阻塞)

127.0.0.1:6379> KEYS *
#萬用字元查詢,效能很差
redis> KEYS *o*

2.5.5 BGSAVE

手動在後臺執行RDB持久化操作

2.5.6 DBSIZE

返回當前庫下的所有key 數量

127.0.0.1:6379> DBSIZE
(integer) 4
127.0.0.1:6379> SELECT 1
OK
127.0.0.1:6379[1]> DBSIZE
(integer) 0

2.5.7 FLUSHDB

強制清空當前庫中的所有key,此命令慎用!

127.0.0.1:6379[1]> SELECT 0
OK
127.0.0.1:6379> DBSIZE
(integer) 4
127.0.0.1:6379> FLUSHDB
OK
127.0.0.1:6379> DBSIZE
(integer) 0

2.5.8 FLUSHALL

強制清空當前Redis伺服器所有資料庫中的所有key,即刪除所有資料,此命令慎用!

127.0.0.1:6379> FLUSHALL
OK

#生產建議修改配置使用rename-command禁用此命令
vim /etc/redis.conf
rename-command FLUSHALL ""   #flushdb和和AOF功能衝突,需要設定 appendonly no,不區分命令大小寫,但和flushall (v7.2.3不衝突)

2.5.9 SHUTDOWN

關閉redis

#命令過於危險
#也可以禁用掉該命令
vim /etc/redis.conf
rename-command SHUTDOWN ""
[root@ubuntu ~]#systemctl restart redis

2.6 Redis 資料型別

2.6.1 字串 string

2.6.2 列表 list

2.6.3 集合 set

2.6.4 有序集合 sorted set

2.6.5 雜湊 hash

2.7 訊息佇列

2.7.1 生產者消費者模式

2.7.2 釋出者訂閱模式

3 Redis 叢集與高可用

3.1 Redis 主從複製

主從複製特點

一個master可以有多個slave
一個slave只能有一個master
資料流向是從master到slave單向的
master 可讀可寫
slave 只讀

3.1.2.1 主從命令配置

#主節點不用配,預設是主,從節點配置下方2條命令
127.0.0.1:6379> REPLICAOF MASTER_IP PORT #新版推薦使用
127.0.0.1:6379> SLAVEOF MasterIP Port   #舊版使用,將被淘汰
127.0.0.1:6379> CONFIG SET masterauth <masterpass>    #從節點配上主節點的密碼

#上面的命令是動態生效,用永久生效,寫到配置檔案中
#redis透過 info replication 或者 role 命令可以檢視自己是否是主節點

例項:
主節點: 10.0.0.200

從節點: 10.0.0.201
#操作
127.0.0.1:6379> replicaof 10.0.0.200 6379
127.0.0.1:6379> config set masterauth 123456    #主節點密碼(這裡最好主從密碼一致)
#此時等待同步,透過 info replication檢視
#master_sync_in_progress:0為0表示同步完成,master_link_status:up為up表示連線成功
#主節點 info replication檢視,slave會顯示從節點資訊

#修改配置檔案,保證從節點配置永久儲存
[root@slave1 ~]#vim /apps/redis/etc/redis.conf
replicaof 10.0.0.200 6379
masterauth 123456    #主節點最好把這一行配上,萬一哪天它變從節點,可以用

#主從同步已經完成

主節點重啟,出發全量複製。從節點重啟,出發增量恢復(排除第一次)

3.1.2.1.2 刪除主從同步

在從節點執行 REPLICAOF NO ONE 或 SLAVEOF NO ONE 指令可以取消主從複製
取消複製 會斷開和master的連線而不再有主從複製關聯, 但不會清除slave上已有的資料

#新版
127.0.0.1:6379> REPLICAOF NO ONE
#舊版
127.0.0.1:6379> SLAVEOF NO ONE

如果主庫崩了,選info中 slave_read_repl_offset和slave_repl_offset值最大的(說明資料最新) 作為新主庫

3.1.5 主從複製最佳化

Redis主從複製分為全量同步和增量同步
Redis 的主從同步是非阻塞的,即同步過程不會影響主伺服器的正常訪問.
注意:主節點重啟會導致全量同步,從節點重啟只會導致增量同步
#本質上是根據runId判斷的,主節點重啟runId變化,那從節點就全量同步過去。(主節點一定要有持久化,否則重啟,資料清空,從節點會全量同步)

從redis 2.8版本以前,並不支援部分同步,當主從伺服器之間的連線斷掉之後,master伺服器和slave伺服器之間都是進行全量資料同步
從redis 2.8開始,開始引入了部分同步,即使主從連線中途斷掉,也不需要進行全量同步

3.1.5.2 主從同步最佳化配置

Redis在2.8版本之前沒有提供增量部分複製的功能,當網路閃斷或者slave Redis重啟之後會導致主從之 間的全量同步,

即從2.8版本開始增加了部分複製的功能。

效能相關配置

repl-diskless-sync no # 是否使用無盤方式進行同步RDB檔案,預設為no(編譯安裝預設為yes),no表示不使用無盤,
需要將RDB檔案儲存到磁碟後再傳送給slave,yes表示使用無盤,即RDB檔案不需要儲存至本地磁碟,而且直接透過網路傳送給slave(無盤存在記憶體中效率高,
但不太穩定)
repl-diskless-sync-delay 5 #無盤時複製的伺服器等待的延遲時間(多長時間複製一次) repl-ping-slave-period 10 #slave向master傳送ping指令的時間間隔,預設為10s repl-timeout 60 #指定ping連線超時時間,超過此值無法連線,master_link_status顯示為down狀態,並記錄錯誤日誌 repl-disable-tcp-nodelay no #是否啟用TCP_NODELAY #設定成yes,則redis會合並多個小的TCP包成一個大包再傳送,此方式可以節省頻寬,但會造成同步延遲時長的增加,導致master與slave資料短期內不一致 #設定成no,則master會立即同步資料 repl-backlog-size 1mb #master的寫入資料緩衝區,用於記錄自上一次同步後到下一次同步前期間的寫入命令,
計算公式:repl-backlog-size = 允許slave最大中斷時長 * master節點offset每秒寫入量,如:master每秒最大寫入量為32MB,最長允許中斷60秒,
就要至少設定為32*60=1920MB,建議此值是設定的足夠大,如果此值太小,會造成全量複製
repl-backlog-ttl 3600 #指定多長時間後如果沒有slave連線到master,則backlog的記憶體資料將會過期。如果值為0表示永遠不過期。 slave-priority 100 #slave參與選舉新的master的優先順序,此整數值越小則優先順序越高。當master故障時將會按照優先順序來選擇slave端進行選舉新的master,
如果值設定為0,則表示該slave節點永遠不會被選為master節點。
min-replicas-to-write 1 #指定master的可用slave不能少於個數,如果少於此值,master將無法執行寫操作,預設為0,生產建議設為1, min-slaves-max-lag 20 #指定至少有min-replicas-to-write數量的slave延遲時間都大於此秒數時,master將不能執行寫操作,預設為10s

3.1.5.1.5 避免複製風暴

單主節點複製風暴
當主節點重啟,多從節點複製
解決方法:更換複製拓撲

單機器多例項複製風暴
機器當機後,大量全量複製
解決方法:主節點分散多機器

3.1.6 常見主從複製故障

3.1.6.1 主從硬體和軟體配置不一致

主從節點的maxmemory不一致,主節點記憶體大於從節點記憶體,主從複製可能丟失資料 
rename-command 命令不一致,如在主節點啟用flushdb,從節點禁用此命令,結果在master節點執行 flushdb後,導致slave節點不同步 

3.1.6.2 Master 節點密碼錯誤

3.1.6.3 Redis 版本不一致

3.2 Redis 哨兵 Sentinel

配合redis高可用,解決當master出現故障時, 自動的將一個slave 節點提升為新的master節點

3.2.2.1 Sentinel 架構和故障轉移機制

sentinel可以監控多組主從複製

Sentinel 架構

Sentinel 故障轉移

3.2.2.2 Sentinel中的三個定時任務

1.每10 秒每個sentinel 對master和slave執行info
發現slave節點
確認主從關係
2.每2秒每個sentinel透過master節點的channel交換資訊(pub/sub)
透過sentinel__:hello頻道互動
互動對節點的“看法”和自身資訊
3.每1秒每個sentinel對其他sentinel和redis執行ping

3.2.3 實現哨兵架構

生產中為了節約成本,會把sentinel裝在redis節點伺服器上(這裡三胎redis節點,每個節點裝一個sentinel)。

sentinel相當於特殊版本的redis(26379埠),在安裝redis時,sentinel已經有了

3.2.3.2 編輯哨兵配置

#如果是編譯安裝,在原始碼目錄有sentinel.conf,複製到安裝目錄即可,
如:/apps/redis/etc/sentinel.conf
[root@ubuntu2204 ~]#cp redis-7.0.5/sentinel.conf /apps/redis/etc/sentinel.conf
[root@centos8 ~]#cp redis-6.2.5/sentinel.conf /apps/redis/etc/sentinel.conf
#保證配置檔案許可權,這裡直接把目錄許可權一起修改了
[root@ubuntu2204 ~]#chown -R redis.redis /apps/redis
#[root@ubuntu2204 ~]#chown redis.redis /apps/redis/etc/sentinel.conf 

#包安裝修改配置檔案(寫完把配置檔案複製到兩外兩臺節點上)
[root@centos8 ~]#vim /apps/redis/etc/sentinel.conf
bind 0.0.0.0
port 26379
daemonize yes
pidfile "redis-sentinel.pid"    #可改為/apps/redis/run/redis-sentinel.pid
logfile "sentinel_26379.log"    #可改為/apps/redis/log/redis-sentinel.log
dir "/tmp"  #工作目錄

sentinel monitor mymaster 10.0.0.200 6379 2        #有多個叢集,這裡就配多個
#mymaster是叢集的名稱(隨意取名,要唯一),此行指定當前mymaster叢集中master伺服器的地址和埠
#2為法定人數限制(quorum),即有幾個sentinel認為master down了就進行故障轉移,一般此值是所有sentinel節點(一般總數是>=3的 奇數,如:3,5,7等)的一半以上的整數值,
比如,總數是3,即3/2=1.5,取整為2,是master的ODOWN客觀下線的依據
sentinel auth-pass mymaster 123456 #有多個叢集,這裡就配多個 #mymaster叢集中master的密碼,注意此行要在上面行的下面,注意:要求這組redis主從複製所有節點的密碼是一樣的 sentinel down-after-milliseconds mymaster 3000 #判斷mymaster叢集中所有節點的主觀下線(SDOWN)的時間,單位:毫秒,建議3000 #sentinel parallel-syncs mymaster 1 #發生故障轉移後,可以同時向新master同步資料的slave的數量,數字越小總同步時間越長,但可以減輕新master的負載壓力 #sentinel failover-timeout mymaster 180000 #所有slaves指向新的master所需的超時時間,單位:毫秒 #logfile /var/log/redis/sentinel.log #把配置檔案複製到另外兩臺機器上(注意屬性不要丟) [root@ubuntu2204 ~]#rsync -av /apps/redis/etc/sentinel.conf 10.0.0.202:/apps/redis/etc

如果是編譯安裝,可以在所有節點生成新的service檔案

#另外兩臺機器也複製該配置
[root@redis-master ~]#cat /lib/systemd/system/redis-sentinel.service
[Unit]
Description=Redis Sentinel
After=network.target

[Service]
ExecStart=/apps/redis/bin/redis-sentinel /apps/redis/etc/sentinel.conf --
supervised systemd
ExecStop=/bin/kill -s QUIT $MAINPID
User=redis
Group=redis
RuntimeDirectory=redis
#Mode=0755

[Install]
WantedBy=multi-user.target

#把配置檔案複製到另外兩臺機器上(注意屬性不要丟)
[root@ubuntu2204 ~]#scp /lib/systemd/system/redis-sentinel.service 10.0.0.202:/lib/systemd/system/redis-sentinel.service

#注意所有節點的目錄許可權,否則無法啟動服務
# [root@redis-master ~]#chown -R redis.redis /apps/redis/
[root@redis-master ~]#systemctl daemon-reload
[root@redis-master ~]#systemctl enable --now redis-sentinel.service

#此時3臺機器sentinel都部署完成,可以連線測試
[root@redis-master ~]#redis-cli -p 26379
127.0.0.1:26379> info    #檢視Sentinel,顯示主從狀態
#sentinel.conf已被sentinel追加內容,其中myid是自動生成唯一的,不能複製給其他sentinel(複製得在服務起來之前)
#實在要複製,把追加的刪了,再複製然後重啟

#注意redis主節點redis.conf要追加主庫的密碼,否則異常恢復後變為從節點,sentinel不追加密碼引數導致連線失敗
masterauth 123456

測試

把主節點redis停了,sentinel自動選舉新的主節點,修改所有redis的conf檔案,sentinel.conf追加內容也修改了
如果把原來的redis再次啟動,會變成新主節點的從節點,redis.conf檔案也會被修改

3.2.4 Sentinel 運維

在Sentinel主機手動觸發故障切換

#redis-cli -p 26379
127.0.0.1:26379> sentinel failover <masterName>

範例: 手動故障轉移

#修改優先順序,能讓某一個節點變為主節點(數字越小,優先順序越高)
[root@centos8 ~]#vim /etc/redis.conf
replica-priority 10 #指定優先順序,值越小sentinel會優先將之選為新的master,默為值為100
[root@centos8 ~]#systemctl restart redis

#或者動態修改
[root@centos8 ~]#redis-cli -a 123456
127.0.0.1:6379> CONFIG GET replica-priority
1) "replica-priority"
2) "100"
127.0.0.1:6379> CONFIG SET replica-priority 99
OK

#連線到任意一個Sentinel節點中,進行故障轉移
[root@centos8 ~]#redis-cli -p 26379
127.0.0.1:26379> sentinel failover mymaster  #原主節點自動變成從節點
OK

3.2.5 應用程式連線 Sentinel

程式不直接連線redis主節點,而是連線Sentinel 間接連線主節點

3.2.5.3 Python 連線 Sentinel 哨兵

[root@ubuntu2204 ~]#apt -y install python3-redis
[root@centos8 ~]#yum -y install python3 python3-redis
[root@centos8 ~]#cat sentinel_test.py
#!/usr/bin/python3
import redis
from redis.sentinel import Sentinel
#連線哨兵伺服器(主機名也可以用域名)
sentinel = Sentinel([('10.0.0.8', 26379),
                     ('10.0.0.18', 26379),
                     ('10.0.0.28', 26379)],
                    socket_timeout=0.5)
redis_auth_pass = '123456'
#mymaster 是配置哨兵模式的redis叢集名稱,此為預設值,實際名稱按照個人部署案例來填寫
#獲取主伺服器地址
master = sentinel.discover_master('mymaster')
print(master)
#獲取從伺服器地址
slave = sentinel.discover_slaves('mymaster')
print(slave)
#獲取主伺服器進行寫入
master = sentinel.master_for('mymaster', socket_timeout=0.5, password=redis_auth_pass, db=0)
w_ret = master.set('name', 'wang')
#輸出:True
#獲取從伺服器進行讀取(預設是round-roubin)
slave = sentinel.slave_for('mymaster', socket_timeout=0.5, password=redis_auth_pass, db=0)
r_ret = slave.get('name')
print(r_ret)
#輸出:wang

上面不管是高可用,還是高可用下的哨兵,都有單點寫入效能瓶頸問題。cluster就是解決這一問題

3.3 Redis Cluster

3.3.1 Redis Cluster 介紹

使用哨兵 Sentinel 只能解決Redis高可用問題,實現Redis的自動故障轉移,但仍然無法解決Redis Master 單節點的效能瓶頸問題
為了解決單機效能的瓶頸,提高Redis 服務整體效能,可以使用分散式叢集的解決方案
早期 Redis 分散式叢集部署方案:
1.客戶端分割槽:由客戶端程式自己實現寫入分配、高可用管理和故障轉移等,對客戶端的開發實現較為複雜
2.代理服務:客戶端不直接連線Redis,而先連線到代理服務,由代理服務實現相應讀寫分配,當前代理服務都是第三方實現.此方案中客戶端實現無需特殊開發,
實現容易,但是代理服務節點仍存有單點故障和效能瓶頸問題。比如:Twitter開源Twemproxy,豌豆莢開發的 codis

3.3.2 Redis Cluster 架構

根據key的名稱進行演算法計算落在不同的主節點上

3.3.2.1 Redis Cluster 架構

缺點:

1.起步6臺機器,成本太高,小公司不需要(小公司可能單機版就夠了)
#實際上最少3個節點可以搭Cluster,全是主節點,沒有從節點(就是沒有資料安全了) (主節點奇數,防止腦裂)
2.不支援多資料庫,只能用0號資料庫,不能select切庫

3.3.2.4 部署方式介紹

redis cluster 有多種部署方法

1.原生命令安裝(太麻煩,不適合)
理解Redis Cluster架構
生產環境不使用
2.官方工具安裝
高效、準確
生產環境可以使用
3.自主研發(大公司自己研發)
可以實現視覺化的自動化部署

3.3.3 實戰案例:基於 Redis 5 以上版本的 Redis Cluster 部署

注意: 如果redis3和4要用redis-trib.rb工具(ruby寫的)

3.3.3.1 建立 Redis Cluster 叢集的環境準備

建立6個單機版redis, 3臺做主, 3臺做從

3.3.3.2 啟用 Redis Cluster 配置

所有6臺主機都執行以下配置

每個節點修改redis配置,必須開啟cluster功能的引數

[root@redis-node1 ~]vim /etc/redis.conf
bind 0.0.0.0
masterauth 123456   #建議配置,否則後期的master和slave主從複製無法成功,還需再配置
requirepass 123456
cluster-enabled yes #取消此行註釋,必須開啟叢集,開啟後查redis程序會有cluster標識(預設0沒開啟)
cluster-config-file nodes-6379.conf #取消此行註釋,此為叢集狀態資料檔案,記錄主從關係及slot範圍資訊,由redis cluster叢集自動建立和維護(在配置dir工作目錄下)
cluster-require-full-coverage no   #預設值為yes,設為no可以防止一個節點不可用導致整個cluster不可用

#或者執行下面命令,批次修改(裡面requirepass沒加)
[root@redis-node1 ~]#sed -i.bak -e 's/bind 127.0.0.1/bind 0.0.0.0/' -e '/masterauth/a masterauth 123456' -e '/# requirepass/a requirepass 123456' -e '/# cluster-enabled yes/a cluster-enabled yes' -e '/# cluster-config-file nodes-6379.conf/a cluster-config-file nodes-6379.conf' -e '/cluster-require-full-coverage yes/a cluster-require-full-coverage no' /etc/redis.con

#如果是編譯安裝可以執行下面操作
[root@redis-node1 ~]#sed -i.bak -e '/masterauth/a masterauth 123456' -e '/# cluster-enabled yes/a cluster-enabled yes' -e '/# cluster-config-file nodes-6379.conf/a cluster-config-file nodes-6379.conf' -e '/cluster-require-full-coverage yes/a cluster-require-full-coverage no' /apps/redis/etc/redis.conf

[root@redis-node1 ~]#systemctl enable --now redis

驗證當前Redis服務狀態:

#注意程序有[cluster]狀態
[root@centos8 ~]#ps -ef|grep redis
redis   1939    1  0 10:54 ?    00:00:00 /usr/bin/redis-server 0.0.0.0:6379 
[cluster]
root    1955   1335  0 10:57 pts/0    00:00:00 grep --color=auto redis

3.3.3.3 建立叢集

#下面命令在叢集節點或任意叢集外節點執行皆可,命令redis-cli的選項 --cluster-replicas 1表示每個master對應一個slave節點(不寫全是主節點),注意:所有節點資料必須清空
[root@redis-node1 ~]#redis-cli -a 123456 --cluster create 10.0.0.8:6379   10.0.0.18:6379   10.0.0.28:6379   10.0.0.38:6379   10.0.0.48:6379   10.0.0.58:6379 --cluster-replicas 1 
#前3個節點自動為主節點,後3個節點自動和前面3個配主從(順序不確定)
輸入yes確定,會顯示建立和槽位情況(資料分配位置)

#也可以透過--cluster檢視叢集槽位情況    (-a輸入密碼)  後面跟上任意節點ip
[root@ubuntu ~]#redic-cli -a 123456 --cluster check 10.0.0.8:6379
#檢視叢集資訊
[root@ubuntu ~]#redic-cli -a 123456 cluster info
#可以透過cluster配置檔案檢視
#也可如下查叢集
[root@ubuntu ~]#redic-cli -a 123456 info replication

測試

#把一個主節點關了,從節點會自動變為主節點
[root@ubuntu ~]#redic-cli -a 123456 info replication    #在從節點檢視變為主節點
#原來的主節點恢復,會變為新主的從節點

#測試寫入,如果直接連線redis寫入,只能寫入計算key對應的redis節點上,且從節點不提供讀功能,只用來備份資料
#可以透過-c讓叢集自動判斷寫入那個redis節點
[root@ubuntu ~]#redis-cli -a 123456 -c
127.0.0.1:6379> set x y    #會返回寫入哪個槽位的redis中
127.0.0.1:6379> get x    #會根據槽位去對應redis上讀
127.0.0.1:6379> dbsize    #檢視當前節點的資料
#注: 不支援mset,mget多值寫入,多值查詢

python連線Cluster叢集

#!/usr/bin/env python3
from rediscluster  import RedisCluster

if __name__ == '__main__':

    startup_nodes = [
        {"host":"10.0.0.201", "port":6379},
        {"host":"10.0.0.202", "port":6379},
        {"host":"10.0.0.203", "port":6379},
        {"host":"10.0.0.204", "port":6379},
        {"host":"10.0.0.205", "port":6379},
        {"host":"10.0.0.206", "port":6379}]
    try:
        redis_conn= RedisCluster(startup_nodes=startup_nodes,password='123456', decode_responses=True)
    except Exception as e:
        print(e)

    for i in range(0, 10000):
        redis_conn.set('key'+str(i),'value'+str(i))
        print('key'+str(i)+':',redis_conn.get('key'+str(i)))

獲取bigkey ,建議在slave節點執行

#redis-cli --bigkeys

範例: 查詢 bigkey
[root@centos8 ~]#redis-cli -a 123456 --bigkeys

3.3.5 Redis cluster 管理

3.3.5.1 叢集擴容

把現有的槽位挪一部分給新的節點(移動存在風險,可能會有資料丟失,最好讓開發做備份)

#增加兩臺redis伺服器,編譯安裝redis
[root@redis-node7 ~]#dnf -y install redis
[root@redis-node7 ~]#sed -i.bak -e 's/bind 127.0.0.1/bind 0.0.0.0/' -e '/masterauth/a masterauth 123456' -e '/# requirepass/a requirepass 123456' -e '/# cluster-enabled yes/a cluster-enabled yes' -e '/# cluster-config-file nodes-6379.conf/a cluster-config-file nodes-6379.conf' -e '/cluster-require-full-coverage yes/c cluster-require-full-coverage no' /etc/redis.conf

#編譯安裝執行下面操作(別忘了加requirepass)
[root@redis-node7 ~]#sed -i.bak -e '/masterauth/a masterauth 123456' -e '/# cluster-enabled yes/a cluster-enabled yes' -e '/# cluster-config-file nodes-6379.conf/a cluster-config-file nodes-6379.conf' -e '/cluster-require-full-coverage yes/c cluster-require-full-coverage no' /apps/redis/etc/redis.conf

[root@redis-node7 ~]#systemctl restart redis

3.3.5.1.2 新增新的master節點到叢集

使用以下命令新增新節點,要新增的新redis節點IP和埠新增到的已有的叢集中任意節點的IP:埠

add-node new_host:new_port existing_host:existing_port [--slave --master-id <arg>]

#說明:
new_host:new_port #指定新新增的主機的IP和埠
existing_host:existing_port #指定已有的叢集中任意節點的IP和埠

Redis 5 以上版本的新增命令:

#將一臺新的主機10.0.0.68加入叢集,以下示例中10.0.0.58可以是任意存在的叢集節點(命令在任意節點執行都行)
[root@redis-node1 ~]#redis-cli -a 123456 --cluster add-node 10.0.0.68:6379 <當前任意叢集節點>:6379
#例:    將10.0.0.68將入到10.0.0.58所在的叢集中
redis-cli -a 123456 --cluster add-node 10.0.0.68:6379 10.0.0.58:6379

3.3.5.1.3 在新的master上重新分配槽位

新的node節點加到叢集之後,預設是master節點,但是沒有slots,需要重新分配,否則沒有槽位將無法訪 問

Redis 5以上版本命令:

[root@redis-node1 ~]#redis-cli -a 123456 --cluster reshard <當前任意叢集節點>:6379
How many slots do you want to move (from 1 to 16384)?4096 #新分配多少個槽位=16384/master個數
What is the receiving node ID? d6e2eca6b338b717923f64866bd31d42e52edc98 #新的master的ID
Source node #1: all     #輸入all,將哪些源主機的槽位分配給新的節點,all是自動在所有的redis node選擇劃分,如果是從redis cluster刪除某個主機可以使用此方式將指定主機上的槽位全部移動到別的redis主機
Do you want to proceed with the proposed reshard plan (yes/no)?  yes #確認分配

#檢視叢集槽位分配情況,輸入任意叢集地址都行
[root@redis-node1 ~]#redis-cli -a 123456 --cluster check 10.0.0.203:6379

3.3.5.1.4 為新的master指定新的slave節點

Redis 5 以上版本新增命令:

redis-cli -a 123456 --cluster add-node 10.0.0.78:6379 <任意叢集節點>:6379 --cluster-slave --cluster-master-id d6e2eca6b338b717923f64866bd31d42e52edc98

範例:

#直接加為slave節點
[root@redis-node1 ~]#redis-cli -a 123456 --cluster add-node 10.0.0.78:6379 10.0.0.8:6379 --cluster-slave --cluster-master-id d6e2eca6b338b717923f64866bd31d42e52edc98

#驗證是否成功
[root@redis-node1 ~]#redis-cli -a 123456 --cluster check 10.0.0.8:6379

3.3.5.2 叢集縮容

3.3.5.2.1 遷移要刪除的master節點上面的槽位到其它master

#還槽位
[root@redis-node1 ~]# redis-cli -a 123456 --cluster reshard 10.0.0.68:6379
How many slots do you want to move (from 1 to 16384)?1365 #分3批還給3個主節點
What is the receiving node ID? d6e2eca6b338b717923xxxxxxxxxx #還給的masterID
Source node #1: d6exxxxxx717923xxxxxxxxxx     #輸入10.0.0.68(要還槽位)的ID
Source node #2: done    #表示結束的意思
Do you want to proceed with the proposed reshard plan (yes/no)?  yes #確認分配

#檢視是否還槽位成功
[root@redis-node1 ~]#redis-cli -a 123456 --cluster check 10.0.0.8:6379

#按照上述方法,再把剩下的分兩次挪給兩外兩個主節點

3.3.5.2.2 從叢集中刪除伺服器

刪除新加入的主和從節點

Redis 5以上版本命令:

[root@redis-node1 ~]#redis-cli -a 123456 --cluster del-node <任意叢集節點的IP>:6379 cb028b83f9dc463d732f6e76ca6bbcd469d948a7
#cb028b83f9dc463d732f6e76ca6bbcd469d948a7是刪除節點的ID

#檢視是否沒有那兩個節點了
[root@redis-node1 ~]#redis-cli -a 123456 --cluster check 10.0.0.8:6379

#如果被刪的redis節點還想用,作為單節點用
就在redis.conf中把下面引數改成no
cluster-enabled no
[root@redis-node1 ~]#systemctl restart redis
#刪除節點資訊(沒有用了)
[root@redis-node1 ~]#rm -f /var/lib/redis/nodes-6379.conf

3.3.5.3 匯入現有Redis資料至叢集

3.3.5.3.1 基礎環境準備

因為匯入時不能指定驗證密碼,所以匯入資料之前需要關閉所有Redis 節點(括叢集的的節點和叢集外的節 點)的密碼。

#單機redis和redis叢集全部取消密碼和關閉保護模式
#1.新版在所有節點(源節點和叢集節點)需要關閉protected-mode
[root@ubuntu2204 ~]#redis-cli -a 123456 config set protected-mode no

#2.在所有節點(源節點和叢集節點)關閉各Redis密碼認證
[root@ubuntu2204 ~]#redis-cli -p 6379 -a 123456 --no-auth-warning CONFIG SET requirepass ""

3.3.5.3.2 執行資料匯入

將源Redis 節點的資料直接匯入之 Redis cluster,此方式慎用(能推走就讓開發自己導)!

Redis 5以上版本命令:

[root@redis ~]#redis-cli --cluster import <叢集任意節點伺服器IP:PORT> --cluster-from <外部Redis node-IP:PORT> --cluster-copy --cluster-replace

#只使用cluster-copy,則要匯入叢集中的key不能存在
#如果叢集中已有同樣的key,如果需要替換,可以cluster-copy和cluster-replace聯用,這樣叢集中的key就會被替換為外部資料    cluster-replace為替換

#匯入完成後還原密碼/保護模式
#所有redis執行
[root@ubuntu2204 ~]#redis-cli -p 6379 --no-auth-warning CONFIG SET requirepass "123456"
[root@ubuntu2204 ~]#redis-cli -a 123456 config set protected-mode yes

3.3.6 Redis Cluster 的侷限性

3.3.6.1 叢集的讀寫分離

在叢集模式下的從節點是隻讀連線的,也就是說叢集模式中的從節點是拒絕任何讀寫請求的。當有命令嘗試從slave節點獲取資料時,
slave節點會重定向命令到負責該資料所在槽的節點。 為什麼說是隻讀連線呢?因為slave可以執行命令:readonly,這樣從節點就能讀取請求,但是這只是在這次連線中生效。也就是說,當客戶端斷開連線重啟後,
再次請求又變成重定向了。 叢集模式下的讀寫分離更加複雜,需要維護不同主節點的從節點和對於槽的關係。 通常是不建議在叢集模式下構建讀寫分離,而是新增節點來解決需求。不過考慮到節點之間資訊交流帶來的頻寬問題,官方建議節點數不超過1000個。

3.3.6.2 單機,主從,哨兵和叢集的選擇

大多數時客戶端效能會”降低”
命令無法跨節點使用︰mget、keys、scan、flush、sinter等
客戶端維護更復雜︰SDK和應用本身消耗(例如更多的連線池)
不支援多個資料庫︰叢集模式下只有一個db 0
複製只支援一層∶不支援樹形複製結構,不支援級聯複製
Key事務和Lua支援有限∶操作的key必須在一個節點,Lua和事務無法跨節點使用

所以叢集搭建還要考慮單機redis是否已經不能滿足業務的併發量,在redis sentinel同樣能夠滿足高可用,且併發並未飽和的前提下,搭建叢集反而是畫蛇添足了。

相關文章