1.数据库和Redis的一致性
全量缓存保证高效读取
所有数据都存储在缓存里,读服务在查询时不会再降级到数据库里,所有的请求都完全依赖缓存。此时,因降级到数据库导致的毛刺问题就解决了。但全量缓存并没有解决更新时的分布式事务问题,反而把问题放大了。因为全量缓存对数据更新要求更加严格,要求所有数据库已有数据和实时更新的数据必须完全同步至缓存,不能有遗漏。对于此问题,一种有效的方案是采用订阅数据库的 Binlog 实现数据同步
现在很多开源工具(如阿里的 Canal等)可以模拟主从复制的协议。通过模拟协议读取主数据库的 Binlog 文件,从而获取主库的所有变更。对于这些变更,它们开放了各种接口供业务服务获取数据。
将 Binlog 的中间件挂载至目标数据库上,就可以实时获取该数据库的所有变更数据。对这些变更数据解析后,便可直接写入缓存里。优点还有:
①大幅提升了读取的速度,降低了延迟
②Binlog 的主从复制是基于 ACK 机制, 解决了分布式事务的问题
③如果同步缓存失败了,被消费的 Binlog 不会被确认,下一次会重复消费,数据最终会写入缓存中
缺点不可避免:
①增加复杂度
②消耗缓存资源
③需要筛选和压缩数据
④极端情况数据丢失
可以通过异步校准方案进行补齐,但是会损耗数据库性能。但是此方案会隐藏中间件使用错误的细节,线上环境前期更重要的是记录日志排查在做后续优化,不能本末倒置。
2.cap可用性
①心跳检测
以固定的频率向其他节点汇报当前节点状态的方式。收到心跳,说明网络和节点的状态是健康的。心跳汇报时,一般会携带一些附加的状态、元数据,以便管理
周期检测心跳机制:超时未返回
累计失效检测机制:重试超次数
②多机房实时热备
两套缓存集群可以分别部署到不同城市的机房。读服务也相应地部署到不同城市或不同分区。在承接请求时,不同机房或分区的读服务只依赖同样属性的缓存集群。此方案有两个好处。
a.提升了性能。读服务不要分层,读服务要尽可能地和缓存数据源靠近。
b.增加了可用。当单机房出现故障时,可以秒级将所有流量都切换至存活的机房或分区
此方案虽然带来了性能和可用性的提升,但代价是资源成本的上升。
③分区容错性
分布式系统对于错误包容的能力
通过限流、降级、兜底、重试、负载均衡等方式增强系统的健壮性
④日志复制
a.Leader把指令添加到日志中,发起 RPC 给其他的服务器,让他们复制这条信息
b.Leader会不断的重试,直到所有的 Follower响应了ACK并复制了所有的日志条目
c.通知所有的Follower提交,同时Leader该表这条日志的状态,并返回给客户端
⑤主备
主机宕机时,备机接管主机的一切工作,主机恢复正常后,以自动(热备)或手动(冷备)方式将服务切换到主机上运行,Mysql和Redis中常用。
MySQL之间数据复制的基础是二进制日志文件(binary log fifile)。它的数据库中所有操作都会以“事件”的方式记录在二进制日志中,其他数据库作为slave通过一个I/O线程与主服务器保持通信,并监控master的二进制日志文件的变化,如果发现master二进制日志文件发生变化,则会把变化复制到自己的中继日志中,然后slave的一个SQL线程会把相关的“事件”执行到自己的数据库中,以此实现从数据库和主数据库的一致性,也就实现了主从复制
⑥互备
指两台主机同时运行各自的服务工作且相互监测情况。在数据库高可用部分,常见的互备是MM模式。MM模式即Multi-Master模式,指一个系统存在多个master,每个master都具有read-write能力,会根据时间戳或业务逻辑合并版本。
⑦集群模式
是指有多个节点在运行,同时可以通过主控节点分担服务请求。如Zookeeper。集群模式需要解决主控节点本身的高可用问题,一般采用主备模式。
3.分布式事务
①XA方案
两阶段提交 | 三阶段提交
准备阶段的资源锁定,存在性能问题,严重时会造成死锁问题
提交事务请求后,出现网络异常,部分数据收到并执行,会造成一致性问
②TCC方案
Try Confirm Cancel / 短事务
Try 阶段:这个阶段说的是对各个服务的资源做检测以及对资源进行锁定或者预留
Confirm 阶段:这个阶段说的是在各个服务中执行实际的操作
Cancel 阶段:如果任何一个服务的业务方法执行出错,那么就需要进行补偿/回滚
③Saga方案
事务性补偿 / 长事务
流程长、流程多、调用第三方业务
4.MQ最终一致性
比如阿里的 RocketMQ 就支持消息事务(核心:双端确认,重试幂等)
①A(订单)系统先发送一个 prepared 消息到 mq,prepared 消息发送失败则取消操作不执行了
②发送成功后,那么执行本地事务,执行成功和和失败发送确认和回滚消息到mq
③如果发送了确认消息,那么此时 B(仓储)系统会接收到确认消息,然后执行本地的事务
④mq 会自动定时轮询所有 prepared 消息回调的接口,确认事务执行状态
⑤B 的事务失败后自动不断重试直到成功,达到一定次数后发送报警由人工来手工回滚和补偿