#作者:任少近
文章目錄
- 前言
- Redis的持久化機制
- RDB
- AOF
- Redis save和bgsave的區別
- redis數據遷移
- redis單機-單機數據遷移
- redis 主從-主從數據遷移
- redis 單機-cluster數據遷移
- redis cluster –redis cluster數據遷移
前言
Redis數據遷移是常見需求,主要包括四種場景:
單機到單機遷移
主從到主從遷移
單機到集群遷移
集群到集群遷移
每種方案都需考慮數據量、停機窗口和業務影響,建議在非高峰時段進行遷移并充分測試。
Redis的持久化機制
RDB
RDB持久化是指在指定的時間間隔內將內存中的數據集快照寫入磁盤,實際操作過程是fork一個子進程,先將數據集寫入臨時文件,寫入成功后,再替換之前的文件,用二進制壓縮存儲。Redis 默認方式。
RDB優勢:
利于備份:一旦采用該方式,那么你的整個Redis數據庫將只包含一個文件,這對于文件備份而言是非常完美的。
數據恢復便捷:對于災難恢復而言,RDB是非常不錯的選擇。因為我們可以非常輕松的將一個單獨的文件壓縮后再轉移到其它存儲介質上。
性能最大化:對于Redis的服務進程而言,在開始持久化時,它唯一需要做的只是fork出子進程,之后再由子進程完成這些持久化的工作,這樣就可以極大的避免服務進程執行IO操作了。
相比AOF數據量小:相比于AOF機制,如果數據集很大,RDB的啟動效率會更高。
RDB劣勢:
數據的完整性和一致性不高:系統一旦在定時持久化之前出現宕機現象,此前沒有來得及寫入磁盤的數據都將丟失。
備份時占用資源:因為Redis 在備份時會獨立創建一個子進程,將數據寫入到一個臨時文件,最后再將臨時文件替換之前的備份文件,因為bgsave每次運行都要執行fork操作創建子進程,頻繁執行成本過高。
RDB持久化配置:
-
指定在多長時間內,有多少次更新操作,就將數據同步到數據文件,可以多個條件配合
save
Redis默認配置文件中提供了三個條件:
save 900 1
save 300 10
save 60 10000
#分別表示900秒(15分鐘)內有1個更改,300秒(5分鐘)內有10個更改以及60秒內有10000個更改。 -
指定本地數據庫文件名,默認值為dump.rdb
dbfilename dump.rdb -
指定本地數據庫存放目錄
dir ./
AOF
AOF持久化以日志的形式記錄服務器所處理的每一個寫、刪除操作,查詢操作不會記錄,以文本的方式記錄,可以打開文件看到詳細的操作記錄。
AOF的優勢:
數據的完整性和一致性更高:Redis中提供了3中同步策略,即每秒同步、每修改同步和不同步。事實上,每秒同步也是異步完成的,其效率也是非常高的,所差的是一旦系統出現宕機現象,那么這一秒鐘之內修改的數據將會丟失。而每修改同步,我們可以將其視為同步持久化,即每次發生的數據變化都會被立即記錄到磁盤中。
AOF的劣勢:
占用磁盤空間大,數據恢復速度慢:對于相同數量的數據集而言,AOF文件通常要大于RDB文件。RDB 在恢復大數據集時的速度比 AOF 的恢復速度要快。
運行效率低,頻繁同步:根據同步策略的不同,AOF在運行效率上往往會慢于RDB。
AOF持久化配置:
1.指定是否在每次更新操作后進行日志記錄,因為的數據會在一段時間內只存在于內存中,可能會在斷電時導致一段時間內的數據丟失。默認為no
appendonly no
-
指定更新日志文件名,默認為appendonly.aof
appendfilename appendonly.aof -
指定更新日志策略,共有3個可選值:
no:表示等操作系統進行數據緩存同步到磁盤(快)
always:表示每次更新操作后手動調用fsync()將數據寫到磁盤(慢,安全)
everysec:表示每秒同步一次(折衷,默認值)
appendfsync everysec
Redis save和bgsave的區別
save
Reids save命令執行一個同步保存操作,將當前Redis實例的所有數據快照(snapshort)已RDB文件的方式保存到磁盤
bgsave
bgsave執行后,會立刻返回OK,Redis 會fork一個子進程,原來的redis主進程繼續執行后續操作,新fork的子進程負責將數據保存到磁盤,然后退出
區別:
save同步阻塞主進程,只有等save完后成,才能進行新操作(阻塞, 只管保存快照,其他的等待)
bgsave 是fork的子進程,非阻塞,等執行完后會通知主進程,然后關閉子進程
redis數據遷移
redis單機-單機數據遷移
遷移環境如下:
# A服務器
***.***.*.171 midware-171
# B服務器
***.***.*.172 midware-172 r
方法1
A 服務器
127.0.0.1:6379> info
# Cluster
cluster_enabled:0# Keyspace
127.0.0.1:6379>
B服務器
127.0.0.1:6379> info
# Cluster
cluster_enabled:0# Keyspace
127.0.0.1:6379>
在A服務器上執行腳本生成10000條數據
在A服務器上手動保存數據
127.0.0.1:6379> bgsave
Background saving started
查看數據目錄
[root@midware-171 data]# ls
appendonly.aof dump.rdb
停止A服務器
127.0.0.1:6379> exit
[root@midware-171 redis]# ps -ef|grep redis
root 13566 1 0 11:29 ? 00:00:06 bin/redis-server 0.0.0.0:6379
root 23799 7625 0 11:45 pts/1 00:00:00 grep --color=auto redis
[root@midware-171 redis]# kill -9 13566
停止B服務器
[root@midware-172 redis]# ps -ef|grep redis
root 9812 1 0 11:36 ? 00:00:00 bin/redis-server 0.0.0.0:6379
root 9916 8451 0 11:46 pts/1 00:00:00 grep --color=auto redis
[root@midware-172 redis]# kill -9 9812
將數據文件從A服務器 拷貝 到 B服務器
[root@midware-171 data]# scp appendonly.aof midware-172:/home/test/redis/data/
appendonly.aof 100% 349KB 79.6MB/s 00:00
[root@midware-171 data]# scp …/conf/redis.conf midware-172:/home/test/redis/conf/
redis.conf
啟動B服務器服務
[root@midware-172 redis]# bin/redis-server ./conf/redis.conf
查看數據
方法2:
停止B服務器,并清除數據
[root@midware-172 redis]# ps -ef|grep redis
root 10042 1 0 11:55 ? 00:00:01 bin/redis-server 0.0.0.0:6379
root 10096 10047 0 11:55 pts/0 00:00:00 ./bin/redis-cli
root 10316 8451 0 12:16 pts/1 00:00:00 grep --color=auto redis
[root@midware-172 redis]# kill -9 10042
[root@midware-172 redis]# rm -rf /data/*
拷貝數據到B機
[root@midware-171 data]# scp dump.rdb midware-172:/home/test/redis/data/
dump.rdb
更改B機配置文件
[root@midware-172 redis]# cat conf/redis.conf
appendonly no
啟動redis B服務
[root@midware-172 redis]# bin/redis-server ./conf/redis.conf
127.0.0.1:6379> info
更改日志存儲方式
127.0.0.1:6379> CONFIG get appendonly
1) "appendonly“ 2) "no"
127.0.0.1:6379> CONFIG set appendonly yes
OK
127.0.0.1:6379> CONFIG get appendonly
1) "appendonly“ 2) "yes"
更改B機配置文件
[root@midware-172 redis]# cat conf/redis.conf
appendonly yes
查看B機key 總數
# Cluster
cluster_enabled:0
# Keyspace
db0:keys=11002,expires=0,avg_ttl=0
127.0.0.1:6379>
redis 主從-主從數據遷移
注:
主從節點遷移,把所有節點當作單機節點來遷移即可
如果是 主從+哨兵 忽略 sentinel 節點,將哨兵拓撲當成普通的主從節點即可
redis 單機-cluster數據遷移
遷移環境如下:
# A服務器
***.***.*.171 midware-171 # Redis cluster B主 從
***.***.*.171:7001 ***.***.*.172:7002
***.***.*.172:7001 ***.***.*.173:7002
***.***.*.173:7001 ***.***.*.171:7002
在A服務器上執行腳本生成12000條數據
[root@midware-171 test]# redis/bin/redis-cli info# Cluster
cluster_enabled:0# Keyspace
db0:keys=12000,expires=0,avg_ttl=0
[root@midware-171 test]#
1.查看Redis cluster B 狀態
2、查看并記錄集群信息,記錄集群id ,ip,角色。后續會使用
記錄每個主節點的slot 數量
3、遷移其他主節點的slot到其中一個主節點
redis-cli -a 123456 --cluster reshard ***.***.*.171:7001 --cluster-from acb7d8390fc2cf2dac0bc07d38ddeb6c7f474109 --cluster-to d190bb0128ff2101f3fdc13561b8edc6755448fa --cluster-slots 5461 --cluster-yesredis-cli -a 123456 --cluster reshard ***.***.*.171:7001 --cluster-from dccce6ccb5ff7152c959b0eda8c655c4eff053c3 --cluster-to d190bb0128ff2101f3fdc13561b8edc6755448fa --cluster-slots 5462 --cluster-yes#刪除原主節點
[root@midware-171 redis]# bin/redis-cli -a 123456 --cluster del-node ***.***.*.171:7001 acb7d8390fc2cf2dac0bc07d38ddeb6c7f474109#重新加入 master 節點 ***.***.*.172:7001 是新加入節點,***.***.*.171:7001 是集群中已存在的節點
redis-cli -a 123456 --cluster add-node ***.***.*.172:7001 ***.***.*.171:7001#刪除從節點
[root@midware-171 redis]# bin/redis-cli -a 123456 --cluster del-node ***.***.*.171:7001 7a82ca3e8e3a71d8fe12572117218fb00e72535d#重新加入節點***.***.*.172:7001,且設置為7a82ca3e8e3a71d8fe12572117218fb00e72535d
redis-cli -a 123456 --cluster add-node ***.***.*.172:7001 ***.***.*.171:7001 --cluster-slave --cluster-master-id acb7d8390fc2cf2dac0bc07d38ddeb6c7f474109
… 同樣處理另外二個節點
再次查詢cluster 節點信息,已經和之前一致
4、關閉集群。放入單機redis生成的 appendonly.aof 到槽位所在的 master節點,且只啟動該節點redis,觀察數據是否正確導入。
redis-cli -a 123456
查看數據是否導入
[root@midware-171 redis]# bin/redis-cli -a 123456 -h ***.***.*.171 -p 7001 info# Cluster
cluster_enabled:1# Keyspace
db0:keys=12000,expires=0,avg_ttl=0
5.重新分配slot
[root@midware-171 redis]# redis-cli -a 123456 --cluster reshard ***.***.*.171:7001 --cluster-from d190bb0128ff2101f3fdc13561b8edc6755448fa --cluster-to acb7d8390fc2cf2dac0bc07d38ddeb6c7f474109 --cluster-slots 5462 --cluster-yes[root@midware-171 redis]# redis-cli -a 123456 --cluster reshard ***.***.*.171:7001 --cluster-from d190bb0128ff2101f3fdc13561b8edc6755448fa --cluster-to dccce6ccb5ff7152c959b0eda8c655c4eff053c3 --cluster-slots 5461 --cluster-yes
查看結果
[root@midware-171 redis]# bin/redis-cli -a 123456 -h ***.***.*.171 -p 7001 info
# Keyspace
db0:keys=3988,expires=0,avg_ttl=0[root@midware-171 redis]# bin/redis-cli -a 123456 -h ***.***.*.172 -p 7001 info
# Keyspace
db0:keys=3996,expires=0,avg_ttl=0[root@midware-171 redis]# bin/redis-cli -a 123456 -h ***.***.*.173 -p 7001 info
# Keyspace
db0:keys=4016,expires=0,avg_ttl=0
三節點keys 3988+3996+4014=12000 遷移完成
redis cluster –redis cluster數據遷移
遷移環境如下:
集群模式:
# Redis cluster A主 從
***.***.*.171:7001 ***.***.*.172:7002
***.***.*.172:7001 ***.***.*.173:7002
***.***.*.173:7001 ***.***.*.171:7002# Redis cluster B主 從
***.***.*.171:8001 ***.***.*.172:8002
***.***.*.172:8001 ***.***.*.173:8002
***.***.*.173:8001 ***.***.*.171:8002
對應每個卡槽分配的位置,相對應
Cluster A
Cluster B
查看集群每個節點的狀態
Cluster A
Cluster B
拷貝所有節點數據文件到目標節點
[root@midware-171 redis]# cp data/7001/appendonly.aof …/redis02/data/8001/
[root@midware-171 redis]# cp data/7002/appendonly.aof …/redis02/data/8002/
[root@midware-172 redis]# cp data/7001/appendonly.aof …/redis02/data/8001/
[root@midware-172 redis]# cp data/7002/appendonly.aof …/redis02/data/8002/
[root@midware-173 redis]# cp data/7001/appendonly.aof …/redis02/data/8001/
[root@midware-173 redis]# cp data/7002/appendonly.aof …/redis02/data/8002/
動所有節點如下:
[root@midware-171 redis02]# bin/redis-server conf/redis_8001.conf
[root@midware-171 redis02]# bin/redis-server conf/redis_8002.conf
[root@midware-171 redis02]# ps -ef|grep redis
root 2346 1 0 09:53 ? 00:00:00 bin/redis-server 0.0.0.0:8001 [cluster]
root 2352 1 0 09:53 ? 00:00:00 bin/redis-server 0.0.0.0:8002 [cluster]
同樣啟動 節點2,節點3主從服務
查看所有keys
Cluster A
Cluster B