前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >聊聊分布式事务

聊聊分布式事务

作者头像
看、未来
发布2022-05-06 14:09:26
2050
发布2022-05-06 14:09:26
举报
文章被收录于专栏:CSDN搜“看,未来”

愿打开此篇对你有所帮助。

好久没有写这个系列了哈。

前面几篇《打开我的收藏夹》文都让我受益匪浅,在此我还是想说一句:都是自己当初收藏的,就不要吃灰了,逐渐放空掉自己的收藏夹未必不是一件好事。

CAP 理论

C:强一致性,所有子节点数据时刻保持一致 A:整体可用 P:分区容错性,允许部分失败

至少要保证 P 吧,CA 不一定兼得的。

BASE 理论

basically available,基本可用。 优先满足 AP,以最终一致性取代强一致性。

我寻思着这俩不是集群吗?

关于缓存那些的可以翻我的redis专栏,一致性哈希我要再写一篇。

题外话

我一直追崇一个技术点不仅要理解其原理,还需要知道这个技术点解决了哪些痛点,这些痛点又是由什么引发的?这个技术还未诞生的时候是如何解决的? 也就是整体的演进过程,历史脉络。 比如为何需要HTTP?HTTP0.9为何需要演进到HTTP1.0? 进而又向1.1、2演进到最新要将Google开发的基于UDP的QUIC协议应用到HTTP3中。 搞懂这些来龙去脉相信你不仅仅对HTTP会有更深层次的理解,对网络也会有更加深刻的认识。当然也不是说一样东西一来就得全盘理清,有些东西还是比较复杂的,只是说我们要往这个方向去学。 这也是我一直觉得很重要的一个学习思想,知其然知其所以然,会让大家更好的理解很多东西。

这里的“我”指敖丙,我觉得他这段话非常之有道理,以后我要把这种做法贯彻到底!

分布式事务

(本分支图片来源于:面试官问我知道的分布式事务,我一口气说了六种

2PC

二阶段提交,一种强一致性设计:

一荣俱荣,一损俱损。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

第一阶段的协调者有超时机制,假设因为网络原因没有收到某参与者的响应或某参与者挂了,那么超时后就会判断事务失败,向所有参与者发送回滚命令。

眼尖的小伙伴多看两眼,就能看出一个问题来。我先不公布,拿张图挡一下,要自己想的就先别划下去。

有没有想过,协调者故障,或者事务失败了呢?

协调者压力可是很大的哦,因为它要为身后那些数据库撑起一片天哈。

如果协调者事务失败,这里有两种情况。

第一种是第二阶段执行的是回滚事务操作,那么答案是不断重试,直到所有参与者都回滚了,不然那些在第一阶段准备成功的参与者会一直阻塞着。

第二种是第二阶段执行的是提交事务操作,那么答案也是不断重试,因为有可能一些参与者的事务已经提交成功了,到最后真的不行只能人工介入处理。

协调者单点故障分析
代码语言:javascript
复制
Switch 协调者挂的时间:
	case 发布准备命令前{
		挂吧,事务还没开始,去修复它
	};
	case 发布准备命令后{
		锁定了资源的事务参与者将可能陷入阻塞,因为资源被锁定了嘛
	}
	case 发送回滚事务命令前{
		同上
	}
	case 发送回滚事务命令后{
		很大概率没事儿,但是出现网络分区就有可能会有些参与者收不到命令阻塞
	}
	case 发送提交事务命令前{
		好了,全死了
	}
	case 发送提交事务命令后{
		同上上
	}
	default{
	}
}
协调者单点故障解决方案

了解一下主从嘛。通过选举赶紧的再来一个协调者顶上去。

还是对上面进行一个划分处理哈:

代码语言:javascript
复制
Switch 协调者挂的时间:
	case 发布准备命令前{
		没事,小意思
	};
	case 发布准备命令后{
		每个参与者自身的状态只有自己和协调者知道
		这时候就需要日志了,不然新协调者哪里知道谁OK不OK啊
	}
	case 发送回滚事务命令前{
		同上
	}
	case 发送回滚事务命令后{
		同上
	}
	case 发送提交事务命令前{
		这个好办,统统滚回去吧
	}
	case 发送提交事务命令后{
		同上上
	}
	default{
	}
}

