IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    redis slaveof自己会发生什么

    ydzhang发表于 2015-01-14 13:33:44
    love 0

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

    127.0.0.1:6379> set key value
    OK
    127.0.0.1:6379> slaveof 127.0.0.1 6379
    OK
    127.0.0.1:6379> get key
    "value"
    (1.03s)
    127.0.0.1:6379> get key
    "value"
    (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时千万得小心。

    The post redis slaveof自己会发生什么 appeared first on Yun Notes.



沪ICP备19023445号-2号
友情链接