replication的代码还没完全看完,先记录看到的一些东西:
1、master/slave之间的同步有两种方式,一种full sync,一种partial sync
2、full sync也有两种实现方式:
1). socket target,就是将rdb的内容通过socket回复给执行sync命令的slave
2). disk target,就是master这端先在后台执行bgsave的过程生成rdb file,执行完成之后,再将rdb file的内容回复给slave
从上面两种方式的实现可以看出一点区别:
比如,master收到一条sync命令,如果master正在执行socket target的bgsave工作,那么这个新的sync命令必须等到当前socket target的bgsave做完,才能开始新一轮的bgsave工作。
但是,如果master正在执行的是disk target的bgsave工作,那么这个新的sync命令有可能(还有一个capability的因素在里面)可以直接利用这一轮bgsave得到的rdb file返回给slave。
3、partial sync的实现方式大致是这样:当server第一次收到sync/psync命令时,server会新分配一个repl_backlog的buf(这块buf的大小可以配置),一个随机的串做为replid。
第一个psync的命令是当做full sync来做的。后面在一些特定的时候会往这个buf里面写入内容(可能是一些完整的命令)。client执行psync的时候会带上相应的偏移,server就把repl_buf
中指定偏移开始的所有内容回复给client
4、对于full sync,不管是disk target还是socket target,在执行完bgsave之后,都会调用updateSlavesWaitingBgsave去查看是否需要开启新的bgsave流程
5、当redis实例的repl_state被设置为REDIS_REPL_CONNECT时,在replicationCron中就会调用connectWithMaster进入sync的过程。sync的过程大致分为两个步骤:handshake和sync。handshake的状态转换在syncWithMaster中可以很清楚地看到;
handshake的最后会进入slaveTryPartialResynchronization,尝试与master进行psync,如果master回复的是+CONTINUE则进入psync的过程,如果master回复的是+FULLRESYNC则进入full sync的过程。
6、slave在handshake中会内部维护一个状态机:CONNECT, CONNECTING, PING, PONG, AUTH, PORT, AUTH, PSYNC,但是master端不会维护相应的状态,只会处理对应的命令。
几个问题:
1、多个客户端同时执行sync的话,server上的执行流程是怎么样的?
2、MULTI里面能执行sync命令吗?