0
0

SSDB源码分析 – 主从和多主同步原理解析

ideawu 发表于 2014年12月02日 20:02 | Hits: 2750
Tag: SSDB

SSDB 的主从同步策略非常简单, 就是把主(Master)上的所有写操作(Binlogs), 在从(Slave)上再执行一遍. MySQL 的主从同步也是一样. 而多主可以理解为互为主从.

把 Master 上的所有操作(Binlogs)在 Slave 上执行一遍, 说来很简单, 但还是会遇到一些难题, 例如 Binlogs 不可能无限地永久保留. SSDB 只保留最新的 1000 万次写操作. 对于熟悉 MySQL 的同学可能也知道这样的例子: 在有 Binlogs 之前, 数据库内已经有了一部分数据. 也就是说, 这部分数据是无法通过 Binlog 来获得的.

为此, 要有一个基础数据的拷贝(Copy)过程. 对于 MySQL 来说, 必须由 DBA 手动拷贝. 而对于 SSDB 来说, 这是自动的.

COPY 状态

因为 Copy 过程不是立即完成的, 所以如何处理 Copy 过程中的新的 Binlog 又成为一个问题. 当然, 问题也很容易解决. 不过, 在解决之前, 要先了解 SSDB 的 Copy 过程.

SSDB 数据库中的所有数据都是排好序的, 所以你可以把整个数据库理解为一个链表, SSDB 从表头开始 Copy, 一次一个节点, 游标一直往后. 这时, 如果有新的 Binlog, SSDB 会先判断这条 Binlog 对应的节点在链表中的什么位置, 是在游标的前面还是后面?

如果在游标的前面, 那么会把这条 Binlog 发给 Slave 执行. 如果在游标的后面, 就会直接忽略掉, 因为游标最终会移动到更新的位置. 从这个描述也可以知道, 处于 Copy 阶段的 Slave, 有可能无法立即知道 Master 上的更新.

当游标移动到了链表的末端之后, Copy 过程就结束了, 主从同步流程进入到 Sync 阶段, 也就是即时(毫秒级)更新阶段.

SYNC 状态

Sync 其实非常简单, 就是 Master 每收到一条写指令, 就把这条指令发给 Slave 执行.

Master 会把 Binlog 进行编号(序号), 所以, Slave 在重启之后是可以断点续传的. 因为有序号的原因, Master 上就可以看到 Binlog 最大序号(用 ssdb-cli 执行 info 命令可以看到binlogs.max_seq):

binlogs
        capacity : 10000000
        min_seq  : 113033
        max_seq  : 113055

而在 Slave 上, 就能看到当前已经收到的 Binlog 的序号(replication.slaveof.last_seq).

replication
    slaveof 127.0.0.1:8888
        id         : svc_2
        type       : sync
        status     : INIT
        last_seq   : 113055
        copy_count : 0
        sync_count : 0

Master 上的binlogs.max_seq应该和 Slave 上的replication.slaveof.last_seq相等, 不然说明有一部分更新还没有来得及同步.注意: 这两个数据是在不同的服务器上获取的!

如果在 Master 上用 info 命令查看, 你还会看到这样的信息:

replication
    client 127.0.0.1:55158
        type     : sync
        status   : SYNC
        last_seq : 113055

这是从 Master 的角度看, 当前连接上来的 Slave 的信息,replication.client.last_seq一般是和replication.slave.last_seq是相等的.注意, 这两个数据是在不同的服务器上获取的!

关于 slaveof.type 同步的类型

  • 对于主从同步, Slave 上的 ssdb.conf 中的slaveof.type必须配置成 sync.
  • 对于双主或者多主, 所有的服务器的 ssdb.conf 都必须将slaveof.type配置成 mirror!

对于双主或者多主, 如果不配置成 mirror 会出现什么情况? 那就是死循环! 一条 Binlog 会在所有服务器上不停地来回传递放大.

关于 slaveof.id

你必须知道, SSDB 节点是不知道自己的 ID 的, 你没法配置节点的 ID.

至于配置文件中的replication.slaveof.id, 假设是在服务器 B 上的配置, B 想从 A 同步数据, 是指 B 认为它所连接的 A 的名字叫 id, 至于 A 叫什么(A 其实没有名字), 这没关系.

事实上, 这个 id 是为了标识一个数据库, 而不是一台机器, 无论这个库你把它拷贝到哪台机器上跑都没关系. B 只认这个库, 即使你把它迁移到了另一台机器, B 仍然认得, 不会认错, 还是会继续从上一次的断点继续同步.

Related posts:

  1. SSDB 的双主和多主配置
  2. MySQL 在线增加从库
  3. MySQL 数据库双主配置
  4. SSDB 配置文件
  5. SSDB源码分析 – 服务器的启动过程

原文链接: http://www.ideawu.net/blog/archives/849.html

0     0

我要给这篇文章打分:

可以不填写评论, 而只是打分. 如果发表评论, 你可以给的分值是-5到+5, 否则, 你只能评-1, +1两种分数. 你的评论可能需要审核.

评价列表(0)