赞
踩
分布式–1概述CAP和Base
分布式–2分布式事务
分布式–3分布式一致性算法
分布式-4集群
分布式–5服务限流算法
分布式–6分布式id
分布式–7性能压测
分布式–8日志链路跟踪
分布式-9分布式锁|redis锁的几种实现
一种简单的副本控制协议,当客户端向一个分布式应用发送写请求的时候,只有当所有的副本节点都更新成功之后,这次写操作才算成功。否则视为失败。这降低了写操作的可用性,提高了读操作的可用性。
假设有N个副本,客户端向一个分布式应用发送写请求的时候,如果有W个副本更新成功之后,这次写操作才算成功。则读操作最多需要读N-W个副本就能读取到最新的结果。
Quorm无法保证强一致性,它是分布式系统中常用的一种机制,用来保证数据冗余的最终一致性的投票算法。Kafka的ISR机制有点类似该机制。
在Paxos协议中,一共有三类角色节点
Proposer 提案者
提案者可以有多个,在流程开始时,提案者提出操作(被称为value)(比如修改某个变量的值),多个提案者可以提出不同的操作。但经过一轮的Paxos算法后,只有一个提案者的操作被运行执行。
Acceptor 批准者
在集群中,批准者有多个(数量设为N)。批准者之间完全独立对等。提案者提出的操作,必须获得半数以上(N/2+1)的批准者批准后才能通过执行
Learner 学习者
学习者不参与选举,而是执行被批准者批准的操作。
1)领导选举
随从(自旋时间没有收到心跳)–候选者(获得大多数节点的投票)-- 领导选举期间,整个集群不对外服务
如果半数服务器分区,则怎么都选不出领导。
2)日志复制
如果应用系统是单一的数据库,那么这个很好保证,利用数据库的事务特性来满足事务的一致性,这时候的一致性是强一致性的。对于java应用系统来讲,很少直接通过事务的start和commit以及rollback来硬编码,大多通过spring的事务模板或者声明式事务来保证。
A应用调用B,在同步调用的返回结果中,B返回成功给到A,一般情况下,这时候就结束了,其实在99.99%的情况是没问题的,但是有时候为了确保100%,记住最起码在系统设计中100%,这时候B系统再回调A一下,告诉A,你调用我的逻辑,确实成功了。其实这个逻辑,非常类似TCP协议中的三次握手。
借助消息队列,在处理业务逻辑的地方,发送消息,业务逻辑处理成功后,提交消息,确保消息是发送成功的,之后消息队列投递来进行处理,如果成功,则结束,如果没有成功,则重试,直到成功,不过仅仅适用业务逻辑中,第一阶段成功,第二阶段必须成功的场景。对应上图中的C流程。
A在同步调用D,D返回成功了。这次调用结束了,但是A为了确保,在过一段时间,这个时间可以是几秒,也可以是每天定时处理,再调用D一次,查询一下之前的那次调用是否成功。
前面部分和上面基于事务型消息的队列,不同的是,第二阶段重试的地方,不再是消息中间件自身的重试逻辑了,而是单独的补偿任务机制。其实在大多数的逻辑中,第二阶段失败的概率比较小,所以单独独立补偿任务表出来,可以更加清晰,能够比较明确的直到当前多少任务是失败的。对应上图的E流程。
commit和rollback是数据库事务中的比较典型的概念,但是在系统分布式情况下,需要业务代码中实现这种,成功了commit,失败了rollback。
最终一致性,适合场景:可以容忍一段时间的脏数据。
(1)读的时候,先读缓存,缓存没有的话,那么就读数据库,然后取出数据后放入缓存,同时返回响应
(2)更新的时候,先删除缓存,然后再更新数据库
• 1、如果是用户纬度数据(订单数据、用户数据),这种并发几率非常小,不用考虑这个问题,缓存数据加上过期时间,每隔一段时间触发读的主动更新即可
• 2、如果是菜单,商品介绍等基础数据,也可以去使用canal订阅binlog的方式。
• 3、缓存数据+过期时间也足够解决大部分业务对于缓存的要求。
• 4、通过加锁保证并发读写,写写的时候按顺序排好队。读读无所谓。所以适合使用读写锁。(业务不关心 脏数据,允许临时脏数据可忽略);
Canal :相当于mysql的从服务器,主服务器更新后,会通知它
1)左边的方案
打开数据库binlog,业务更新数据库后通过订阅直接更新redis
2)右边
根据每个人浏览记录,通过大数据分析推荐个性化数据
• 我们能放入缓存的数据本就不应该是实时性、一致性要求超高的。所以缓存数据的时候加上过期时间,保 证每天拿到当前最新数据即可。
• 我们不应该过度设计,增加系统的复杂性
• 遇到实时性、一致性要求高的数据,就应该查数据库,即使慢点。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。