分布式事务/一致性/配置/管理/锁/协调/通信

2019-10-27  本文已影响0人  上山走18398

分布式
事务
缓存,一致性(集群数据同步或者分布式数据一致)
配置:元数据,配置信息
管理协调

通信:mq RPC grpc
监听: A是否可用,不可用启动备份,监听数据的变化是否消费->以便实现下一步
幂等性: token方案+redis
注册中心
顺序性mq:

通过绘制分布式场景构建分布式体系

分布式

应用场景!!!!!

KeyWord

分布式一致性

?数据的一致性,是否允许多个节点发起写操作,?
写(更新) --> 同步
网络

理论

拜占庭将军问题:消息传递的不确定性
CAP理论
BASE理论:既然无法达到强一致性,那么采用适当的方法达到最终一致性

数据一致模型

强一致性:
弱一致性:
最终一致性:

一致性算法

Paxos
Raft
ZAB(节点编号myid和ZXid)

一致性协议
引入协调器(Coordinator),协调者
2pc
3pc
TCC
消息队列异步确保
较轻的解决方案:幂等/重试,状态机,恢复日志,异步校验,主从同步

作为一个分布式系统,它和单机系统的最大区别,就在于网络.

参考链接:https://blog.51cto.com/13580976/2161507

单主协议(不允许数据分歧):
  1. 主备同步,主备复制是有延时的,实现最终一致性:
    主节点处理完写操作,立即返回给客户端,异步(master挂了,造成数据丢失)

  2. 2PC -CA特性:
    协调者才拥有超时机制
    数据同步完成之后才返回客户端结果
    阶段1: 准备阶段

    1. 表决 (所有的slave)
      a 协调者向所有参与者发送事务内容,询问是否可用提交事务,并等待答复
      b 各参与者执行事务操作,将undo和redo信息记录事务日志中(但不提及事务)
      c 执行成功,给协调者反馈yes,即可提交,否则反馈no,不可提交

    2. 提交(暂存区移交到永久区,否则回滚)
      a 确认ack信息

    3. 2pc缺陷:
      a 同步阻塞: 所有参与事务的逻辑均处于阻塞状态
      b 单点故障
      c 脑裂

  3. 3PC
    事务的提交过程分为canCommit,PreCommit,doCommit

    1. 引入超时机制,所有成员都有
    2. 把准备阶段一分为二
      均无法彻底解决分布式一致性问题
  4. Paxos
    背景: 分布式系统,网络异常,机器宕机,如何达成一致性
    目的:可容忍消息丢失,延迟,乱序,重复,2F+1容错机制最多允许F个节点同时出现故障,最多只针对一个确定的提案达成一致
    参考链接:https://blog.csdn.net/omnispace/article/details/79653932
    角色成员:

    1. proposal:提案
    2. Proposer:提议者
    3. Acceptor: 决策者
    4. Learner: acceptor告诉learner哪个value被选定,learner就认为那个value被选定
      paxos算法通过一个决议分为两个阶段(learn阶段之前决议已经形成)
  1. RAFT
    依靠状态机和主从同步
    1. 选取主节点:投票机制,超过半数即可(身份:leader,follower_计时器(计算超时时间)_Candidate)
    2. 同步数据
多主协议(允许数据分歧):Gossip 、POW

Zookeeper-Zab协议

Zookeeper Atomic Broadcast-> zookeeper原子广播协议
崩溃恢复
原子广播
https://www.cnblogs.com/stateis0/p/9062133.html

https://www.jianshu.com/p/400a44edee88

分布式事务

分布式系统的不同节点,分布式事务就是为了保证不同数据库的数据一致性

本地事务 ACID
参考链接: https://www.jianshu.com/p/f0a1b00a6002

  1. 并行事务的原子性
  • 事务的状态
  • 事务依赖:
    如果事务T2依赖于事务T1,那么T1必须在T2提交之前完成提交操作
    多个事务依赖T1 -> 可能造成级联回滚
  1. 隔离性的实现:
    https://blog.csdn.net/w2064004678/article/details/83012387
  • 时间戳
  • 多版本和快照隔离 MVCC
    每一行数据中额外保存两个隐藏的列:当前行创建时的版本号和删除时的版本号
  1. 级联回滚
    事务之间产生了依赖而导致的,将事务隔离,在A事务完成之前对其他事物不可见
  2. 一致性
  • ACID
  • CAP
    具体在数据库上,就是分布式数据库中,每一个节点对于同一个数据必须具有相同的拷贝 -> 数据的分布式存储
分布式事务产生的原因

1 数据库分库分表

分库分表的原理

  1. 应用SOA化

业务的服务化,网站进行拆解,分离出来订单中心,用户中心,库存中心,每个服务会有专门的数据库存储信息

  1. master-slave
分布式事务的应用场景
  1. 支付
  2. 在线下单
  3. 扣库存和更新订单状态
