天天看點

Redis Cluster實作叢集伸縮,附帶SpringBoot操作Redis 叢集

作者:添甄
滿懷憂思,不如先幹再說!

本文章為系列文章,如需系統觀看請按照文章順序閱讀,如有所了解,解決針對性問題,可直接閱讀,謝謝支援!用到Redis版本為5.X,不是最新版,是我公司使用的版本。

叢集伸縮介紹

叢集伸縮說白了就是在Redis中上線和下線節點,比如我們上篇文章中使用了6台節點3主3從來存儲資料,如果公司業務蒸蒸日上6台節點不夠用我們就需要新增節點,這個叫做叢集擴容 ,如果有點涼或者高峰期過了就需要下線節點,這個叫做叢集縮容。這裡就說說Redis5.0.5版本怎麼去擴容和縮容叢集。

Redis Cluster實作叢集伸縮,附帶SpringBoot操作Redis 叢集

節點擴容

Redis Cluster實作叢集伸縮,附帶SpringBoot操作Redis 叢集

配置檔案

這個配置和之前一樣,改改端口檔案名即可

port 8006
daemonize yes
logfile "8006.log"
dir "/usr/local/redis-5.0.5/data/"
protected-mode no
dbfilename dump-8006.rdb
# 開啟叢集
cluster-enabled yes
# 叢集運作時檔案
cluster-config-file nodes-8006.conf
# 是否叢集所有的節點都正常叢集才可使用,改為no
cluster-require-full-coverage no
# 節點請求逾時時間 
cluster-node-timeout 15000
# 關閉保護模式
protected-mode no           

啟動節點

redis-server redis-8006.conf
redis-server redis-8007.conf           

檢視節點啟動狀态

Redis Cluster實作叢集伸縮,附帶SpringBoot操作Redis 叢集

添加節點

1、使用redis-cli --cluster help指令檢視幫助

Redis Cluster實作叢集伸縮,附帶SpringBoot操作Redis 叢集

create:建立一個叢集

call:可以執行redis指令

add-node:将一個節點添加到叢集裡,第一個參數為新節點的ip:port,第二個參數為叢集中任意一個已經存在的節點的ip:port

del-node:移除一個節點

reshard:重新分片

check:檢查叢集狀态

2、使用add-node參數添加節點

redis-cli --cluster add-node 127.0.0.1:8006 127.0.0.1:8000
redis-cli --cluster add-node 127.0.0.1:8007 127.0.0.1:8000           
這裡抱歉一下:我運作出來的圖找不到了,是以借了一張,大概長這樣
Redis Cluster實作叢集伸縮,附帶SpringBoot操作Redis 叢集

檢視節點狀态

說明:我這裡大家看到我打有馬賽克,因為這張圖是我配置設定完槽之後截的,因為之前的圖一樣找不到了,大家會發現這裡多了兩台節點8006和6007
Redis Cluster實作叢集伸縮,附帶SpringBoot操作Redis 叢集

配置設定槽

執行以下指令:

redis-cli --cluster reshard 127.0.0.1:8000           
這裡會出現下圖效果,這裡會讓你選擇你想挪動多少槽,從1到16384,後續資訊我在下方使用文字貼出,大家跟着去做!
Redis Cluster實作叢集伸縮,附帶SpringBoot操作Redis 叢集

How many slots do you want to move (from 1 to 16384)? 2000

說明:需要多少個槽移動到新的節點上,自己設定,比如2000個槽

What is the receiving node ID? de7f62b1b649622bd18e8b4983864573ee6cc0e0

說明:把這2000個hash槽移動到哪個節點上去,需要指定節點id,我這裡寫的是8006的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為從所有主節點中分别抽取相應的槽數指定到新節點中,抽取的總槽數為2000個;或者輸入原節點ID然後輸入done,意思将輸入的節點ID,抽取的總槽數為2000個,我這裡輸入的是all。

Do you want to proceed with the proposed reshard plan (yes/no)? yes

注意:輸入yes确認開始執行分片任務

檢視新的節點狀态

大家算一算這個是不是我們撒謊改變配置設定的有2000個槽,這2000個槽分别從8000、8001、8002分過來的,而8007并沒有配置設定槽,他是8006的從節點,接下來我們設定一下。

Redis Cluster實作叢集伸縮,附帶SpringBoot操作Redis 叢集

配置主從關系

大家可還記得如何人配置設定主從?

redis-cli -p 8007 cluster replicate de7f62b1b649622bd18e8b4983864573ee6cc0e0           

檢視叢集狀态發現8007變成slave

Redis Cluster實作叢集伸縮,附帶SpringBoot操作Redis 叢集
至此我們完成了節點擴容,從原本的3主3從,擴容成4主4從。我們這裡都是在同一台節點上完成的,在實際生産過程中都是在不同節點上的,隻需要修改ip和端口号即可,相信這對優秀的各位來說都是小意思!

叢集縮容

Redis Cluster實作叢集伸縮,附帶SpringBoot操作Redis 叢集

下線8007從節點

使用del-node ip:port nodeID

