Pika Binlog结构
Pika的主从同步是使用Binlog来完成的,一主多从的结构master节点也可以给多个slave复用一个Binlog,只不过不同的slave在binglog中有自己的偏移量而已,master执行完一条写命令就将命令追加到Binlog中,ReplicaSender将这条命令从Binlog中读出来发送给slave,slave的ReplicaReceiver收到该命令,执行,并追加到自己的Binlog中,由于主从偏移量一样,所以一旦发生网络或节点故障需要重连主从时,slave仅需要将自己当前的Binlog偏移量发送给master,master找到后从该偏移量开始同步后续命令,理论上将命令不做处理一条一条追加到文件中,如果这样的记录格式容错很差,如果读文件中写错一个字节则导致整个文件不可用,所以pika采用了类似leveldb log的格式来进行存储,具体如下:
在了解了Binlog格式之后,首先给出一个解释pika的主从同步的对象
上图1是一个主从同步的一个过程(即根据主节点数据库的操作日志,将主节点数据库的改变过程顺序的映射到从节点的数据库上),从图1中可以看出,每一个从节点在主节点下都有一个唯一对应的BinlogSenderThread。(为了说明方便,我们定一个“同步命令”的概念,即会改变数据库的命令,如set,hset,lpush等,而get,hget,lindex则不是)
主要模块的功能:
- WorkerThread:接受和处理用户的命令;
- BinlogSenderThread:负责顺序地向对应的从节点发送在需要同步的命令;
- BinlogReceiverModule: 负责接受主节点发送过来的同步命令
- Binglog:用于顺序的记录需要同步的命令
主要的工作过程:
- 当WorkerThread接收到客户端的命令,按照执行顺序,添加到Binlog里;
- BinglogSenderThread判断它所负责的从节点在主节点的Binlog里是否有需要同步的命令,若有则发送给从节点;
- BinglogReceiverModule模块则做以下三件事情:
- 接收主节点的BinlogSenderThread发送过来的同步命令;
- 把接收到的命令应用到本地的数据上;
- 把接收到的命令添加到本地Binlog里至此,一条命令从主节点到从节点的同步过程完成
BinLogReceiverModule的工作过程:
上图2是BinLogReceiverModule(在源代码中没有这个对象,这里是为了说明方便,抽象出来的)的组成,从图2中可以看出BinlogReceiverModule由一个BinlogReceiverThread和多个BinlogBGWorker组成。
- BinlogReceiverThread: 负责接受由主节点传送过来的命令,并分发给各个BinlogBGWorker,若当前的节点是只读状态(不能接受客户端的同步命令),则在这个阶段写Binlog
BinlogBGWorker:负责执行同步命令;若该节点不是只读状态(还能接受客户端的同步命令),则在这个阶段写Binlog(在命令执行之前写)
BinlogReceiverThread接收到一个同步命令后,它会给这个命令赋予一个唯一的序列号(这个序列号是递增的),并把它分发给一个BinlogBGWorker;而各个BinlogBGWorker则会根据各个命令的所对应的序列号的顺序来执行各个命令,这样也就保证了命令执行的顺序和主节点执行的顺序一致了之所以这么设计主要原因是:配备多个BinlogBGWorker是可以提高主从同步的效率,减少主从同步的滞后延迟;
- 让BinlogBGWorker在执行执行之前写Binlog可以提高命令执行的并行度;
- 在当前节点是非只读状态,让BinglogReceiverThread来写Binlog,是为了让Binglog里保存的命令顺序和命令的执行顺序保持一致.
原文: https://github.com/Qihoo360/pika/wiki/pika-%E5%A2%9E%E9%87%8F%E5%90%8C%E6%AD%A5