场景的分布式事务解决方案
  1. 基于XA协议的两阶段提交

事务管理器和本地资源管理器
应用场景狭隘,没有记录prepare阶段日志,性能不理想
2pc

  1. !!消息事务+最终一致性 (业务系统结合MQ消息中间实现)

所有的消息事务就是基于消息中间件的两阶段提交,本质上是基于消息中间件的一种特殊利用;
**要么保证本地事务操作成功并且对外发送消息成功,要么两者都失败
两阶段提交高并发场景下的应用:
Producer mq Consumer

  1. 把消息发送分成两个阶段:
  1. 发送prepare消息给mq
  2. 执行本地事务
  3. 根据本地事务执行结果,确认或者取消prepared消息
  如果1,2失败直接回滚,第三步失败,RocketMq会定期扫描prepare消息,询问发送方是发送这条消息还是取消发送
  消息中间件,支持重复消息,网络异常带来的重试,消费方要实现幂等
  对于消费方,事务消息支持重试机制,也就是说不必生产者主动发起重试
  1. 只要消息事务成功,那么A操作一定成功,消息一定发出来了(保证mq一定会被消费,ack机制和序列化机制)
  2. B会收到消息去执行,如果B执行失败,消息会重投,直到B成功
  3. 变相的实现A与B的分布式事务
    事务型消息队列
    消息队列+定时补偿机制
    异步回调机制
  1. TCC编程模式
    try: 资源预留&锁定,事务发起方将调用服务提供方的Try方法来锁定业务🔒需要的所有资源
    confirm: 确认执行业务逻辑操作,这里使用的资源一定都是Try中预留的资源,Try+Confirm组合起来是一次完整的业务逻辑
    cancel: 取消执行业务逻辑 ,try阶段只是预留资源,并未真正执行操作
  1. 最大努力通知方案
  1. 2pc,3pc
  1. 轻型解决方案

幂等/重试,状态机,恢复日志,异步校验
幂等:MVCC 去重

mq消费的顺序性,在什么情况下要保证顺序性

单聊消息投递,发送和接受顺序一致
群聊消息,保证所有用户展现顺序一致
充值支付,保证同一个用户发起的请求在服务端执行序列一致

顺序的生产:

  1. 以客户端或者服务端端时间为主(北京时间?纽约时间?)
  2. 服务端生成单调递增id作为时序一句
  3. 假如业务能接受误差不大的趋势递增id
    消息发送,帖子发送时间,甚至秒杀时间都没有这么精准的时序要求
  4. 单点序列化,可以保证多机相同的时序
    producer -> 发送顺序
    消费被存储时保持和发送的顺序一致
    consumer -> 消费顺序

增删改 不能变成 删改增的顺序
消息发送的一致性, 事务操作+消息发送为一个整体,同时成功

业务功能场景下保证消息的发送和接收顺序是一致的。如:订单场景,要求订单的创建、付款、发货、收货、完成消息在同一订单下是有序发生的(局部有序)
产生原因:网络重试 网络送达的不确定性

按照消息的生产者发送顺序来消费(FIFO_可能由于网络原因顺序是乱序的)
消息中间件 -> 创建mq Queue
A 单线程消费来保证消息的顺序性
B 对消息进行编号,消费者处理时根据编号判断顺序
参考链接: https://blog.csdn.net/A_BlackMoon/article/details/85197888
参考链接: https://blog.csdn.net/thekenofDIS/article/details/79973589
kafka ,同一个key发送到同一partition,但是多线程并发处理就会出错,单线程性能不行,如何处理
AB顺序变成BA->保证后一条消息发送之前,上一条的消息状态已经是可知的
!!顺序性
参考链接:https://www.jianshu.com/p/b100126a2bf3
rabbitmq:
1. queue consumer
2. 多个consumer消费一个queue,造成顺序问题
3. 拆分多个queue 或者一个queue对应一个consumer,然后这个consumer内部用内存队列
kafka:
1. 一个topic ,三个partition
2. key(比如订单ID),相关数据落到同一个partition,partition是有序的(kafka可以保证同一个分区是有序的)
3. 多个线程并发处理消息->造成顺序错乱
4. N个内存Queue,具有相同key的数据都到同一个内存queue,然后对于N个线程,每个线程分别消费一个queue,保证顺序性
rocketMQ
1. orderID取模,相同模的数据放到messageQueue里面,只要消费者有序消费即可
消息中间件对比

https://www.jianshu.com/p/8f7ebbcbeee5 各种队列对比

消息重复问题,能否保证幂等性

造成消息重复的根本原因:网络不可达
服务端接送到两条一样的消息,该如何处理

参考链接:blog.itpub.net/69917606/viewspace-2642545

消息不丢失,99.99

生产者丢
mq丢
消费者丢

上一篇下一篇

猜你喜欢

热点阅读