zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

数据一致性场景实战(一)

2023-04-18 16:57:00 时间

场景一:多redis数据一致性

背景

现在很多并发性很高的系统为了提高吞吐量而使用redis来当数据存储,而当redis挂了的时候有可能数据丢失,这个时候系统可能不可用,而把流量路由到db肯定是不可行的,因为流量太大,这个时候恢复redis中的数据又比较耗时,而这个时候经常会出现使用多个reids集群,即有一个或者多个备份redis集群。这个时候怎么保证多个redis集群数据一致性呢?

解决方案

方案一:强一致性方案-分布式事务中间件

就是在业务代码层面控制,使用分布式事务中间件或者使用tcc来控制事务。 优点:可以保证强一致性 缺点:复杂度较高,且业务代码改动较大 如果是解决背景中的问题,这个方案不推荐

方案二:最终一致性-本地消息表

这里每个redis写操作都生成一条消息来记录日志,失败则进行重试。

优点:实现简单,容易维护 缺点:无 这个方案使用较广,针对背景中的问题推荐该方案

方案三:弱一致性-redis主从同步

将其余redis集群以从节点的方式挂到使用redis的主节点上,来实现主从同步。 优点:不需要业务代码改造,非常简单 缺点:不适用于redis cluster模式

场景二:redis与mysql数据强一致性

背景

在高并发的业务场景下,数据库大多数情况都是用户并发访问最薄弱的环节。所以,就需要使用redis做一个缓冲操作,让请求先访问到redis,而不是直接访问Mysql等数据库,这样可以大大缓解数据库的压力。 读取缓存步骤一般没有什么问题,但是一旦涉及到数据更新:数据库和缓存更新,就容易出现缓存和数据库间的数据一致性问题。

方案

方案一:延时双删策略

先说一下双删策略,也就是更新前删除以及更新后删除。为啥要增加一个延时呢? 举个场景 1)请求A进行写操作,删除缓存 2)请求B查询发现缓存不存在 3)请求B去数据库查询得到旧值 4)请求A将新值写入数据库,并删除缓存 5)请求B将旧值写入缓存

在这种情况下缓存中还是旧数据,这里的延时就是需要避免上面问题,设置一个延时再删除,这里的延时时间可以根据业务具体时间来确认。

如果删除缓存失败,怎么办?这里就不作详细描述,方案原理就是补偿,详细可以参考这篇文章:https://www.cnblogs.com/cb1186512739/p/12740138.html

方案二:延时落库

这个方案就是把redis当数据库用,有一定风险,针对特定业务,比如说秒杀场景的库存等,操作都在redis中,定时将redis中的数据落库。