【LSP】Redis 分布式锁、并发竞争、双写一致

[复制链接]
查看3500 | 回复7 | 2020-12-5 22:30:28 | 显示全部楼层 |阅读模式


并发竞争
这个问题产生的根源是并发写,本身 Redis 是不会产生并发问题的,看过前面文章的同学应该知道, Redis 的线程模型是单线程的,所有的操作指令都在文件事件处理器的队列中,这个绝对是按照先进先出的原则进行操作的,那么并发竞争的问题是如何产生的?

例如我们现在有三个客户端 A , B , C ,需要按序像 Redis 中写入或者更新数据 A -> B -> C ,就像下面这样:


但是现在突然 A 的网络抖动了一下,导致 A 并不是第一个去 Redis 中写数据的,整个流程的操作顺序变成了 B -> C -> A ,这样数据不就错了么。

这就好比你在网上买东西,加购物车,下订单,支付订单的顺序变掉了,你先下单,再支付,再加购物车,这个流程根本走不下去的好吧。这种事情发生在线上的系统上的时候,是非常恐怖的。

这种情况解决起来其实也很简单,加一个分布式锁就可以了,比如这样:


我们可以基于 Zookeeper 实现一个全局分布式锁,确保同一时间,只能有一个系统实例在操作某个 key ,别人都不允许读和写。

你要写入缓存的数据,都是从 DB 里查出来的,都得写入 DB 中,写入 DB 中的时候必须保存一个时间戳,从 DB 查出来的时候,时间戳也查出来。

每次要写之前,先判断一下当前这个 Value 的时间戳是否比缓存里的 Value 的时间戳要新。如果是的话,那么可以写,否则,就不能用旧的数据覆盖新的数据。

双写一致性
只要使用缓存,就可能会涉及到缓存与数据库的双写,只要是双写,就一定会有数据一致性的问题。

首先先介绍下经典的 Redis + BD 的读写模式:

读的时候,先读缓存,缓存没有的话,就读数据库,然后取出数据后放入缓存,同时返回响应。
更新的时候,先更新数据库,然后再删除缓存。
为什么是删除缓存,而不是更新缓存?
这里还会有另外一个问题:为什么是删除缓存,而不是更新缓存?

原因很简单,很多时候,在复杂点的缓存场景,缓存不单单是数据库中直接取出来的值。

比如可能更新了某个表的一个字段,然后其对应的缓存,是需要查询另外两个表的数据并进行运算,才能计算出缓存最新的值的。

另外更新缓存的代价有时候是很高的。是不是说,每次修改数据库的时候,都一定要将其对应的缓存更新一份?也许有的场景是这样,但是对于比较复杂的缓存数据计算的场景,就不是这样了。如果你频繁修改一个缓存涉及的多个表,缓存也频繁更新。但是问题在于,这个缓存到底会不会被频繁访问到?

举个栗子,一个缓存涉及的表的字段,在 1 分钟内就修改了 20 次,或者是 100 次,那么缓存更新 20 次、100 次;但是这个缓存在 1 分钟内只被读取了 1 次,有大量的冷数据。实际上,如果你只是删除缓存的话,那么在 1 分钟内,这个缓存不过就重新计算一次而已,开销大幅度降低。用到缓存才去算缓存。

其实删除缓存,而不是更新缓存,就是一个 lazy 计算的思想,不要每次都重新做复杂的计算,不管它会不会用到,而是让它到需要被使用的时候再重新计算。像 mybatis,hibernate,都有懒加载思想。查询一个部门,部门带了一个员工的 list,没有必要说每次查询部门,都把里面的 1000 个员工的数据也同时查出来啊。80% 的情况,查这个部门,就只是要访问这个部门的信息就可以了。先查部门,同时要访问里面的员工,那么这个时候只有在你要访问里面的员工的时候,才会去数据库里面查询 1000 个员工。

严格要求 「缓存 + 数据库」 必须保持一致
这种模式应该就是我们大多数人现在使用的模式,在不是严格要求 「缓存 + 数据库」 必须保持一致的时候,这样做是可以的。

