codis迁移引发的问题

首先介绍下codis的迁移:
codis将所有的数据预分配为1024个slot,做一次典型的数据迁移,其最小单位就是一个slot,其流程大致是这样的(以下文字主要来自Codis作者huangdongxu的博客):

由dashboard通过ZK向所有proxy下发一个pre_migrate命令,如pre_migrate slot_1 to group 2.
当所有proxy都收到并且回复了pre_migrate命令时,标记slot_1的状态为 migrate,服务该slot的server group改为group2, 同时codis-config向group1的redis机器不断发送 SLOTSMGRT 命令, target参数是group2的机器, 直到group1中没有剩余的属于slot_1的key.
迁移过程中, 如果客户端请求 slot_1 的 key 数据, proxy 会将请求转发到group2上, proxy会先在group1上强行执行一次 MIGRATE key 将这个键值提前迁移过来. 然后再到group2上正常读取
迁移完成, 标记slot_1状态为online

这是一个典型的两阶段提交的流程,首先通知所有的proxy准备迁移了,然后再开始数据的迁移.需要注意的问题是,此时的选择了怎样的数据一致性模型以及如何保证这一点的?

Codis使用的是强一致性的数据模型,而不是类似Dynamo那样的当发现有不一致的数据都返回给使用者由使用者来解决冲突的方式.具体策略是:

在pre_migrate阶段,proxy如果收到这个slot的请求,会block住直到migrate状态了才开始处理.
在migrate阶段,如果新的处理该slot的proxy接收到了该slot的请求,首先会同步一份该slot的数据过来,再返回给客户端.

可以看到,无论哪个阶段,只要处理到了正在处理的slot,这样的处理都势必造成请求的处理变慢,整个服务的可用性降低,这也是没有办法的事情,具体看业务而定,是否需要更看重可用性还是一致性了。

现象:
此次测试迁移是由dashboard发起的,在迁移过程中一个slot的status一直处于migrate状态,在等待一段时间后发现程序无法通过proxy读取数据,而此时dashboard中proxy都处于online状态,看似无异常。

日志排查:
查看dashboard日志报错:

[error] read tcp 10.10.80.11:6380: i/o timeout 
[error] read tcp 10.10.80.11:6380: connection reset by peer 

查看10.10.80.11的redis日志报错:

slotsmgrt: connect to target 10.10.80.10:6380
[30551] 11 Oct 11:59:35.755 # slotsmgrt: writing to target 10.10.80.10:6380, error 'accept: Resource temporarily unavailable', nkeys = 1, onekey = 'api_assess_records', cmd.len = 2964714399, pos = 0, towrite = 65536
[30551] 11 Oct 11:59:36.235 # slotsmgrt: close target 10.10.80.10:6380

根据redis日志报错,查看10的redis本地登陆及远程登陆一切正常,根据codis github中的issue说此问题是由于target中的codis-server无法连接导致,但是经检查一切正常,暂时没有找到原因。

将10.10.80.10的codis-server进行重启,状态仍然处于migrate。
在dashboard中将proxy重新启动重新上线,此时报错:

slot {
"product_name": "codis",
"id": 976,
"group_id": 3,
"state": {
"status": "pre_migrate",
"migrate_status": {
"from": 4,
"to": 3
},
"last_op_ts": "0"
}
} is not online

提示slot此时仍处于pre_migrate状态
查看dashboard日志报错:

[error] Some proxies may not stop cleanly

从上面介绍的迁移流程“dashboard通过ZK向所有proxy下发一个pre_migrate命令,当所有proxy都收到并且回复了pre_migrate命令时,标记slot_1的状态为 migrate”,从此处理解应该是proxy杀掉重新online时,zk对应的proxy节点没有进行更改,因此会导致无法online。这是我个人结合github中的issue理解,不知对不对。

由于这种情况一直持续,暂时不能解决,而dashboard发起的迁移无法停止,因此在测试中将slot 强制init,然后在重新分配,才能够重新上线继续运行。

总结:
codis虽然号称通过codis-config 管理工具, 支持包括, 添加/删除 Redis 节点, 添加/删除 Proxy 节点, 发起数据迁移等操作,但是在操作过程中总是会产生异常问题,这些个问题有时通过在官方github上留言能够解决,但是这种方式很耗时,如果放到生产环境中则为时已晚。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值