redis主備同步非常友善,通過slaveof指令即可同步。上周應用切換了redis,想讓新的redis和舊的redis進行資料同步,結果把新redis中其他應用已經寫入的所有資料都删除了。。。這裡記錄下恢複方法。
首先先恢複redis的dump檔案。還好現在阿裡雲彈性計算叢集給每個鏡像每天都進行了備份,通過操作前一天的備份鏡像,快照制作當時的整個redis目錄複制了出來,作為恢複的基礎。
然後将恢複回來的檔案再複制一份備份,原先那份修改redis的配置檔案,修改啟動端口(我從預設的6379改成了6479),然後啟動舊的redis,成功将當時的dump檔案載入到新的redis執行個體中。
查詢到redis有migrate指令,能夠将key遷移到另外一個redis執行個體中(具體參考這裡)。通過bash指令,循環的将備份的執行個體所有key,都試圖通過migrate指令遷移到新的redis中。
遷移過程中,遷移成功的key,在舊的執行個體中會被删除,失敗的key,可以看見失敗原因都是key is busy。也就是說,要遷移的key在新的執行個體中已經存在了。
和使用方确定了所有已經存在的key,是hash類型的,都是要保留的資料。是以,通過一個簡單的shell腳本,讀取備份執行個體中hash類型key,并添加到新的redis中。bash腳本為:
[cce lang=”bash”]
#!/bin/bash
old_redis="./redis-cli -p 6479"
new_redis="./redis-cli"
keys=`$old_redis keys '*'`
for k in $keys
do
key_type=`$old_redis type $k`
if [ $key_type = "hash" ]; then
hash_keys=`$old_redis hkeys $k`
for hash_key in $hash_keys
hash_value=`$old_redis hget $k $hash_key`
$new_redis hset $k $hash_key $hash_value
echo "merge $k $hash_key to new redis"
done
#eval "$old_redis del $k"
fi
[/cce]
邏輯非常簡單,就是先通過keys指令擷取到所有遷移失敗的key,然後通過type指令擷取類型。如果是hash類型的key,周遊所有的hash key,然後讀取出一個key下所有的鍵值對,并通過hset指令放到新的redis執行個體中。最後将合并完成的key從備份執行個體中删除。這裡由于業務上隻需要合并hash類型的,其他容器類型(list, set等)也可以通過類似的方式做新老合并。
轉載自:https://coolex.info/blog/427.html