那为什么说上面这种方案在严格要求 「缓存 + 数据库」 的场景下不行呢?

因为这个问题只有在对一个数据在并发的进行读写的时候,才可能会出现这种问题。

就是如果说并发量没那么高的话,比如 1s 才一个对缓存的读写请求,那么大概率是不会出现缓存 「缓存 + 数据库」 不一致的情况。

但是问题是,如果每天的是上亿的流量,每秒并发读是几万,每秒只要有数据更新的请求,就可能会出现上述的 「缓存 + 数据库」 不一致的情况。

那么这种问题是不是就没有解决方案,当然有,但是如果不是严格要求 「缓存 + 数据库」 必须保持一致性的场景,最好不要使用这个方案。

我们可以让读请求和写请求串行化,把所有的读写请求都串行到一个队列里面去。


串行化可以保证一定不会出现不一致的情况,但是它也会导致系统的吞吐量大幅度降低,用比正常情况下多几倍的机器去支撑线上的一个请求。

把所有的操作都放到队列里面,顺序肯定不会乱,但是并发高了,这队列很容易阻塞,反而会成为整个系统的瓶颈。
aaaa
村长黑科技是专业提供项目资源的服务的村长黑科技平台,如合购网赚项目、引流推广软件、软件程序开发等项目就选村长黑科技平台,参与或发布项目定制各种软件就来村长黑科技平台
千百渡 | 2020-12-6 10:50:28 | 显示全部楼层
LZ帖子不给力,勉强给回复下吧
aaaa
村长黑科技是专业提供项目资源的服务的村长黑科技平台,如合购网赚项目、引流推广软件、软件程序开发等项目就选村长黑科技平台,参与或发布项目定制各种软件就来村长黑科技平台
回复

使用道具 举报

neige | 2020-12-7 12:48:21 | 显示全部楼层
支持支持再支持
aaaa
村长黑科技是专业提供项目资源的服务的村长黑科技平台,如合购网赚项目、引流推广软件、软件程序开发等项目就选村长黑科技平台,参与或发布项目定制各种软件就来村长黑科技平台
回复

使用道具 举报

天镜盗梦 | 2020-12-7 18:41:19 | 显示全部楼层
纯粹路过,没任何兴趣,仅仅是看在老用户份上回复一下
aaaa
村长黑科技是专业提供项目资源的服务的村长黑科技平台,如合购网赚项目、引流推广软件、软件程序开发等项目就选村长黑科技平台,参与或发布项目定制各种软件就来村长黑科技平台
回复

使用道具 举报

68079330 | 2020-12-9 19:33:39 | 显示全部楼层
我也是坐沙发的
aaaa
村长黑科技是专业提供项目资源的服务的村长黑科技平台,如合购网赚项目、引流推广软件、软件程序开发等项目就选村长黑科技平台,参与或发布项目定制各种软件就来村长黑科技平台
回复

使用道具 举报

伴我多久 | 2020-12-10 16:02:21 | 显示全部楼层
为了三千积分!
aaaa
村长黑科技是专业提供项目资源的服务的村长黑科技平台,如合购网赚项目、引流推广软件、软件程序开发等项目就选村长黑科技平台,参与或发布项目定制各种软件就来村长黑科技平台
回复

使用道具 举报

liqiang24 | 2020-12-12 12:36:52 | 显示全部楼层
前排顶,很好!
aaaa
村长黑科技是专业提供项目资源的服务的村长黑科技平台,如合购网赚项目、引流推广软件、软件程序开发等项目就选村长黑科技平台,参与或发布项目定制各种软件就来村长黑科技平台
回复

使用道具 举报

千面萌萌 | 2020-12-12 17:29:23 | 显示全部楼层
顶起顶起顶起
aaaa
村长黑科技是专业提供项目资源的服务的村长黑科技平台,如合购网赚项目、引流推广软件、软件程序开发等项目就选村长黑科技平台,参与或发布项目定制各种软件就来村长黑科技平台
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则