0.背景
最近参与的一个项目用到了Redis集群。某天一名开发跑过来告诉我他的程序读集群中的从库时,被Redis重定向到其他的节点了,问我有没有办法能够让Redis在读从节点的时候不进行重定向。经过一番思考和搜索,发现了Redis集群中关于从节点读取重定向的问题。记录在这里。
1.MOVED响应
图1
根据Redis官方文档的内容,当一个客户端向集群的某个节点发送请求后,如果该节点持有被请求的数据,Redis将会返回响应的值。如果被请求的数据由另外的节点持有,那么Redis集群将会返回一个 -MOVED响应给客户端,并且指明被请求的数据所在节点的地址与端口。接下来,客户端将向正确的节点再次发送请求。
也就是说,默认情况下只要redis集群被访问的数据不在被访问的节点上,就会发生所谓的重定向,即:集群返回一个带有地址、端口信息的MOVED响应给客户端,客户端根据响应的信息重新请求。
但是,也有不会发生重定向的时候。
2.READONLY与READWRITE
READONLY与READWRITE是一对指令,可以在集群中的从节点上使用这两个指令。READWRTE用来关闭READONLY
图2
根据官方文档的描述,当从节点收到请求时,会默认将客户端重定向到持有被请求数据的主节点上(master 节点)。但是,当我们在从节点上运行READONLY命令后,如果被请求的数据由该从节点的主节点持有,则不会发生重定向。当然,如果被请求的数据不在该从节点的主节点上,及时我们开启了READONLY,重定向依然会发生。
从图3、图4可以看到,我们在172.18.53.4:7001这个主节点上有键“o”,172.18.53.5:7002是该主节点的从节点。
图3
图4
我们切换到172.18.53.5:7002这个实例上。
首先不执行READONLY命令,直接执行get o 命令,从图5可以看到,我们被重定向到了172.18.53.4:7001节点上。
图5
现在回到172.18.53.5:7002上,首先执行READONLY命令,再执行 get o,可以看到,获取到目标的键值对后,我们依然在172.18.53.5:7002上。
图6
现在,我们再看看另外一种情况。
主节点172.18.53.5:7001上有键“olkis”,它的从节点是172.18.53:7002。
图7
图8
我们依然选择在172.18.53.5:7002(避开172.18.53.5:7001的从节点)上执行READONY后再执行get olkis,我们发现,重定向还是发生了。
图9
由此,我们就验证了上文所描述的当从节点开启了READONLY后的重定向行为。赶快在自己喜欢的redis集群上试一试吧。