您的位置:首页 > 数据库 > Redis

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

2016-01-06 16:14 543 查看
最近一直在重写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会报错说找不到指令。
这种错误只会发生在调试阶段,而正式版之所以不会出现这种错误,应该是对主服务器有超时判断。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: