问题:
服务上云过程中遇见跨机房服务调用问题导致QPS下降,方法耗时增加
分析:
redis是个缓存服务 自己的损耗不应该被网络时延影响
解决:
采用阿里开源组件:RedisShake
之前也有redis-migrate-tool,但是这个不适合做实时数据同步,其他的那些迁移工具如:redis-port、redis-migration缺少维护社区不活跃,这个阿里云的redis-shake“烛昭”挺热心的
还支持prometheus监控:
准备:
1.阿里云的redis集群申请创建(费用一个月3000元左右)
2.阿里云的redis集群申请自带密码,redis为了追求高性能一般不建议使用密码(设置为免密访问)
3.阿里云的redis集群是高可用,连接方式是代理模式的
4.阿里云的redis集群有白名单限制
5.准备一台能够连接源redis集群和目标redis集群的机器
6.下载redis-shake,开始同步
操作记录:
1.修改配置文件(只修改source和target部分)redis-shake.conf:
source.type = cluster``source.address = 涉密隐藏``source.password_raw =``source.auth_type = auth``source.tls_enable = ``false``source.rdb.input = local``source.rdb.parallel = ``0``source.rdb.special_cloud = target.type = proxy``target.address = 涉密隐藏``target.password_raw =``target.auth_type = auth``target.db = -``1``target.tls_enable = ``false``target.rdb.output = local_dump``target.version = |
|---|
配置打印
展开源码
2.启动脚本:
nohup ./redis-shake.linux -conf=redis-shake.conf -type=sync 1>>redis-shake.output 2>&1 &
已经封装在start.sh脚本中:
#!/usr/bin/env bash
catalog=$(dirname "$0")
cd "${catalog}" || exit 1
if [ $# != 2 ] ; then
echo "USAGE: $0 [conf] [mode]"
exit 0
fi
name="redis-shake"
if [ "Linux" != "$(uname -s)" ];then
printf "\\nWARNING !!! MacOs doesn't supply to use this script, please use \"./%s -conf=config_file_name\" manual command to run\\n" "$name"
exit 1
fi
nohup ./$name.linux -conf=$1 -type=$2 1>>$name.output 2>&1 &
3.查看监控:
http://涉密隐藏:9320/conf 查看配置
http://涉密隐藏:9320/metric 同步过程监控
http://涉密隐藏:9320/metrics Prometheus监控
4.日志(截取重要部分):
# 第一部分检查redis-shake配置config
# 第二部分开始进行模拟slave节点挂载,发送psync命令数据同步,记录offset位置
# 第三部分等待源端save rdb完毕
# 第四部分全量同步阶段,显示百分比
# 第五部分增量同步,出现字样sync rdb done后,当前dbSyncer进入增量同步
展开源码
日志中提示错误内容请按照提示修改:见FAQ
5.监控:
| 示例图 | 参数解释 |
|---|---|
涉密隐藏 | * StartTime: 进程启动时间 |
- PullCmdCount: 增量阶段,1秒内从源端拉取的命令个数
- PullCmdCountTotal: 启动至今,增量阶段,从源端拉取的命令总个数
- BypassCmdCount: 增量阶段,1秒内从源端拉取后过滤的个数
- BypassCmdCountTotal: BypassCmdCount总的计数
- PushCmdCount: 增量阶段,1秒内尝试写目的端的个数
- PushCmdCountTotal: PushCmdCount总的计数
- SuccessCmdCount: 增量阶段,1秒内成功写入目的端的命令个数
- SuccessCmdCountTotal: SuccessCmdCount总的计数
- FailCmdCount: 增量阶段,1秒内成功写入目的端的失败个数
- FailCmdCountTotal: FailCmdCount总的计数
- Delay: 增量阶段1秒内的延迟
- AvgDelay: 平均延迟
- NetworkSpeed: 1s内的网络流程
- NetworkFlowTotal: NetworkSpeed总的计数
- FullSyncProgress: 全量同步百分比进度,如果全量结束则为100
- Status: 当前同步阶段,full表示全量,incr表示增量
- SenderBufCount: 内部发送队列长度,通常不需要关心
- ProcessingCmdCount: 当前处理的个数
- TargetDBOffset: 目的端的offset
- SourceDBOffset: 源端的offset
- SourceAddress: 源端地址
- TargetAddress: 目的端地址
- Details: 存储一些额外信息 |
复盘分析:
1.psync RDB文件花费了多少时间?
在当前网络情况下同步4个RDB文件花费了40s
| 时间戳 | 动作 |
|---|---|
| 2020/03/30 18:15:21 | starts syncing data from XXX |
| 2020/03/30 18:15:21 | try to send 'psync' command |
| 2020/03/30 18:15:21 | Event:FullSyncStart |
| 2020/03/30 18:15:22 | dbSyncer 等待源端save rdb完毕 |
| 2020/03/30 18:16:01 | Aux information key RDB同步完毕 |
2.restore RDB文件花费了多少时间?
当前环境下最长花费了:37:50(共5.78G,4个线程4个节点)
分别耗时:35:40、36:18、36:54、37:50
| 时间戳 | 动作 |
|---|---|
| 2020/03/30 18:16:05 | dbSyncer[X] total = 1.044GB - 2.926MB [ 0%] entry=40499 |
| 2020/03/30 18:51:45 | dbSyncer[3] total = 1.044GB - 1.044GB [100%] entry=15173086sync rdb done |
| 2020/03/30 18:52:23 | dbSyncer[0] total = 1.044GB - 1.044GB [100%] entry=15170878sync rdb done |
| 2020/03/30 18:52:59 | dbSyncer[1] total = 1.044GB - 1.044GB [100%] entry=15170987sync rdb done |
| 2020/03/30 18:53:55 | dbSyncer[2] total = 1.044GB - 1.044GB [100%] entry=15173086sync rdb done |
3.增量同步平均耗时?
通过metric指标可以看出:平均延迟2.16 ms(后面通过redis-full-check校验一致性,校验完全正确这里有个疑问可能是我QPS过低造成的)
+forwardCommands=0 +filterCommands=0 +writeBytes=0
其中forwardCommands表示发送的命令个数,filterCommands表示过滤的命令个数,比如opinfo或者指定了filter都会被过滤,writeBytes表示发送的字节数。
| 时间戳 | 动作 |
|---|---|
| 2020/03/30 18:51:45 | dbSyncer[3] FlushEvent:IncrSyncStart Id:redis-shake |
| 2020/03/30 18:52:23 | dbSyncer[0] FlushEvent:IncrSyncStart Id:redis-shake |
| 2020/03/30 18:52:59 | dbSyncer[1] FlushEvent:IncrSyncStart Id:redis-shake |
| 2020/03/30 18:53:55 | dbSyncer[2] FlushEvent:IncrSyncStart Id:redis-shake |
注意事项:
1.尽量同步的source数据源不要有lua脚本
2.尽量不要有事务
3.尽量不要低版本往高版本同步
详细原因见FAQ,本实验中只是个同构redis4集群的同步
FAQ: