1. redis 集群的扩容与收缩,最经典的需求
2. 数据异构同步,从 redis 到 mysql等等
3. redis 原有集群的拆分,按业务线打散成多个集群
4. redis 当前内存使用,key占比分析
5. 无用数据的检测和清除
6. 对于 rdb 文件的备份
redis-port原理
简单来说,就是把自已伪装成 slave, 欺骗master来达到数据流同步的目地。
发送sync命令->接收rdb->解析rdb->过滤->回放rdb->回放master推送的同步数据。
1. 支持 psync,例如 --psync 。
2. 从 master 获取 rdb+backlog 速度过慢,可导致 master 主动关闭连接。可以结合 --sockfile=buffer.tmp --filesize=64GB 参数,这样能使用一个最大 64GB 的文件作为缓冲(循环写,自动释放),能加速 rdb+backlog 的获取,口味更佳。
3. 向 slave restore 的速度,可以通过增加 CPU 以及增加并发连接数实现,分别是 --ncpu=4 --paralle=32。
4. 其实,使用 psync 的话,port 和 master 之间就有 position 的概念了,可以减少同步失败的发生情况,redis-port 会自动重试直到不能。
注意事项
1. 同步时有两个 redis 参数需要注意。
repl-backlog-size
同步buffer的大小,默认1mb,根据当前数据量大小适当调整,比如10mb。
client-output-buffer-limit
client slave 级别的buffer也要调整,比如 client-output-buffer-limit slave 256mb 128mb 60 。
2. restore 操作只要目标集群存在指定Key,就会fatal,如果没问题可以在代码中去掉err检测。
3. 使用伪装slave的机制,redis-port一定要轮流同步,同时bgsave可不好玩。
4. 代码修改成通用的工具,每次改代码逻辑容易出问题,from和target一定要确认好。
5. 同步时由于源数据量太大,可能工具会中断,调整redis-port并发数和redis上面提到的两个buffer就好。
安装
1、安装redis-port
# go get github.com/CodisLabs/redis-port/releases
默认会下载在/usr/local/src/github.com/CodisLabs下,或者可以在github.com上下载redis-port的新版本。
安装依赖
# go get github.com/cupcake/rdb
将下载的版本解压重命名为redis-port后,放到codis安装的同级目录下,例如我的codis安装在
/usr/local/go/src/github.com/CodisLabs,那么将redis-port放到这个目录下即可。
# cd /usr/local/go/src/github.com/CodisLabs/redis-port/
# make
# ll /usr/local/go/src/github.com/CodisLabs/redis-port/bin/
total 4920
-rwxr-xr-x. 1 root root 5037040 May 12 11:08 redis-port
redis-port参数说明:
-n N, --ncpu=N
set runtime.GOMAXPROCS to N
-p M, --parallel=M
set number of parallel routines
-i INPUT, --input=INPUT
use INPUT as input file, or if it is not given, redis-port reads from stdin (means '/dev/stdin')
-o OUTPUT, --output=OUTPUT
use OUTPUT as output file, or if it is not given, redis-port writes to stdout (means '/dev/stdout')
-m MASTER, --master=MASTER
specify the master redis
-t TARGET, --target=TARGET
specify the slave redis (or target redis)
-P PASSWORD, --password=PASSWORD
specify the redis auth password
-A AUTH, --auth=AUTH
specify the auth password for target
-e, --extra
dump or restore following redis backlog commands
--redis
target is normal redis instance, default value is false
--codis
target is codis proxy, default value is true
--filterdb=DB
filter specifed db number, default value is '*'
DECODE dumped payload to human readable format (hex-encoding)
redis-port decode [--ncpu=N] [--parallel=M] [--input=INPUT] [--output=OUTPUT]
RESTORE rdb file to target redis
redis-port restore [--ncpu=N] [--parallel=M] [--input=INPUT] --target=TARGET [--codis|--redis] [--auth=AUTH] [--extra] [--faketime=FAKETIME] [--filterdb=DB]
DUMP rdb file from master redis
redis-port dump [--ncpu=N] [--parallel=M] --from=MASTER [--password=PASSWORD] [--output=OUTPUT] [--extra]
SYNC data from master to slave
redis-port sync [--ncpu=N] [--parallel=M] --from=MASTER [--password=PASSWORD] [--psync]
[--filterdb=DB] --target=TARGET [--auth=AUTH] [--codis|--redis] [--sockfile=FILE [--filesize=SIZE]]
2、使用redis-port
1)同步原生redis 192.168.34.6:7000 到codis 192.168.34.6:19000,目标是 codis-proxy。
# ./redis-port sync --from=192.168.34.6:7000 --codis --target=192.168.34.6:19000 -n 1
2015/05/12 17:54:11 [INFO] set ncpu = 1, parallel = 1
2015/05/12 17:54:11 [INFO] sync from '192.168.34.6:7000' to '192.168.34.6:19000'
2015/05/12 17:54:11 [INFO] rdb file = 345
2015/05/12 17:54:11 [INFO] total=345 - 345 [100%] entry=38
2015/05/12 17:54:11 [INFO] sync rdb done
2015/05/12 17:54:12 [INFO] sync: +forward=0 +nbypass=0 +nbytes=0
2015/05/12 17:54:13 [INFO] sync: +forward=0 +nbypass=0 +nbytes=0
2015/05/12 17:54:14 [INFO] sync: +forward=0 +nbypass=0 +nbytes=14
2)使用redis-port decode redis/codis rdb文件。
# cat /test/dump.rdb |./redis-port decode 2> /dev/null
{"db":0,"type":"string","key":"a","value":"hello"}
{"db":1,"type":"string","key":"a","value":"9"}
{"db":0,"type":"hash","key":"c","field":"hello","value":"world"}
{"db":0,"type":"expire","key":"c","expireat":1487663341422}
{"db":0,"type":"list","key":"b","index":0,"value":"hello"}
{"db":0,"type":"list","key":"b","index":1,"value":"world"}
将rdb文件decode到文件中。
# cat dump99.rdb |./redis-port decode -o save99.log -n 1 2> /dev/null
3)使用redis-port restore rdb文件到codis。
# ./redis-port restore -i dump.rdb --codis --target=192.168.34.6:19000 -n 1
2015/05/13 12:01:29 [INFO] set ncpu = 1, parallel = 1
2015/05/13 12:01:29 [INFO] restore from '/test/dump.rdb' to '192.168.34.6:19000'
2015/05/13 12:01:29 [INFO] total = 363 - 363 [100%] entry=40
2015/05/13 12:01:29 [INFO] restore: rdb done
将redis实例中的rdb文件转成其他格式文件。
#./redis-port dump -f 192.168.34.6:7000 | tee save.rdb | ./redis-port decode -o save.log -n 8 2>/dev/null
2017/02/22 14:30:17 main.go:178: [INFO] set ncpu = 1, parallel = 1
2017/02/22 14:30:17 dump.go:29: [INFO] dump from '192.168.34.6:7000' to '/dev/stdout'
2017/02/22 14:30:17 main.go:178: [INFO] set ncpu = 1, parallel = 1
2017/02/22 14:30:17 decode.go:45: [INFO] decode from '/dev/stdin' to 'save.log'
2017/02/22 14:30:17 dump.go:42: [INFO] rdb file = 147
2017/02/22 14:30:17 dump.go:94: [INFO] total = 147 - 147 [100%]
2017/02/22 14:30:17 dump.go:96: [INFO] dump: rdb done
2017/02/22 14:30:17 decode.go:114: [INFO] decode: total = 147 write=325 entry=5
2017/02/22 14:30:17 decode.go:116: [INFO] decode: done
4)使用redis-port dump codis-server生成rdb 文件。
# ./redis-port dump -f 192.168.34.6:6379 -o dump88.rdb
2015/05/13 12:10:58 [INFO] set ncpu = 1, parallel = 1
2015/05/13 12:10:58 [INFO] dump from '192.168.34.6:6379' to 'dump88.rdb'
2015/05/13 12:10:58 [INFO] rdb file = 363
2015/05/13 12:10:58 [INFO] total = 363 - 363 [100%]
2015/05/13 12:10:58 [INFO] dump: rdb done
参考:
https://github.com/wandoulabs/redis-port
欢迎加入343595434Codis技术交流群,一起解决问题!