Redis開發與運維:數據遷移
- 2019 年 10 月 11 日
- 筆記
問題
最近項目重構,提前想把一台上的redis實例轉移到另一台redis實例上。
源redis資料庫:阿里雲Redis、VPC網路、Server版本2.8.19 目標資料庫:阿里雲Redis、VPC網路、Server版本4.0.11 前提:
當前我們使用Redis作為我們的資料庫(永久+ 臨時快取) 目標:
把當前永久性數據導入到目標資料庫,臨時快取數據不做處理 方案
設置主從複製,這個應該是比較穩妥的方案,但是支援主從必須3.0以上 -- 這個方案否掉了 那就使用鍵遷移命令,查了一下三種方式:move 、dump + restore 、migrate 自測
Windows伺服器,下載了源資料庫 redis2.8.19 分別啟用了兩個實例分別是 6999和7999 源數據 6999,目標數據 7999 move
這個命令是做實例內,db遷移的,對於當前實例間同步是不滿足的。
但也不妨嘗試一下:
db5中的鍵移到db6,
localhost:6999[5]> get QianBiTou:VC:Config "0x001,1,2,3" localhost:6999[5]> move QianBiTou:VC:Config 6 (integer) 1 localhost:6999[5]> get QianBiTou:VC:Config (nil) 移動嘛所以db5的鍵就沒了,db6才能獲取到
localhost:6999[5]> SELECT 6 OK localhost:6999[6]> get QianBiTou:VC:Config "0x001,1,2,3" dump + restore
1、源資料庫上:dump 相當於把這個鍵按照協議序列化
localhost:6999[6]> get QianBiTou:VC:Config "0x001,1,2,3" localhost:6999[6]> DUMP QianBiTou:VC:Config "x00x0b0x001,1,2,3x06x00xfbx06ZUnxdexb5x95" 2、目標資料庫上:restore 進行初始化這個鍵
127.0.0.1:7999[2]> RESTORE QianBiTou:VC:Config 0 "x00x0b0x001,1,2,3x06x00xfbx06ZUnxdexb5x95" OK 127.0.0.1:7999[2]> GET QianBiTou:VC:Config "0x001,1,2,3" 這個方案呢,可行但是看了一下第三個,感覺第3個是2的改進版本
migrate
localhost:6999[6]> help migrate MIGRATE host port key destination-db timeout [COPY] [REPLACE] summary: Atomically transfer a key from a Redis instance to another one. since: 2.6.0 group: generic 從這到那:127.0.0.1:6999 -> 127.0.0.1:7999 key=QianBiTou:VC:Config
1、看看源資料庫6999,db6這個key的值。嗯,有值。
localhost:6999[6]> get QianBiTou:VC:Config "0x001,1,2,3" 2.、再看看目標資料庫,把這個key清場.
127.0.0.1:7999[2]> GET QianBiTou:VC:Config "0x001,1,2,3" 127.0.0.1:7999[2]> DEL QianBiTou:VC:Config (integer) 1 127.0.0.1:7999[2]> GET QianBiTou:VC:Config (nil) 3.、準備好了,那就開始轉吧,走你
localhost:6999[6]> get QianBiTou:VC:Config "0x001,1,2,3" localhost:6999[6]> MIGRATE 127.0.0.1 7999 QianBiTou:VC:Config 2 5000 OK 4、看看目標機器上過來了木有
en, 過來了 127.0.0.1:7999[2]> GET QianBiTou:VC:Config "0x001,1,2,3" 5.、再看看源資料庫
e...沒啦? localhost:6999[6]> get QianBiTou:VC:Config (nil) 再進一步
查閱資料發現,MIGRATE = dump + restore + del ,因為它是原子性的所以推薦使用這個方法。 但是會把原來的數據刪掉,類似於跨實例move。文檔中 加上copy和replace 參數就不會刪除源數據了。 copy 複製
replcae 複製並替換
1.、再試試,數據重新加回去
localhost:6999[6]> set QianBiTou:VC:Config 0x001,1,2,3 OK localhost:6999[6]> MIGRATE 127.0.0.1 7999 QianBiTou:VC:Config 2 5000 replace (error) ERR wrong number of arguments for 'migrate' command 2.、報錯了,再查查官方資料。好吧,還是版本不支援:
COPY and REPLACE are available only in 3.0 and above. KEYS is available starting with Redis 3.0.6. AUTH is available starting with Redis 4.0.7. 最終方案
1、主從 --不行,版本低了
2、MOVE-- 不行,實例內,數據沒了
3、 MIGRATE --不行,實例間,版本不行+數據沒了
4、 dump + restore 這個算是最終方案
方案可行性:因為不涉及快取數據,是永久數據的導出導入,所以不存在原子性問題,還有忘記了一點數據量非常小 執行方案
[TestMethod] public async Task RestoreToOtherRedis_Test() { // 源redis string sourceRedis = "r-xxxxxxxxxxxpd.redis.rds.aliyuncs.com:6379,password=uuuuuu,defaultDatabase=5,prefix="; //目標redis string targetRedis = "r-xxxxxxxxxxxxpd.redis.rds.aliyuncs.com:6379,password=uuuuuu,defaultDatabase=5,prefix="; List<string> keys = new List<string>(); try { using (var sourceClient = new CSRedis.CSRedisClient(sourceRedis)) { // key 很少的時候使用cmd: keys * // 建議使用 scan keys = sourceClient.Keys("*").ToList(); using (var targetClient = new CSRedis.CSRedisClient(targetRedis)) { foreach (var key in keys) { if (key.StartsWith("RedisCach")) continue; // 序列化數據 var dump = sourceClient.Dump(key); // 初始化數據 var ok = targetClient.Restore(key, dump); } } } } catch (Exception ex) { string msg = ex.ToString(); } finally { } 驗證
事後驗證了一下,確實數據過來了 
注意點
MOVE 實例內 MIGRATE 原子操作。最好使用copy和replace 參數源數據不刪除。 DUMP + RESTORE 不是原子操作 