Percolator 分布式事务原理

Percolator 分布式事务原理

简介

Percolator 提供了跨行、跨表的、基于快照隔离的 ACID 事务。

结构

Percolator 为了实现分布式事务,抽象了三个列。

列
    Data
        作用:
            具体存储数据集
        映射关系: {key, start_ts} => {value}
            key: 真实的 key
            start_ts: 事务开始时间戳
            value: 真实的数据值
    Lock
        作用:
            事务执行中产生的锁
            事务开启时获取锁
            事务提交时释放锁
        映射关系: {key, start_ts} => {primary_key, lock_type,..etc}
            key: 数据的 key
            start_ts: 事务开始时间戳
            primary_key: 该事务的 primary_key 的引用. primary_key 是在事务执行时,从待修改的 keys 中选择一个作为 primary_key, 其余的则作为 secondary key.
    Write
        作用:
            已提交事务信息,存储提交时间戳
            write 列记录着 key 的提交记录,当客户端读取一个 key 时,会从 write 列中读取 key 所对应数据在 data 列中的存储位置,然后从 data 列中读取真正的数据。
        映射关系:
            {key, commit_ts} => {start_ts}
                key: 数据的 key
                commit_ts: 事务的提交时间戳
                start_ts: 事务开始时间戳, 指向该数据在 data 中的实际存储位置

流程

写流程

1.Prewrite阶段
    1.从 TSO 获取 start_ts
    2.尝试对所有被写元素加锁, percolator 为所有需要写的 key 选出一个作为 primary, 其余的作为 secondary
        1.每个 key 处理流程如下,中间出现失败,则 Prewrite 失败(先 Prewrite primary,成功后再 Prewrite secondaries)
            1.检查 write-write 冲突
                若 write 列当前 key 的最新数据 commit_ts 大于等于 start_ts,存在更新版本的已提交事务,失败,直接 Abort 整个事务
            2.检查 lock 列中该写入操作是否被上锁
                若 key 已被上锁,失败,直接 Abort 整个事务
        2.Lock 列写入 lock(start_ts, key, primary) 为当前 key 加锁
            若当前 key 被选为 primary, 则标记为 primary;
            若为 secondary, 则标明指向 primary 的信息
    3.Data 列写入 data(key, start_ts, value)
        由于此时 write 列尚未写入,因此数据对其它事务不可见
2.Commit阶段
    1.从 TSO 获取 commit_ts
    2.依次对各个 key 进行提交
        1.先 Commit primary , 如果失败则 Abort 事务
            检测 lock 列 primary 对应的锁是否存在,如果锁已经被其它事务清理(触发 failover 可能导致该情况),则失败。
            写入 Write 列: commit_ts -> data 列的 start_ts
            释放锁:删除 Lock 列当前 key
        2.再异步的进行 Commit secondary
            Commit seconary 无需检测 lock 列锁是否还存在,一定不会失败
            写入 Write 列: commit_ts -> data 列的 start_ts
            释放锁:删除 Lock 列当前 key

读流程

1.Get 操作首先检查 [0, start_ts] 时间区间内 Lock 是否存在
    1.若存在,则返回错误
    2.如果不存在有冲突的 Lock
        1.获取在 Write 中合法的最新提交记录指向的在 Data 中的位置
        2.从 Data 中获取到相应的数据并返回

异常处理流程(异步清理锁)

若 Client 在 Commit 一个事务时,出现了异常,Prewrite 时产生的锁会被留下。为避免将新事务 hang 住,Percolator 必须清理这些锁。

Percolator 用 lazy 方式处理这些锁:
当事务 A 在执行时,发现事务 B 造成的锁冲突,事务 A 将决定事务 B 是否失败,以及清理事务 B 的那些锁。

根据key 从 Lock 列查询 primary 锁
1.若 primary lock 存在
    事务B被 roll back
        因为我们总是最先提交 primary, 所以 primary 未被提交时,可以安全地执行回滚
2.若 primary lock 不存在
    说明 primary lock 已被 WRITE 所替代,也就是说该事务已被提交,事务需要 roll forword
        因为:在 B 提交 commit 之前, 它会先确保其 primary lock 被 write record 所替代(即往 primary 的 write 写提交数据,并删除对应的 lock)。

参考

Percolator论文

相关推荐

  1. Percolator 分布式事务原理

    2024-05-15 23:28:10       38 阅读
  2. 【微服务篇】分布式事务方案以及原理详解

    2024-05-15 23:28:10       37 阅读
  3. 分布式事务

    2024-05-15 23:28:10       43 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-15 23:28:10       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-15 23:28:10       106 阅读
  3. 在Django里面运行非项目文件

    2024-05-15 23:28:10       87 阅读
  4. Python语言-面向对象

    2024-05-15 23:28:10       96 阅读

热门阅读

  1. 5.nginx常用命令和日志定时切割

    2024-05-15 23:28:10       29 阅读
  2. 手机号码的正则表达式

    2024-05-15 23:28:10       26 阅读
  3. xss-lab 1-18关payload

    2024-05-15 23:28:10       28 阅读
  4. 算法提高之热浪

    2024-05-15 23:28:10       30 阅读
  5. 轻松了解深度学习的几大模型

    2024-05-15 23:28:10       33 阅读
  6. Spring整合Junit(单元测试)

    2024-05-15 23:28:10       29 阅读
  7. Chrome查看User Agent的实战教程

    2024-05-15 23:28:10       34 阅读
  8. Spring Boot中自定义注解来统计方法执行时间

    2024-05-15 23:28:10       34 阅读