前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >多线程编程之高并发下的缓存一致性方案

多线程编程之高并发下的缓存一致性方案

原创
作者头像
javaworld
修改2019-05-10 18:13:28
2.1K0
修改2019-05-10 18:13:28
举报

雪崩时,没有一片雪花是无辜的!

缓存一致性背景

在高并发的场景下,缓存往往成为缓解数据库I/O压力最完美的选择;将并发高峰期请求频繁的数据放入缓存,请求派发时优先操作(读取或者修改)缓存中的数据,然后在异步同步到数据库中。这种处理方式在理想情况下是很完美的,它使得数据库I/O不再试并发瓶颈,指数扩张了整个系统的吞吐量。倒是现实却也存在很多问题:

  1. 缓存穿透,雪崩,并发等问题有兴趣童鞋请看我问答或者点击文末的更多链接,其中有对穿透雪崩的详细解决方案。
  2. 数据一致性问题,是指缓存中的数据和持久化存储中的数在某一时刻存在不一致的情况。今天缓存以redis为例,持久化以mysql为例。
  3. 缓存内存管理问题,缓存是否存在内存泄漏,如何解决无限增长的redis内存?

解决方案

针对以上 第二个问题,也就是我这篇文章的主要面对的问题,不管是先写库还是先删除数据在写库,还是先删除数据然后写库然后再删除,都存在数据不一致的情况,因为在高并发的场景下,写和读是高频率并发的,你无法提前预知谁先到来。针对这一问题,目前业界有一下四个解决方案:

  • 第一方案:经典的延时双删策略,伪代码如下:
代码语言:javascript
复制
public void updateUserInfo(String key,UserBasic userBasic){
 redis.delKey(userBasic.getUserid());
 userBasicMapper.update(userBasic);
 Thread.sleep(200);
 redis.delKey(userBasic.getUserid())
}

这种方式,在一定程度上能够解决数据一致问题,在数据库I/O写入完成之后再次清理缓存,能够让最新的数据以最短的时间同步的缓存中去,在写数据库期间的读请求还是会打到数据中中,存在两个明显的问题:1,200毫秒怎么来的,主要考虑数据库主从同步时间,或者直接从主库读取缓存数据;2,清空缓存之后,高并发操作mysql存在缓存击穿的风险。

  • 第二方案:基于binlog的异步消息队列同步缓存机制。该方法要求通过mysql数据库binlog伪代实时更新新缓存,这里有两个要求:1,实时监控binlog,对biglog中的add,update,del操作进行处理;2,通过消息队列异步更新缓存。该方案也存在以下问题:1,需要等待数据库主从完成之后才能进行缓存同步,这期间是一段空档期,缓存和数据库中数据是不一致的。2,全量更新数据流可能较大,增量更新对于数据丢失问题比较难处理。
  • 第三方案:删除缓存更新主库成功之后,更新缓存,设置过期时间约为数据库主从时间;然后再推迟指定时间异步更新缓存。这种处理方式能够解决延时双删的缓存击穿问题,能够最大限度的满足数据一致性问题。伪代码如下:
代码语言:javascript
复制
public void updateUserInfo(String key,UserBasic userBasic){
 redis.del(userBasic.getUserid());
 boolean success = userBasicMapper.update(data);
 if(success){
 redis.put("newdata",userBasic,200);
 }
 new Thread(new Runnable() {
 @Override
 public void run() {
 Thread.sleep(200);
 redis.delKey(userBasic.getUserid())
 }
 })
}
  • 第四方案:不删除缓存,数据库主从设置同步后返回,然后更新缓存或者直接读主库。这个我就不写伪代码了。大家理解就好,没理解透也没关系私信我。

建议

对于以上数据一致性解决方案,第四方案是最优选,在数据库主库操作没返回前,不清理缓存,以为这个时候数据库数据还没更新,和缓存的旧数据是一致的。主库更新完成之后,暂时使用操作数据更新缓存,确保了缓存数据和主库数据一致。在主从同步之后再异步更新缓存,确保了缓存和更新了数据之后的从库数据一致。比较完美的解决了以上问题。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 缓存一致性背景
  • 解决方案
  • 建议
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档