这个问题断断续续看了起码有一个礼拜,然后测试redis 集群的 HA出现了问题。
观察到的现象:
- 10个master,10个slave, readFrom.ANY
- iptable block slave, 然后观察各个应用的可用性
- 客户端大量的超时,15分钟之后恢复;
我们看了lettuce的配置, 配置了topo 刷新,按倒里,断开 slave 连接之后,topo刷新就会识别到,并移除断开的连接;
我们调研的方向:
- readFrom.ANY, slave 到底有没有下线,于是在本地搭建redis 集群,没有任何问题,slave 在刷新的时候会下线;
- 也就是说topoRefresh 是工作的;slave下线,所有的请求都发给 master;
我们对于 本地测试 和线上测试不一致的问题产生了很多疑问,就是各种推测都是矛盾的,为啥本地就没问题?
https://www.cnblogs.com/hushaojun/p/16285486.html,我们看了这篇文章,结合测试的情况看,关键点还是锁定了 15min自己恢复的这一点上。这个线索太明显了,我们推断就是 线上的环境下, client 没有收到 类似于fin 的包,只能够自己等待底层tcp retries次数过后,也就是15分钟,才识别出来连接断开,然后下线 slave。
在这之前,所有的command 都还是发给了slave,放在了queue里面,由于2s 中没有response就超时;
然后,我们就想本地复现 为啥收不到 fin包,试了很多种方式都不行。甚至看了 iptables的原理,drop 和reject区别;都不行;
最后看到这个帖子,也就是释怀了,估计和环境和硬件有关系,不强求了,
https://github.com/StackExchange/StackExchange.Redis/issues/1848#issuecomment-913064646
能解决问题就行:
https://github.com/lettuce-io/lettuce-core/issues/1428
就是本地client 自己发送心跳或者keepalive,不依赖服务对端网络;
- 一个很奇怪的事:toporefresh 1分钟就能识别到salve连接不可用,为啥不去下线? *
我想它主要还是完全代理给了watchdog,由watchdog处理重新,断开和恢复。 refreshtopo估计能比较好的处理新加节点,remove节点,因为网络抖动的问题,他认为不是 toporefresh。