前言
Redis是一个开源的高性能键值对数据库。它通过提供多种键值数据类型来适应不同场景下的存储需求,并借助许多高层级的接口使其可以胜任如缓存、队列系统等不同的角色。
Redis持久化了解
为了让性能更加优异,Redis默认是把所有的数据都存在内存中的。但是当服务器重启或程序异常崩溃时,Redis的数据就会全部丢失。因此出现了持久化的概念。持久化就是将存在内存中的数据同步到磁盘来保证持久化。

1、Redis持久化的方式
两种: RDB 和 AOF
RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot)。
AOF 持久化记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。 AOF 文件中的命令全部以 Redis 协议的格式来保存,新命令会被追加到文件的末尾。 Redis 还可以在后台对 AOF 文件进行重写(rewrite),使得 AOF 文件的体积不会超出保存数据集状态所需的实际大小。
2、持久化的数据有什么用?
用于重启后的数据恢复。Redis是一个内存数据库,无论是RDB还是AOF,都只是其保证数据恢复的措施;所以Redis在利用RDB和AOF进行恢复的时候,都会读取RDB或AOF文件,重新加载到内存中。
默认持久化了解
其中RDB就是point-in-time snapshot快照存储,也是默认的持久化方式。对于RDB可理解为半持久化模式,即按照一定的策略周期性的将数据保存到磁盘。对应产生的数据文件为dump.rdb,通过配置文件中的save参数来定义快照的周期。Redis的RDB文件不会坏掉,因为其写操作是在一个新进程中进行的。

一、准备工作

默认的持久化设置:

save 900 1                          #当有一条Keys数据被改变时,900秒刷新到Disk一次
save 300 10                        #当有10条Keys数据被改变时,300秒刷新到Disk一次
save 60 10000                    #当有10000条Keys数据被改变时,60秒刷新到Disk一次

利用持久化迁移数据,下面操作在所有主节点执行
##########查看配置信息及当前存储的key值###########
[root@localhost ~]# redis-cli -c -h 10.10.10.10 -p 6379

#########保存最新的key值################
redis 10.10.10.10:6379> BGSAVE
Background saving started
##########查看是否保存成功##############
redis 10.10.10.10:6379> LASTSAVE
(integer) 1420367903

Redis–BGSAVE
在后台异步(Asynchronously)保存当前数据库的数据到磁盘。BGSAVE 命令执行之后立即返回 OK ,然后 Redis fork 出一个新子进程,原来的 Redis 进程(父进程)继续处理客户端请求,而子进程则负责将数据保存到磁盘,然后退出。
LASTSAVE
返回最近一次 Redis 成功将数据保存到磁盘上的时间,以 UNIX 时间戳格式表示。

转换Unix时间戳的网址
http://tool.chinaz.com/Tools/unixtime.aspx

二、安装部署redis-migrate-tool

官方链接:https://github.com/vipshop/redis-migrate-tool
软件编译安装:

mkdir /opt/cachecloud/  && cd /opt/cachecloud/
wget https://github.com/vipshop/redis-migrate-tool/archive/master.zip
unzip master.zip
mv redis-migrate-tool-master redis-migrate-tool
cd redis-migrate-tool
mkdir data
autoreconf -fvi
./configure
make
src/redis-migrate-tool -h

三、配置启动redis-migrate-tool

3.1)配置文件实例:
vim /opt/cachecloud/redis-migrate-tool/rmt.conf

示例1:从rdb文件恢复数据到redis cluster集群

[source]
type: rdb file
servers:
 - /data/redis/dump1.rdb
 - /data/redis/dump2.rdb
 - /data/redis/dump3.rdb

[target]
type: redis cluster
servers:
 - 127.0.0.1:7379

[common]
listen: 0.0.0.0:8888

示例2:从redis cluster集群迁移数据到另外一个cluster集群

[source]
type: redis cluster
servers:
- 127.0.0.1:8379

[target]
type: redis cluster
servers:
- 127.0.0.1:7379

[common]
listen: 0.0.0.0:8888

示例3:从redis cluster集群迁移数据到twemproxy集群

[source]
type: redis cluster
servers:
- 127.0.0.1:6379

[target]
type: twemproxy
hash: fnv1a_64
hash_tag: "{}"
distribution: ketama
servers:
- 127.0.0.1:6380:1 server1
- 127.0.0.1:6381:1 server2
- 127.0.0.1:6382:1 server3
- 127.0.0.1:6383:1 server4

