redis 从服务器给主服务器发送ACK时,主服务器长时间不读取socket,则会出现错误。

最近一直在重写redis 源码,在调试时发现一个错误:

错误发生的场景如下:

从服务器不下断点,而主服务器的断点一直卡在,readQueryFromClient函数中的read函数之前。


在这种情况下,从服务器会一直向主服务器发送ACK,直到socket写缓冲区被写满,才停止。而主服务器由于一直被卡在read函数之前,所以socket接收缓冲区(我这缓冲区大小是335KB)的中数据一直没有被读取。这时如果让主服务器执行,它会读取socket接收缓冲区中的数据,而redis默认一次读取16K的数据。

ACK命令的全写是:

*3\r\n$8\r\nREPLCONF\r\n$3\r\nACK\r\n$1\r\n1\r\n

 一共是34个字节,如果接收缓冲区中的数据大于16K时,它在读取最后一条命令时会剩余4个字节没读(34-16*1024/34=4)

如下解释:
在接收缓冲区中的内存内容是这样的:
*3\r\n$8\r\nREPLCONF\r\n$3\r\nACK\r\n$1\r\n1\r\n*3\r\n$8\r\nREPLCONF\r\n$3\r\nACK\r\n$1\r\n1\r\n*3\r\n$8\r\nREPLCONF\r\n$3\r\nACK\r\n$1\r\n1\r\n*3\r\n$8\r\nREPLCONF\r\n$3\r\nACK\r\n$1\r\n1\r\n............*3\r\n$8\r\nREPLCONF\r\n$3\r\nACK\r\n$1\r (到这里是16*1024个字节,后面的会在下次被读) \n1\r\n

而下次读的时候读到\n1\r\n,这对于redis来说是一条错误的命令,所以redis会报错说找不到指令。
这种错误只会发生在调试阶段,而正式版之所以不会出现这种错误,应该是对主服务器有超时判断。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值