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 仍然认得, 不会认错, 还是会继续从上一次的断点继续同步.

SSDB 的双主和多主配置

SSDB 数据库是支持双主(双 Master)和多主架构的. 而且, 我们的应用也是部署双主架构, 但当作单主来用. 也就是说, 平时只往其中一个写, 当出现故障时, 整体切换到另一个主上面. 如果应用层已经解决了数据拆分, 也即不会两个节点同时操作一个 key, 那么就可以放心使用双主同时写入.

SSDB 双主的配置非常简单:

#server 1

replication:
	slaveof:
		id: svc_2
		# sync|mirror, default is sync
		type: mirror
		ip: 127.0.0.1
		port: 8889

#server 2

replication:
	slaveof:
		id: svc_1
		# sync|mirror, default is sync
		type: mirror
		ip: 127.0.0.1
		port: 8888

只需要将 type 设置为 mirror, 然后每个节点各指向对方即可.

如果是多主, 则每个节点要指向其它 n-1 个节点.


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值