[common]
listen: 0.0.0.0:34345
threads: 8
step: 1
mbuf_size: 512
source_safe: true

3.2)软件运行:

cd /opt/cachecloud/redis-migrate-tool
src/redis-migrate-tool -c rmt.conf -o log -d

3.3)状态查看:通过redis-cli连接redis-migrate-tool监控的端口,运行info命令

$redis-cli -h 127.0.0.1 -p 8888
127.0.0.1:8888> info
# Server
version:0.1.0
os:Linux 2.6.32-573.12.1.el6.x86_64 x86_64
multiplexing_api:epoll
gcc_version:4.4.7
process_id:9199
tcp_port:8888
uptime_in_seconds:1662
uptime_in_days:0
config_file:/ect/rmt.conf

# Clients
connected_clients:1
max_clients_limit:100
total_connections_received:3

# Memory
mem_allocator:jemalloc-4.0.4

# Group
source_nodes_count:32
target_nodes_count:48

# Stats
all_rdb_received:1
all_rdb_parsed:1
rdb_received_count:32
rdb_parsed_count:32
total_msgs_recv:7753587
total_msgs_sent:7753587
total_net_input_bytes:234636318
total_net_output_bytes:255384129
total_net_input_bytes_human:223.77M
total_net_output_bytes_human:243.55M
total_mbufs_inqueue:0
total_msgs_outqueue:0
127.0.0.1:8888>

3.4)数据校验:

$src/redis-migrate-tool -c rmt.conf -o log -C redis_check
Check job is running...

Checked keys: 1000
Inconsistent value keys: 0
Inconsistent expire keys : 0
Other check error keys: 0
Checked OK keys: 1000

All keys checked OK!
Check job finished, used 1.041s

附加工具:redis-port

安装go:

wget https://dl.google.com/go/go1.7.5.linux-amd64.tar.gz
tar zxvf go1.7.5.linux-amd64.tar.gz
mv go /usr/local/
mkdir $HOME/work
echo 'export GOROOT=/usr/local/go' >>/etc/profile 
echo 'export PATH=$PATH:$GOROOT/bin' >>/etc/profile
echo 'export GOPATH=$HOME/work' >>/etc/profile
source /etc/profile
# go version
go version go1.7.5 linux/amd64

下载 redis-port

redis-port地址
使用示例1

./redis-port  restore  --input=x/dump.rdb  --target=dst_host:dst_port   --auth=dst_password  
[--filterkey="str1|str2|str3"] [--targetdb=DB] [--rewrite] [--bigkeysize=SIZE] [--logfile=REDISPORT.LOG]
参数说明

x/dump.rdb : 自建 redis 的 dump 文件路径
dst_host : 目的数据库 redis 域名
dst_port : 目的数据库 redis 端口
dst_password : 目的数据库 redis 密码
str1|str2|str3 : 过滤具有 str1 或 str2 或 str3 的 key
DB : 将要同步入目的数据库 redis 的 DB
rewrite : 覆盖已经写入的 key
bigkeysize=SIZE : 当写入的 value 大于 SIZE 时,走大 key 写入模式

根据 redis-port 日志查看数据同步状态

根据redis-port日志查看同步状态
Redis Cluster在线迁移

当出现restore: rdb done时数据同步完成。

使用示例2

./redis-port  sync  --from=src_host:src_port --password=src_password  --target=dst_host:dst_port   
--auth=dst_password  [--filterkey="str1|str2|str3"] [--targetdb=DB] [--rewrite] [--bigkeysize=SIZE] 
[--logfile=REDISPORT.LOG]
参数说明

src_host : 自建 redis 域名(或者 IP)
src_port : 自建 redis 端口
src_password : 自建 redis 密码
dst_host : 目的数据库 redis 域名
dst_port : 目的数据库 redis 端口
dst_password : 目的数据库 redis 密码
str1|str2|str3 : 过滤具有 str1 或 str2 或 str3 的 key
DB : 将同步入目的 redis 的 DB
rewrite : 覆盖已经写入的 key
bigkeysize=SIZE : 当写入的 value 大于 SIZE 时,走大 key 写入模式

根据 redis-port 日志查看数据同步状态
Redis Cluster在线迁移

根据redis-port日志查看同步状态当出现sync rdb done时全量同步完成,进入增量同步的模式。