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会报错说找不到指令。
这种错误只会发生在调试阶段,而正式版之所以不会出现这种错误,应该是对主服务器有超时判断。
错误发生的场景如下:
从服务器不下断点,而主服务器的断点一直卡在,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会报错说找不到指令。
这种错误只会发生在调试阶段,而正式版之所以不会出现这种错误,应该是对主服务器有超时判断。
相关文章推荐
- Redis学习笔记1-Redis数据类型
- ELK日志管理系统
- spring + redis 实现数据的缓存
- spring + redis实现缓存
- redis 下载启动,设置、查询超时时间
- java对redis的基本操作
- Redis之Hash___redis中哈希(Hash)在.net中的运用
- Redis基础之Java散列代码
- redis 可视化管理工具
- redis服务器及采集端设置
- redis中save和bgsave区别
- redis持久化
- Redis: 改变HomeBrew安装的数据库文件目录
- Redis学习笔记
- Redis的安装和使用之一 -----Redis相关运用
- Redis 消息队列运用
- redis持久化
- Redis Cluster原理
- redis3.0搭建分布式集群
- redis持久化rdb和aof