强一致性和弱一致性的分析思路以及分布式场景的并发技巧

强一致性和弱一致性

分区引发的分布式一致性问题

当数据出现分区(分区不一定等于分片,分片是指数据划分多个域,分区多指复制,分区包含分片的概念)

根据CAP原理(CAP原理来源于 FLP不可能原理),数据出现分区P,那么一致性C和有效性A就得二选一。

我们如果强调一致性,即CP,那么就会出现,数据会一段时间不可读,也就意味着系统长时间不可用。

如果我们强调系统可用性,即AP,那么就会出现,数据会有一段时间读取旧数据,也就意味着系统对外提供的数据和实时数据不一致。

FLP 不可能原理:在网络可靠,存在节点失效(即便只有一个)的最小化异步模型系统中,不存在一个可以解决一致性问题的确定性算法。

分区所面对的场景

分区所面对的场景有很多

其中最常见的就是DB缓存。

我们把数据存储在DB,然后用redis等缓存节点,cache数据,提高查询性能。

也就是说,我们得把部分mysql数据cache到redis中。

我们的web系统会收到两种请求:读请求和写请求。

读请求

读取数据,发现有数据就直接返回,发现没有数据就从DB读取,并缓存到redis中。

非常简单的套路。

写请求

写请求我们有几个问题需要确认:

  • 操作顺序: DB和redis先操作谁?
  • 是否删除缓存:要不要删除缓存?

然后我们可以得出4种策略:

1. 先更新DB,后更新cache
2. 先更新DB,后删除cache
3. 先更新cache,后更新DB
4. 先删除cache,后更新DB

思考在访问DB或者redis失败的情况下,这个几种场景会发送什么问题,以及解决方案。
这就是一道复杂的场景分析题了,按照几种失败场景合理分析即可,下面我做个演示。

1. 先更新DB,后更新cache

先更新DB,后更新cache失败,那么按照读请求会一直命中cache的旧数据,除非cache再次被更新或者删除。
更新失败的话,最好不要反复重试更新,因为更新很多时候是不等幂的,比如你在重试的时候新的更新事件来了,那么重试的数据很容易覆盖了最新数据。

2. 先更新DB,后删除cache

先更新DB,后删除DB,如果删除失败,也会出现旧数据的问题,但是他比更新数据更加友好,而且节约宝贵的缓存空间。还有一个好处就是删除是等幂的,也就说你不小心删除了最新数据也不怕,因为读请求会以DB存储的为准,重新Load。

3. 先更新cache,后更新DB

这个和先更新DB比起来,有一个大问题,就是DB可能没有写入成功,但是你却写入缓存,而我们缓存的数据要求要先在DB存在,显然DB没有写入成功看起来很糟糕,而且失败重试不等幂。

4. 先删除cache,后更新DB

这个看起来还过得去,先删除cache,失败,也就不会去更新DB了。如果更新DB失败,那么该次请求要么放弃(放弃的话还好),要么重试,如果重试的话,延迟会比较久,之前删除的缓存很可能又被旧数据填充了。

总结

基本上,就是往并发脏读,失败重试等幂性这个方向去考虑问题即可。

面对的问题

缓存穿透,即查不存在db中的key,导致访问db。可以用bloom过滤拦截不在db的key。

缓存雪崩,即多个key同一时间过期,加随机数,避免同样的过期时间。

缓存击穿,同一个key过期时被DB被并发,可以采用互斥锁,确保一个进程进行load db。

其他手段

  • 给缓存的key设置随机的expire时间,让缓存自动过期。

  • 用队列或者binlog日志的方式主动删除key。

  • bloom过滤安全防护。

  • 用线程池控制缓存key的写并发数。

  • 考虑失败重试是否等幂

引用: https://www.cnblogs.com/semi-sub/p/13735800.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值