Skip to content

Instantly share code, notes, and snippets.

@ideawu
Last active April 23, 2021 02:43
Show Gist options
  • Save ideawu/e16990e1b4a4e429fc5a52dbe3fe3109 to your computer and use it in GitHub Desktop.
Save ideawu/e16990e1b4a4e429fc5a52dbe3fe3109 to your computer and use it in GitHub Desktop.
多写入点数据同步
  • 多个节点组成一个 raft 组
  • 某个组可以作为另一个组的 slave, 从另一组同步 binlog
  • leader 负责从另一个组同步 binlog, followers 从 leader 处同步, 不走 raft
  • 两组 binlog 如何 merge?
@ideawu
Copy link
Author

ideawu commented Feb 27, 2021

  • 多写入点的集群, 每个写入点维护自己的一份数据
  • 可以永久保留多份数据, 读的时候做 merge
  • 也可以指定某个节点是 master, 它所维护的那一份是主干, 其它的数据都是分支
  • 分支需要合并到主干

@ideawu
Copy link
Author

ideawu commented Feb 27, 2021

先考虑两个容器怎么 merge, 再推广到 db.

  • 容器本身有创建时间 ctime, 也即上一次清空容器的时间
  • 容器内的每一个元素都有修改时间 mtime
  • 元素保留 tombstone, 与其它容器的 binlog 对比后, 时间超过即可清理掉

其实就是 k-way binlogs apply, 一共有 k 条日志序列, 其中 1 条序列是本地产生的, 另外的 k-1 条是从别的写入点同步过来的. 如果要达到强一致, 就需要确认了其它 k-1 条之后, 才能 apply 自己的那一条. 但是, 从高可用的角度看, 有时候不需要确定其它 k-1 条, 也必须 apply 自己的那一条.

在网络分区的时候, 也是无法确定其它 k-1 条的, 这时, 不能停止 apply. 先 apply 了, 以后网络恢复之后, 再修复数据.

@ideawu
Copy link
Author

ideawu commented Feb 27, 2021

日志序列有如下属性:

  • clock, 表示已知的这条日志序列的时钟, 当从另的节点同步来一条日志时, 更新这个时钟. 如果对方长时间没有新日志产生, 也应该定期同步一条 noop 日志过来, 以便更新时钟
  • logs, 日志列表

理想的情况下, 每一条日志序列的时钟都能及时更新. 不过, 在网络分区时, 无法得到更新, 这时, 我们不希望系统停止工作, 所以继续工作, 等时钟更新之后, 再修复.

@ideawu
Copy link
Author

ideawu commented Feb 27, 2021

所谓的乱序 apply?

@ideawu
Copy link
Author

ideawu commented Feb 27, 2021

LogEntry { zone_id, index, time, data }

Container { ctime }

Item { mtime }

binlog 遇到 DEL 指令时, 删除数据, 然后从指令时间戳之后开始 apply.

@ideawu
Copy link
Author

ideawu commented Feb 27, 2021

两个极端:

  1. apply 到一个副本, 发现乱序时, rollback
  2. 保留多个副本, 读的时候 merge

好的系统在这两个极端中间.

优化方向:

  • 减小副本的粒度, 例如把 logs 划分成不同的 chunk, 这样 rollback 的成本较小, 或者 merge 的成本较小
  • 减小操作粒度, rollback 时只针对某个 key
  • 尽可能往只有一个副本存在, 在可能的情况下, 消除多副本
  • 读的时候不要读多副本, 即使有多副本存在, 只读一个"主"副本

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment