TIDB 对于Percolator 在分布式事务提交方面优化 Async Commit
Percolator 是谷歌在2010发表的论文«Large-scale Incremental Processing Using Distributed Transactions and Notifications» 介绍的分布式事务协议。TIDB 很多的理论都是基于 GOOGLE的一些白皮书的. 分布式事务TIDB 也是借鉴了 google 的 percolator的论文并进行了改进,提高了性能.
首先我们先对percolator的一些概念进行理解,然后在看TIDB 对于这些理论改进的部分.
1 获取TSO 用时间戳作为 start_ts
1 事务在提交需要缓存在client端, percolator 的事务提交分为 perwrite 和 commited
2 事务开启会获取TSO 事务号, TSO 是通过时间戳标识的,事务开启时获取的时间戳是 start_ts
3 Perwrite 过程
3.1 获取TSO 用时间戳作为 start_ts
3.2 选择一个写入点为主节点, 其他的复制节点为从节点
3.3 在获得start_ts后进行判断,要插入的key是否有冲突, 如时间有一致的, 在 这样的情况下, perwrite 事务直接abort
3.4 时间戳被记录到数据ROW中
3.5 WRITE 操作进行锁定,此时这个时间只能属于这个操作
4 Commit 过程
4.1 获取TSO 作为commit_ts
4.2 对数据进行commit 主节点的操作
4.3 操作成功,将结果返回给client
4.4 异步进行 commit secondary的操作
以上是分布式percolator 的整体单事务工作的流程. 这里有一个位置是需要等待的,就是我们的 get TSO .
TIDB 在如下的操作中更改了一些部分提高了性能
那么我们看看TIDB 是如何利用自己的本身的情况来优化percolator 模型的,下面是一个对比的列表
TIDB 中改变的是
1 在 Perwrite 后就可以确认数据可以进行commit
2 在perwrite 后会可以获得commit_ts
这样修改后,网络交互会少一个程序. 主要的特点
1 基于TIKV 存储所有数据,而不是在客户端存储缓存的方式
2 perwrite 完成后就可以确认数据可以commit了
那么问题是如何能确认perwrite 完成了
1 采用percolator的方式则数据的状态以primary key 负责,查到secondary key 可以通过指针来指向 primary key,查询键值的状态
2 commits 的时间可以在perwrite 确认后在进行commits的获取
但为了提高整体系统性能,减少交互,则需要解决上面的两个问题
1 在perwrite就要进行确认,KEY 所以TIDB 在这里进行改动,在主节点中记录了secondary key 的, 这样可以无论通过那个KEY 都可以去找到其他的key,这样做的另一个隐藏的需求就是在提高性能的时候, 记录的键的数量不要太大,这里TIDB 控制到 256个KEY address, 整体字节数在 4096个字节内.
这里TIDB 优化的目的为减少网络交互,而过大的事务在网络交互中本身会将优化后的优势消减,所以大事务这里TIDB 并不会使用这样的方式来进行commit
2 commits ,上面说了commits 获取与perwrite有关, 而我们获得每个事务的commits 的工作可以通过 Max TS (PD placement driver) MAX TS 为当前PD 分配时间戳的大值,commits = MAX TS + 1 保证事务commits 是顺序的递增的.
总结: Async Commit 提交的方法针对提交primary key 耗时的操作,针对某些场景也是有无法奏效的情况. 如 你的I/0 已经是瓶颈了,那么通过软件的方式来优化就是徒劳的, 同时对于big transaction 以及 big key 来说, 问题的优化点已经不在提高 primary 提交的效率了,而是把大事务拆小的优化,让提交的事务尽量小使用 async commit的方法提高数据提交的效率.
注:分布式数据库的理论和单体数据库的理论差异比较大, 还需要用更多的时间领会其中设计者的心思的精妙.
相关文章