[redis] redis在線系統熱遷移的方案與記錄


一 前言

如圖,是我的環境。

這里邊有三個系統,1 業務系統。2 redis cluster集群。3 redis cluster集群的管理系統。

系統1,會對redis中進行秒級的數據添加,讀取,刪除操作。系統3,是redis集群的增加節點減少節點,節點failover功能進行管理。

如圖目前,我的系統里,redis共占用了a1,b1,c1,d1四台物理設備。我的目的是,在不影響業務系統運行的情況下,

將redis集群遷移到a2,b2,c2,d2四台物理設備上去。

 

 

二 預備知識

目標系統的redis版本是4.0,之所以強調版本,是因為新版本中,擁有了命令

redis-cli --cluster。4.0版本中並沒有,它的前任是腳本,redis-trib.rb。二者

大同小異,沒有本質區別。

下面是,進行中使用到的幾個操作

1.  查看當前集群拓撲的方法

redis-cli -c cluster nodes 
redis-cli -c cluster slots

拓撲關系

a51459f9cf9b5611cefe137dfcfbd9d9fdb03cfe 10.1.3.168:6379@16379 slave c3ac54ffd1efd366fdf70b3ba0e4185bee49840e 0 1584705659599 6 connected
8ea700c80aa9bebbcd87549cad4538cfeb13dc5f 10.1.4.40:6379@16379 master - 0 1584705662628 1 connected 0-5460
d1fb28322822546c76800cee00fc08ea30eee3d9 10.1.4.39:6379@16379 slave 38dcb1adf11ca19bc66d2d2e887588fb65537c9e 0 1584705658000 4 connected
f4f3aa15073de7f6efc0ee104d4b51de8d5e5ff5 10.1.3.165:6379@16379 slave 8ea700c80aa9bebbcd87549cad4538cfeb13dc5f 0 1584705660606 5 connected
38dcb1adf11ca19bc66d2d2e887588fb65537c9e 10.1.3.170:6379@16379 myself,master - 0 1584705659000 3 connected 10923-16383
c3ac54ffd1efd366fdf70b3ba0e4185bee49840e 10.1.3.169:6379@16379 master - 0 1584705661622 2 connected 5461-10922

 

2  查看數據分布的方法

redis-trib.rb info 127.0.0.1:6379  

數據分別是指,那些數據存儲在那些節點上。

我這里的集群組織方式是,一對一對的組織。每一對有一個master,一個slave。slave作為master的數據冗余和failover節點。可以從上一個命令的輸出里,見到他們的關系,

而,數據的分布如下所示,關注keys信息。可以看見,那些那些key,在那些那些地方。當正在進行數據遷移時,我們能看見keys前邊的數值在一點點減少。

[root@redis6st caotong]# redis-trib.rb info 127.0.0.1:6379
127.0.0.1:6379 (38dcb1ad...) -> 1998 keys | 5461 slots | 1 slaves.
10.1.4.40:6379 (8ea700c8...) -> 2012 keys | 5461 slots | 1 slaves.
10.1.3.169:6379 (c3ac54ff...) -> 1999 keys | 5462 slots | 1 slaves.
[OK] 6009 keys in 3 masters.
0.37 keys per slot on average.

 

3 查看集群實時狀態的方法

redis-trib.rb check 127.0.0.1:6379 

這個輸出,重點關心的是一下額外的信息, 如xxx is migrating 字樣

復制代碼
[root@redis6st caotong]# redis-trib.rb check 127.0.0.1:6379
>>> Performing Cluster Check (using node 127.0.0.1:6379)
M: 38dcb1adf11ca19bc66d2d2e887588fb65537c9e 127.0.0.1:6379
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
S: a51459f9cf9b5611cefe137dfcfbd9d9fdb03cfe 10.1.3.168:6379
   slots: (0 slots) slave
   replicates c3ac54ffd1efd366fdf70b3ba0e4185bee49840e
M: 8ea700c80aa9bebbcd87549cad4538cfeb13dc5f 10.1.4.40:6379
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
S: d1fb28322822546c76800cee00fc08ea30eee3d9 10.1.4.39:6379
   slots: (0 slots) slave
   replicates 38dcb1adf11ca19bc66d2d2e887588fb65537c9e
S: f4f3aa15073de7f6efc0ee104d4b51de8d5e5ff5 10.1.3.165:6379
   slots: (0 slots) slave
   replicates 8ea700c80aa9bebbcd87549cad4538cfeb13dc5f
M: c3ac54ffd1efd366fdf70b3ba0e4185bee49840e 10.1.3.169:6379
   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.
復制代碼

 

三 思路

兩個思路。

1,把集群節點遷走,集群還是那個集群只不過他們的各種節點都被更新了。

2,把數據遷走,幸運的是我的業務系統有重連機制,並且支持熱修改集群信息。所以只要保證數據的增刪改查都能成功並正確。切換一個全新的cluster同樣對業務無感知。

 

四 方案一

我這里,采用的遷移方案,是先擴容再縮容。這樣是熱的,online的。對在線系統無感知的。

把你想遷入的目標作為擴容資源擴進來,然后再將你想縮容的資源作為遷出目標縮掉,即可。

 

我會先增加一對主備節點,然后理由上面提到的兩個命令,來觀察:

(1)遷移的過程是否正常,(2)數據是否正常流動,(3)遷移是否已經進行完成

遷移進行完成指的是數據流動已經完成。

過程是否正常:1 通過前文的check命令查看runtime狀態。2.通過info命名查看數據流動進程。

