分布式负载均衡算法 分布式ID算法 分片表主键自增 号段模式原理 Tinyid原理 雪花算法原理 经典基础理论基础 CAP BASE 分布式事务 TCC 截取此文章 2PC (几乎所有主从中间件用到的方法,如zookeeper) MQ 分布式一致性协议 Paxos算法 第一篇例子介绍的蛮好的 RAFT算法 定义 集群配置 zk常用命令 Dubbo下zk注册中心原理 zk领导选举 zk如何处理数据 zk如何保证数据一致性 zk和redis分布式锁区别 场景 架构 找的网图 简单实现思路 seata源码基本思路 简单版seata源码实现
8.1 分布式相关理论和算法 8.2 分布式之zookeeper 8.3 SEATA分布式事务源码原理
8.1 分布式相关理论和算法
1 轮询算法 2 权重轮询算法 3 一致性哈希 4 最少连接数 5 最快相应时间 等 都是字面意思不解释了
1 UUID (32位数的16进制数字,太长太占空间,淘汰) 2 号段模式 3 滴滴 Tinyid 4 雪花算法 5 Redis实现 6 分布式 zookeeper ID生成 7 分片表主键自增 等
可设置起始值,增长值不同来配置 但是每加如新机器,全部配置都得改动 每次只能向db获取一个id,性能也较差
批量提前提供ID,当应用时一一给具体业务分配ID 如提前提供0-1000一段ID,数据库以乐观锁形式记录号段长度和当前位置, 批量拿ID同时也能减小数据库压力
在号段模式基础上,双号段缓存优化。 随机从两个db上拿ID,一个db生成奇数ID,一个偶数ID,保证不会拿到重复值
64 bit long数字作为 ID 1 bit 无意义(统一0为正数) 41 bit 时间戳 (可表示69年时间) 5 bit 机房ID 5 bit 机器ID (机房ID+机器ID 可部署1024台机器) 12 bit 序号 (相同1毫秒内的第几个请求,id请求累加1序号)
一致性(数据) 可用性(业务程序响应等) 容错分区(网络)
基本可用 (业务基本可用,支持分区失败) 软状态 (允许数据延迟) 最终一致性
TCC操作: Try阶段,尝试执行业务,完成所有业务的检查,实现一致性;预留必 须的业务资源,实现准隔离性。 Confirm阶段:真正的去执行业务,不做任何检查,仅适用Try阶段预留的业务资 源,Confirm操作还要满足幂等性。 Cancel阶段:取消执行业务,释放Try阶段预留的业务资源,Cancel操作要满足幂 等性。
第三方等待所有程序预提交,收到一半以上的确认ACK信号则大家一起最终执行, 否则回滚
生产者执行时会修改发布的名称,让订阅的消费者无法消费。通过自我判断成功 执行后修改回原先名称,让订阅消费者继续消费。具体将来kafka章节再说
发布/接受/学习 该算法主要是快速度选出老大 1 当接受者第一次遇到id 100的发布者1时候,接受者将变成他铁粉不再改动支持者 并且id小于100的发布者理都不理,这样会使得选举很快。 2 当大于id100比如id200的发布者2给那个接受者拉票时,接受者依然支持发布者1 ,并且id小于200的所有发布者理都不理。这样选举速度更快了 3 当有发布者拿到一半以上铁粉就成为老大了,其他发布者也得跟随这个老大
主从,详情看下面zk的ZAB算法,其实差不太多
8.2 分布式之zookeeper
一个拥有文件系统特点的数据库 处理数据一致性问题的分布式数据库 具有发布和订阅功能的分布式数据库(watch机制)
1 vim 配置 zoo.cfg文件 clientPort xxxx //配置端口 server.1 = xxx server.2 = xxx //配置集群ip和port 2 启动集群 bin/zkServer.sh start//zk会自动选举leader和follower 3 客户端接入zk集群 zk集群下任意一节点bin目录下,启动一个客户端接入即可 ./zkCli.sh -server [client ip port]
没参考价值,略
图片不知道怎么正过来,我也很无奈
ZAB协议领导者选举,过半机制,2pc数据同步等共同组成ZAB协议
1 一开始大家都给自己投票 2 彼此之间互相比较zxid(即事务id),谁zxid大则这轮改票为大的一方。如果zxid 一致则看谁myid(自己的id)大为准 3 当一个节点得到超过一半数量的投票,则当选leader 领导选举结束后又有新节点来,如果新节点zxid大于leader的zxid,则新节点需 要回滚,新节点必须和leader节点xzid同步,然后加入集群 当leader挂掉,触发领导者选举 当有follwer挂掉导致领导者发现跟随follower未超过一半,leader停止对外服务, 仍需要重新领导者选举
1 事务日志按照顺序添加 2 更新内存 DateTree (从内存中拿数据,不走磁盘,速度更快)
2pc事务一致性模式 1 leader生成事务 2 预提交 3 所有follower生成事务 4 ack返回 5 收到一半以上follower的ack则提交,否则回滚 6 提交成功,数据写入内存DateTree
1 zk有节点的watch机制,注册个监听器,不需要一直主动尝试获取锁,性能开销小 redis需要不停主动尝试获取锁,性能开销较大 2 redis拿到锁的服务器挂了需要等到超时时间才释放锁,zk是临时节点拿锁,当服 务器挂了,立刻就会删除临时节点并且释放锁
8.3 SEATA分布式事务源码原理
实际业务中,我们会遇到,订单系统代码层出错,执行回滚。但是数据库依然添加 了相关数据。为什么呢,因为库存系统和订单系统是分开的。我们只回滚了订单 系统,却没有回滚库存系统。所以分布式事务就产生了。 所以我们希望订单系统能够通知库存系统一起跟着回滚
RM(资源管理器) TM(事务管理器) TC(全局协调者) RM 事务参与者 TM 全局事务管理者 TC:事务的协调者。保存全局事务,分支事务,全局锁等记录,然后通知各个RM回 滚或提交。
1 开启全局事务 创建map 2 注册分支事务 transactionIdMap.get(groupId).add(transactionId) 如果transactionType为rollback则groupId下全部回滚 3 提交全局事务 sentMsg(groupId,"commit")
seata中维护三个表,branch_table/global_table/lock_table branch_table维护了注册的分支事务信息 global_table维护了注册的全局事务信息 lock_table主要记录业务表在被哪个写事务执行上锁,其他事务不能冲突执行 seata也有一个undo_log表,根据事务id(xid)以Json形式保存image镜像到 undo_log内,将来可以根据镜像进行2pc回滚 1 seata首先底层实现GlobalTranscationScanner.class的注解,这个注解类 implement AbstractAutoProxyCreator(SpringAOP顶级抽象父类接口) 和 InitializingBean(初始化RMClient和TMClient) 2 判断是注解调用还是TCC调用等等,AOP生成代理类,内部织 入GlobalTransactionalInterceptor的注解拦截器 3 根据begin变量判断是全局事务还是分支事务,TM和TC开启信息交互 A 全局事务 1 getCurrentOrCreate创建TM 2 获取全局事务信息 3 开启全局事务beginTransaction(txInfo,tx); 4 调用JDBC往global_table内写入全局事务数据 B 分支事务 beforeImage原先镜像 根据增删改查不同sql创建不同执行器,执行execute方法(需要从 lock_table中拿锁,如果拿不到30ms拿一次,拿10次自旋拿锁,一直拿不 到回滚到beforeImage) afterImage(生成执行后镜像) prepareUndoLog(beforeImage,afterImage) 完整镜像保存到undo_log 表内,可以供将来回滚使用 commit提交,branch_table写入分支事务信息,与TC信息交互 4 提交本地事务并上传成功或失败状态到TC 5 如果有本地事务提交失败,全局事务链下所有事务全部回滚
//客户端真正应用 @Service public class DemoService{ @Autowired DemoDao demoDao; @GlobalTransaction(isStart=true) //我们自己实现的SEATA注解 @Transactional public void test(){ //假设Dubbo下,demoDao,demoDao2很多个demoDao不在同一个系统 demoDao.inset("data1"); } } 1 实现@GlobalTransaction(isStart=true)注解 @Target(~) @Retention(~) public @interface GlobalTransaction{ boolean isStart() default false;//控制是否是全局事务,默认不是 } 2 加切面 @Aspect //对应Seata拦截器 @Component public class GlobalTransactionAspect implements Ordered{ @Around("@annoation(~.annoation.GlobalTransaction)")//所有加了这个注解的都要拦截走这个切面 public void invoke(ProceedigJoinPoint point){ before逻辑: //拿point方法,拿GlobalTransaction对象, //如果isStart是true,表示这是全局事务,开启创建全局事务组 GlobalTransactionManager.createGroup() point.proceed(); //spring切面下@Transaction切面真正方法 after逻辑 //创建注册事务分支到事务组 TM GlobalTransactionalManager下方法 //如果proceed成功,创建的事务分支的lbTransaction.Type为提交属性,不成功设为回滚属性 //如果状态回滚,TC通知全局事务组下所有事务全部回滚 } }
RM资源管理层(提交本地事务) public class LbConnection implements Connection{ 通过构造方法接收Spring实现的Connection,利用它完成大多数重写方法, 我们只需要改变提交方法逻辑 Connection connection; LbTransaction lbTransaction; @Override ~commit(){ new Thread{//不阻塞后面的注册 lbTransaction的线程wait; //等待NettyClientHandler设置transactionType然后执行本地提交或回滚 if(lbTransaction.transactionType为commit本地提交){ connection.commit(); }else{ connection.rollback(); } } } } 对Spring底层*javax.sql.DataSource.getConnection(...)加切面 @Around(...) ~ proceed ~{ Connection connection = point.proceed() //Spring本身实现类 return new LbConnection(connection); //SPring会使用我们自己重写的实现类 }
事务管理者TM public class GlobalTransactionManager{ NettyClient nettyClient; ThreadLocal<LbTransaction> current = new ~; ThreadLocal<String> currentGroupId = new ~; Map<String,LbTransaction> LB_TRANSACTION_MAP = new ~; //创建全局事务组 public String getOrCreateGroup{ 1 利用分布式ID算法创建一个唯一ID GroupId 2 以Json形式 nettyClient.send(JSONObject)发送给NettyServer 的NettyClientHandler保存事务信息 3 currentGroupId.set(groupId); } //注册全局事务组 public ~~~~ 设置事务Type,事务Id,GroupId等然后以Json形式传给NettyServer //提交全局事务组 //创建分支事务 public ~~~ 创建lbTransaction,以Json形式 nettyClient.send(JSONObject)发送 给NettyServer //注册分支事务 public ~~~~ map.put(groupId,lbTransaction) } public class LbTransaction{ public String transactionId; public TransactionType transactionType; 构造方法 ~ } public class NettyClientHandler{ ~ channelRead(~){ LbTransaction transaction = GlobalTransactionManager.getlbTransaction(groupId); 如果GlobalTransactionAspect下point.proceed执行成功,这里会 传入成功指令,设置transaction.transactionType为commit。然后 我们配置的RM下LbConnection会执行commit方法本地提交,否则本地回滚 } }
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算