IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 理解分布式事务 -> 正文阅读

[大数据]理解分布式事务

1. 为什么需要分布式事务

首先,复杂的业务场景是需要事务的,这是毋庸置疑的,至于需要分布式事务则可能是因为业务数据太多,进行了分库,或者newsql数据酷中对数据进行了shard,将数据存放在了不同的服务器上,对这些不属于同一进程或不属于同一台物理机的数据进行操作时,也希望可以支持事务功能,这就是分布式事务。

2. 二阶段提交

目前来讲,比较常见的分布式事务实现方式是二阶段提交。主要实现方式如下:

  1. 从分布式集群中选择一个节点作为协调者
  2. 客户端将本次事务请求发给协调者
  3. 协调者收到请求后,在本地记录事务状态,然后将写入请求分发给所有需要参与该事物的其他节点,这些其他节点叫作参与者。
  4. 参与者收到请求后,在本地进行prepare操作,即对需要写入的数据加锁,然后将新版本数据写入,在本地记录事务状态,完成后给协调者回复一个prepareOk。如果失败则给协调者恢复rollback
  5. 协调者收到所有的prepareok之后,就可以提交事务,将事物状态改为commit,然后向所有参与者发起commit请求。
  6. 参与者收到commit请求后,完成事务提交,释放锁信息,给协调者进行回commitOk。
  7. 协调者收到所有commitOk之后,就可以回复客户端,删除事务信息,本次事务以成功提交而结束,。
  8. 如果在第5步中收到了任意参与者的rollback信息,那么协调者都将决定回滚该事物,流程和commit一致。
    可以看到在步骤中,每次事务状态改变后,就需要持久化那么事务上下文的信息什么时候才能删除?
    参与者在完成commit之后,就可以清理事务上下文。协调者需要在收到所有的commitOk请求后,才能清理事务上下文。协调者这时候才能清理的原因是要确保所有的参与者都收到了commit/rollback请求。看个例子,协调者决定提交一个事务,提交后向所有参与者发送commit请求,发送之后清理事务上下文,这时候有个参与者挂了,过了两分钟才重启,这时候该参与者永远也无法知道事务该提交还是回滚,因为协调者上的事务上下文已经被清理了。所以这是不安全的,协调者的上下文必须在知道所有节点都完成commit/rollback之后才能清理。

3. 二阶段提交能够满足ACID吗

首先分析一下2PC为什么符合原子性。虽然有多个参与者参与事务,但是事务状态的推动都是靠协调者来进行了,只有协调者可以推动事物的整体状态,所以当协调者做出决定的时候,事务要么是commit,要么是rollback,不可能存在一部分参与者提交,一部分参与者回滚的情况,不论如何,事务总是符合原子性的。
分析一下隔离性,在二阶段提交的过程中,所有的写入操作都会使用锁保护,如果不考虑性能,所有的数据读取也需要加锁,那么最终的对数据读写就能达到串行化,这是靠二阶段提交中加上SS2PL来实现的。当然也不一定非要使用锁的方式,和单机事务一样,也可以在二阶段提交中使用OCC等方式来进行并发控制。
持久性,上述算法协调者会在收到所有的commitOk请求后,完成事务提交,这时候所有参与者都已经将数据写入了,保证了持久性。

4. 异常处理

二阶段提交这种方案乍一看很简单,就是靠协调者根据各种情况,推动事物状态,但是在分布式场景中,可能出现各种预期之外的情况,下面简单分析一下:

4.1 协调者宕机

  1. 在prepare状态宕机。协调者收到客户端时候请求后会持久化事务上下文,那么重启之后可以恢复出来,继续给所有的参与者发送prepare消息,之后流程继续。只要协调者没进入到commit或者rollback状态,宕机重启流程都是一样的,只是参与者可能会收到相同的prepare请求,幂等处理即可(不能上次prepare进行了commit,这次相同的prepare请求却需要rollback)
  2. 在进入commit状态后宕机。其实和prepare相似,协调者会持久化commit状态,之后给所有参与者发送commit请求,如果这时候宕机了,能够恢复出commit事务上下文,给所有参与者发送commit消息。

4.2 参与者宕机

  1. 参与者宕机对事物状态就更没影响了,因为状态只靠协调者推进。但是参与者宕了之后,写调整需要进行一些处理,比如长期收不到所有节点的prepareOk请求,那么超时后参与者可以决定rollback。如果协调者长期收不到commitOk请求, 那么参与者需要一直尝试给未完成的节点发送commit请求,直到收到所有的commitOk,在此之前协调者也无法清理事务上下文。

2PC的故障处理非常麻烦,而且存在一些问题,比如某个事物协调者宕机了,但是所有参与者完成了prepare,这时候参与者就只能等协调者恢复,在此之前都必须持有之前上的锁,会阻塞集群的其他事务,这是2PC让人很不喜欢的一点,所以在spanner中进行了改进,使用paxos为每个节点进行3副本冗余,当某个节点宕机后其他副本迅速顶上,防止2PC阻塞住。

5. 优化

简单分析一下2PC提交的延迟:

  1. 客户端发送给协调者请求(1次网络)
  2. 协调者存储事务上下文(1次落盘)
  3. 协调者给所有参与者发请求(1次网络)
  4. 参与者收到prepare请求后写入数据并持久化事务状态(一次落盘)
  5. 参与者回复prepareOk(1次网络)
  6. 协调者完成提交,更新并持久化事务状态(1次落盘)
  7. 协调者给所有参与者发送commit(1次网络)
  8. 参与者更新事务状态为commit(1次落盘)
  9. 参与者回复commitOk(1次网络)
    10.协调者结束事务,回复客户端(1次网络)

相当于6/2次网络来回,然后4次落盘。来看看如何优化延迟:

优化一,没必要等到所有节点都commitOk之后再回复请求,协调者更新了事务状态为commit之后,就可以对客户端进行提交,剩下的参与者提交和事务上下文回收可以异步进行。即上述的7,8,9步可以不需要,通过异步执行。

优化二,并行提交,客户端没必要把所有请求都发给参与者,让参与者给协调者发信息。客户端可以直接将请求发送给所有参与者,从所有参与者中选出一个协调者来处理事务即可。即1234可以合成为1步(客户端向所有参与者发起事务请求,并指定其中一个是协调者。)

优化三,第6步是收到了所有prepareOk后更新事务状态,然后持久化状态,根据优化1这时候就可以回复客户端。这一步的持久化状态可以不需要吗?理论上是可以行的,因此如果参与者进入了commit或者rollback状态,那一定是因为参与者全部完成了prepare,而参与者prepare的上下文在每个参与者中一定存在,所以这协调者持久化commit/rollback状态可以异步执行,即使宕机了,该信息丢失了,可以重启后,重新尝试向所有的参与者发起prepare请求,参与者会回复commit或者rollback请求,这样协调者可以回复出来commit或者rollback状态。

所以优化后最终逻辑为:

  1. 客户端向所有参与者发起请求,选择其中一个为协调者(1次网络)
  2. 所有参与者完成prepare阶段,更新事务状态(1次写盘)
  3. 所有参与者向协调者发起prepareOk请求(1次网络)
  4. 协调者收到所有prepareOk之后,完成提交,回复客户端(1次网络)
  5. 后面全是异步执行,定期给所有节点发送commit请求,收到所有commitOk后进入事务上下文清理阶段。
    整体来说只需要1次写盘,就可以完成提交。
  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-01-16 13:08:20  更:2022-01-16 13:08:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 14:40:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码