2PC 是一种尽量保证强一致性的分布式事务,因此它是同步阻塞的,而同步阻塞就导致长久的资源锁定问题,总体而言效率低,并且存在单点故障问题,在极端条件下存在数据不一致的风险。

但是也不能说人家就没用是吧,那不是还有个场景必须要强一致性嘛,那个ACID的那个。

数据库

3PC

相比于 2PC 增加了预提交阶段。

在这里插入图片描述
在这里插入图片描述

相比于 2PC 有什么升级?

1、准备阶段的变更成不会直接执行事务,而是会先去询问此时的参与者是否有条件接这个事务。因此性能会差一些,而且绝大部分的情况下资源应该都是可用的。 2、预提交阶段的引入起到了一个统一状态的作用,如果是等待预提交命令超时,那该干啥就干啥了,反正本来啥也没干。

3PC 通过预提交阶段可以减少故障恢复时候的复杂性,但是不能保证数据一致,除非挂了的那个参与者恢复。

TCC

2PC 和 3PC 都是数据库层面的,而 TCC(Try - Confirm - Cancel) 是业务层面的分布式事务。

在这里插入图片描述
在这里插入图片描述

TCC模型有个事务管理者的角色,用来记录TCC全局事务状态并提交或者回滚事务。

相对于 2PC、3PC ,TCC 适用的范围更大,但是开发量也更大,毕竟都在业务上实现,而且有时候你会发现这三个方法还真不好写。不过也因为是在业务上实现的,所以TCC可以跨数据库、跨不同的业务系统来实现事务。

本地消息表

本地消息表其实就是利用了 各系统本地的事务来实现分布式事务。 本地消息表顾名思义就是会有一张存放本地消息的表,一般都是放在数据库中,然后在执行业务的时候 将业务的执行和将消息放入消息表中的操作放在同一个事务中,这样就能保证消息放入本地表中业务肯定是执行成功的。 然后再去调用下一个操作,如果下一个操作调用成功了好说,消息表的消息状态可以直接改成已成功。 如果调用失败也没事,会有 后台任务定时去读取本地消息表,筛选出还未成功的消息再调用对应的服务,服务更新成功了再变更消息的状态。 这时候有可能消息对应的操作不成功,因此也需要重试,重试就得保证对应服务的方法是幂等的,而且一般重试会有最大次数,超过最大次数可以记录下报警让人工处理。 可以看到本地消息表其实实现的是最终一致性,容忍了数据暂时不一致的情况。

消息队列

就是消息队列嘛,这个概念还不熟悉嘛?

在这里插入图片描述
在这里插入图片描述

半消息不是说一半消息,而是这个消息对消费者来说不可见。

最大努力通知

举个很常见的例子,我给你发了个QQ消息,你一直不去点,你一打开QQ就可以看到我有条消息等着你去处理,这既是最大努力通知。 或者,想一下 epoll 的 LT 模式。

哎,八篇到这儿就捋出这点来,不知道是我菜还是当时眼光不太好。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-10-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • CAP 理论
  • BASE 理论
  • 题外话
  • 分布式事务
    • 2PC
      • 协调者单点故障分析
      • 协调者单点故障解决方案
    • 3PC
      • TCC
        • 本地消息表
          • 消息队列
            • 最大努力通知
            相关产品与服务
            消息队列 CMQ 版
            消息队列 CMQ 版(TDMQ for CMQ,简称 TDMQ CMQ 版)是一款分布式高可用的消息队列服务,它能够提供可靠的,基于消息的异步通信机制,能够将分布式部署的不同应用(或同一应用的不同组件)中的信息传递,存储在可靠有效的 CMQ 队列中,防止消息丢失。TDMQ CMQ 版支持多进程同时读写,收发互不干扰,无需各应用或组件始终处于运行状态。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档