redis-cli --cluster del-node 127.0.0.1:8007 d4aa5b7ea13899beef910b93228fc27b48bf88f4           
Redis Cluster實作叢集伸縮,附帶SpringBoot操作Redis 叢集

檢視叢集狀态

你會發現8007節點已經下線了

Redis Cluster實作叢集伸縮,附帶SpringBoot操作Redis 叢集

下線8006主節點

這個稍微有點麻煩,因為主節點上有資料槽,需要歸還槽,然後在執行下線操作,否則就有可能造成資料丢失,這也是裡邊的小細節需要大家牢記!

執行:redis-cli --cluster reshard 127.0.0.1:8006

配置設定槽

這裡一定要注意,我這裡怎麼變成4000了呢,我之前不是配置設定了2000個槽到8006嗎?因為上邊操作錯誤了。是以這裡第一個ID是接收槽的節點的ID也就是8000的ID,第二個填寫源節點的ID也就是8006的ID。
Redis Cluster實作叢集伸縮,附帶SpringBoot操作Redis 叢集

檢視叢集狀态

我們發現8006已經沒有槽了,而8000多了10923-12255槽
Redis Cluster實作叢集伸縮,附帶SpringBoot操作Redis 叢集

下線節點

redis-cli --cluster del-node 127.0.0.1:8006 de7f62b1b649622bd18e8b4983864573ee6cc0e0           
Redis Cluster實作叢集伸縮,附帶SpringBoot操作Redis 叢集

檢視叢集狀态

已經成功下線,我們進入叢集測試添加查詢資料都是沒有問題的。

Redis Cluster實作叢集伸縮,附帶SpringBoot操作Redis 叢集

重定向

moved重定向

我們先來看看下邊的指令出現的問題

Redis Cluster實作叢集伸縮,附帶SpringBoot操作Redis 叢集
上邊的兩個紅色框分别為8000的槽和8001的槽 緊接着的是我們想叢集中set了一個資料key為java,value為javaweb 接下來的cluster keyslot java指令是計算java這個key應該配置設定到那個槽中,結果為858,那麼858這個槽在8000節點上是以資料就存儲在了8000節點上 我們看最後一個紅框,計算了python的槽值為7252,被8001節點維護,是以set值時大家發現多出一行提示重定向到8001上接下來我們的用戶端就被重定向到了8001端口可以看到最後一行已經由8000程式設計了8001 如果我們去擷取或者設定資料,如果直接在該節點維護那麼會直接完成操作,如果不在該節點,Redis會向用戶端回複moved,用戶端會重定向到指定的節點上操作

ask重定向

Redis Cluster實作叢集伸縮,附帶SpringBoot操作Redis 叢集

moved和ask差別

  1. 兩者都是用戶端重定向
  2. moved确定槽已經遷移,不在目前節點
  3. ask是槽還在遷移中
大家會發現,如果我們遷移了槽或者槽正在遷移中我們的用戶端來通路Redis Cluster中随機一個節點時如果資料不在該節點上會去做moved或者ask操作也就是重定向到其他的節點上 ,這樣會對性能造成一定的影響。比如我們叢集中有100個節點那麼直接命中的機率就是1%。基于這個問題,我們面給大家說Stream用戶端來解決

smart用戶端

介紹

我們的叢集資料在不同的slot中,在不同的節點上,key不在該節點上那麼會發生moved重定向,去其他節點上操作,如果叢集正在伸縮在做槽的遷移那麼會發生ask重定向,會大大影響我們對Redis叢集操作的性能,我們可以使用smart用戶端完成高性能的操作Redis Cluster。我們通過JedisCluster對象操作Redis叢集。

原理

  1. 從叢集中選擇一個可以運作的節點,使用Cluster slots初始化槽和節點映射
  2. 将這種映射關系存儲到本地,為每一個節點建立一個Jedis Pool
  3. 之後直接連接配接到Redis節點上去執行指令
  4. smart用戶端将key發送到指定的節點上,如果成功就會得到響應
  5. 如果出現連接配接出錯,随機找個活躍節點,向其發送指令,大機率會得到 moved 異常,然後重新初始化 slot 和 node 的映射關系,再向目标節點發送指令
  6. 如果這樣的情況連續出現 5 次,報錯:Too many cluster redirection!
Redis Cluster實作叢集伸縮,附帶SpringBoot操作Redis 叢集

SpringBoot操作Redis Cluster

參考《最新超詳細注釋解析SpringBoot2.X操作Redis5.X》,隻需要修改配置檔案中的連接配接即可,操作等等都一樣

application.yml檔案

spring:
  redis:
    cluster:
      nodes: 192.168.11.101:8000,192.168.11.101:8001,192.168.11.101:8002,192.168.11.101:8003,192.168.11.101:8004,192.168.11.101:8005
    timeout: 5000ms           

總結

  • Redis單機,主從複制,哨兵,叢集都可以成功搭建
  • 各運作模式之間的關系,特點也都心中明朗
  • SpringBoot操作Redis單機,哨兵和叢集
  • 怎麼用好Redis,開發規範,出現的坑,相關面試題請大家關注Redis系列文章後續繼續推出
如果不錯記得關注,點贊哦!無償提供程式設計咨詢服務,如有需要可私信

繼續閱讀