#作者:任少近
文章目录
- 前言
- 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