最終的狀態,可以通過nodes命令觀察,是否出現fail的節點。以及是否每個master都結對一個slave,

包括誰和誰是一對的這種對應關系。

 

增減動作通過前文中的管理系統接口完成的,沒有命令的細節。 該系統只是對redis -cli和redis-trib.rb的封裝,

附加了他自己的邏輯在里邊。

redis-cli --cluster help可以看見更多細節,包括add node,add slot之類的常用命令。

刪除一個節點的方法:

redis-trib.rb del-node host:port node_id

參考: https://www.cnblogs.com/ivictor/p/9768010.html

 

然而,該方案並沒有實施成功,因為該管理系統的bug,導致其自己進入不可跳出的管理狀態里。

這里不在贅述,進入方案二

 

五 方案二

如前文述,方案二的思路是數據遷移。管理系統在節點變更是存在問題。但是全新創建的話,仍然是可用的。

於是,現在我們可用繞可它來達到目標。

需要強調的是,本人是新手,完成100台以下的數據遷移工作只有三天時間,並之前幾乎沒有好好接觸過redis。

所以整體目標是安全與快速。故選用以下四個方法,並排列優先級:

 

可選有四種方法,要求必須滿足online的數據無縫熱遷移:

1  python工具:https://github.com/p/redis-dump-load

  該工具簡單使用后發現不支持集群,只支持單點設備。工作量大,留做備選。

 

2  ruby工具: https://github.com/delano/redis-dump

  該工具測試之后發現有一個bug。用的話,需要修復一下bug。會增加額外工作,留作備選。報錯如下

CROSSSLOT Keys in request don't hash to the same slot redis dump

   另外,這個東西安裝有點麻煩,還有安裝ruby環境。安裝ruby的環境與包管理工具的方法:

yum install rubygems

3  C工具:https://github.com/tanruixing88/redis-migrate-tool 

  該方法可以。並最后成功了。后邊詳述。另,這是唯品會工具的一個fork,說是唯品會的只支持3.0,這個支持高版本,見:

  https://cco.xyz/post/redis-migrae-tool/

4  RDB與AOF方案:使用bgsave命令,已經修改配置文件等方法。

  這是保底方案,是官方正規方法,並且一點可以成功。但是很顯然更花時間。有額外的學習成本,也有額外的時間成本。

 

redis-migrate-tool的詳細操作步驟

1  配置文件: 所有節點的IP + Port,包括slave和master

[source]
type: redis cluster
servers:
- 10.1.0.12:6379
- 10.1.0.6:6379
- 10.1.0.24:6379
- 10.1.0.11:6379
- 10.1.0.5:6379
- 10.1.0.9:6379
- 10.1.0.8:6379
- 10.1.0.7:6379
- 10.1.0.13:6379
- 10.1.0.10:6379

[target]
type: redis cluster
servers:
- 10.1.0.50:6379
- 10.1.0.46:6379
- 10.1.0.48:6379
- 10.1.0.47:6379
- 10.1.0.45:6379
- 10.1.0.51:6379
- 10.1.0.49:6379
- 10.1.0.19:6379

[common]
listen: 0.0.0.0:8888

 

 

快速生成以上ip串的小技巧:

redis-cli -c cluster nodes |awk '{print $2}' |awk -F'@' '{print "- "$1}'

2   啟動方法:

./redis-migrate-tool -c migrate.conf -o log -d

 

 

3  停止方法

使用下面的命令行進入管理界面:

redis-cli -h 127.0.0.1 -p 8888

 

然后執行shutdown命令。

 

遷移步驟:

1  新建一個全新的redis 集群,並確保集群建立成功,集群狀態up。

2  配置 redis-migrate-tool工具的配置文件

3  啟動工具,這個時候能觀察到新group中的key書目在不斷增加。直到超過舊集群的key總數。

    這里需要說明的時候,因為舊group依然是業務在線的。所以key實際上處於有增有減的動態過程中。而遷移工具實際上做的時候一個不斷copy的工作,

   所以,新集群實際上是舊集群里所有key的累加結果。被刪掉的舊集群上的key並不會被一起上新集群里刪掉。

4  這里有兩個假設,

   1  遷移工具的遷移速度大於舊集群中key的新增速度。

   2  業務系統必須容忍這樣一直失敗場景:剛存入的key,在小於遷移速度的時間內有可能獲取失敗。

   在滿足以上兩個條件的前提下,進行第五步操作:

   遷移業務系統:使用命令解綁舊的業務系統與redis 集群的綁定關系,綁定新的集群。

 

6  在第五步完成之后,可以觀察到舊集群中的key數量將不在變化,沒有新的key增加,也沒有舊的key刪除。

    再觀察遷移工具,發現全部的key遷移已經完成了。

   這塊時候可以停止遷移工具了。

 

7  刪除舊的集群

 

8  (4)中提到的那些沒有被刪除的舊key,會在n天后超時自己刪掉自己。

  我的業務系統對每一個key丟進行了超時配置。不過即使沒有這個附件條件,依然沒有關系,我們可以通過一下方法來達到這個目的,

  以使得我的方案更具有處理一般問題的普適性。

  對所有可以,設置超時的方法:

redis-cli -c keys '*yourKEYWORD*' |xargs -l -I {} redis-cli -c set {} 123 ex 3

 

至此,數據熱遷移完成。對業務無感知。

 

六 完

 [classic_tong @ 20200321  https:////www.cnblogs.com/hugetong/p/12584107.html] 

完。

參考:https://yq.aliyun.com/articles/726005 


免責聲明!

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



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