读写语义
分布式系统一致性保证要求各数据节点按同样的数据版本进行推进
- 写入成功的数据来读要保证读到
- 用户看到事务A成功后,开始提交事务B,那么A的数据版本一定要小于B
- 另外还有数据隔离级别,按数据版本读
数据A写成功要保证能读到可以使用持久化日志来保证,写成功的一个必要条件是各参与者已完成持久化日志且日志状态要能推进至成功,能读到只要读取时能看到这条日志apply的结果或者等待这条日志apply完即可
因为事务A和B可能发生在不同的分区,所以需要有中心节点来进行定序,保证A的数据版本小于B
而要满足数据库隔离级别的需求,还要实现按版本读,此时多分区事务A的提交版本号是个问题,事务A涉及的多分区上可能正在发生跨分区的读,只有先通知到每个参与者上有事务写入,才能让读感知到这个正在提交的事务,而最终的提交版本应该比这些已经发生的读版本号大才行
实现方式
- 先通知到所有参与者开启事务写prepare日志(加锁并持久化日志)
- 获取GTS时间戳作为提交版本
- commit(持久化日志)
- 返回用户写成功
关键路径上需要三次RPC和两次持久化日志操作
- 先通知到所有参与者开启事务写prepare日志(加锁并持久化日志)
- 获取GTS时间戳作为提交版本
- pre-commit(不持久化日志只改写内存)
- 返回用户写成功
关键路径上需要三次RPC和一次持久化操作
- 参与者1取GTS时间戳(和下面发给其他参与者的prepare并行)
- 写prepare日志(取本地读版本,加锁并持久化日志)
- 将所有本地版本和GTS版本比较最大值作为最终提交版本,并等GTS推过这个版本号(大概率推过)
- 返回用户写成功
关键路径上需要一次RPC和一次持久化操作
网友评论