当前位置:   article > 正文

redis slaveof自己会发生什么

slaveof 自己

向2.8版本redis发送slaveof,将自己变成自己的slave(简称slaveof self)是会返回+OK的,因为响应slaveof命令时,只是设置下master,接下来的同步都是异步进行的。

  1. 127.0.0.1:6379> set key value
  2. OK
  3. 127.0.0.1:6379> slaveof 127.0.0.1 6379
  4. OK
  5. 127.0.0.1:6379> get key
  6. "value"
  7. (1.03s)
  8. 127.0.0.1:6379> get key
  9. "value"
  10. (7.95s)

slaveof self之后,发现redis仍然是可以服务的,但请求响应慢了很多,一个请求通常持续好几秒钟,为什么会这样?

step1. 当redis接收到slaveof后,将masterhost设置为自己,然后返回OK。

step2. redis在后台建立到master的连接,这条连接的两端都是这个redis自身,两端分别称为master、slave

step3. 连接建立后,slave调用syncWithMaster与master建立同步

step4. slave向master异步发送PING,master回复PONG

step5. slave向master同步发送REPLCONF,调用sendSynchronousCommand,这里会阻塞的等待5s,直到超时;而由于redis是单线程,此时请求发送给master(实际上是自己),而master又阻塞在这个请求上,所以最终导致REPLCONF一定会超时,slave日志里会打印

Master does not understand REPLCONF listening-port: -Reading from master: Connection timed out

step6. slave同步发送PSYNC命令给master,同样因为自己正阻塞等待,最后这个请求也一定会超时,日志里会打印

Unexpected reply to PSYNC from master: -Reading from master: Connection timed out

step7. slave将读事件处理handler设置为readSyncBulkPayload(6超时,slave上认为没有错误,个人觉得这里的实现是有问题的),然后进入下一次事件循环,此时redis作为master收到了5、6里自己发出的请求,回复了+OK;读事件接下来会触发slave执行readSyncBulkPayload,从master读取rdb文件的长度,而实际读到的是+OK,于是认为协议错了,就关闭了到master的连接,日志里会打印

protocol from MASTER, the first byte is not '$' (we received '+OK'), are you sure the host and port are right?

redis会不断重复1-7的步骤,当接受到正常的请求时,如果redis刚好阻塞在同步发送REPLCONF、PSYNC(两个超时各5s,共10s)的过程中,则需要等待这些请求超时,redis下一次进入事件循环才处理请求,所以用户看到redis的请求延时很大(0-10s不等)。

slaveof self会使redis进入循环尝试主备同步的状态,对服务影响非常大,所以运维redis时千万得小心。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/586199
推荐阅读
相关标签
  

闽ICP备14008679号