首页 > 其他分享 >高并发缓存架构实战和优化

高并发缓存架构实战和优化

时间:2024-05-03 18:55:05浏览次数:31  
标签:导致 缓存 架构 请求 数据库 并发 加锁

参考资料:

图灵课堂-https://vip.tulingxueyuan.cn

 

中小公司Redis缓存架构以及线上问题分析

直接写入数据库,然后更新redis;

正常低并发情况下,这种情况是暂时不会出现问题的,因为并发量并不高,不会出现各种各样的并发问题。

大厂线上大规模商品缓存数据冷热分离实战

使用缓存,主要是为了令常用的数据放到缓存中,不常用的数据最少放到缓存中,尽量提升缓存的空间利用率。

所以,就对缓存数据加上一个过期时间,这样可以让冷数据过期了节省缓存空间;同时针对查询到的数据再进行过期时间续期,让常用数据长时间停留在缓存中。

实战解决大规模缓存击穿导致线上数据库压力暴增

缓存击穿:缓存中没有,但是数据库有;就是大量请求到redis,查询不到数据,要落库查询,这样可能会导致大量的请求访问数据库,令数据库压力增长,可能会让数据库崩溃。此时可以针对缓存设置过期时间的时候,设置随机过期时间,保证少量的请求去访问数据库。

缓存穿透:缓存中没有,数据库中也没有。就是数据不存在,或者是从数据库直接物理删除,会导致查询缓存没有,数据库也没有;或者是黑客使用不存在的数据进行攻击。这样会令数据库压力暴增,可能会导致数据库崩溃。后端也可以限流,也可以设置一个IP黑名单。

或者缓存一个空的字符串,或者一个常量json串,尽量不要返回null。同时设置一个过期时间。但是这样并不会彻底避免这样的情况,同时也会让redis和数据库的请求压力增加;所以针对这样的情况可以使用布隆过滤器。

黑客攻击导致缓存穿透线上数据库宕机BUG

ddos攻击,可以进行限流操作;但是更好的方案是再加上一个布隆过滤器。

一行代码解决线上缓存穿透问题

返回一个空值,前端进行配合。

一次大V直播带货导致线上商品系统崩溃原因分析

冷门商品突然有大量的流量访问,此时针对这个key来说,压力很高;此时直接访问数据库,此时还有别的请求去访问数据库,可能会导致数据库的崩溃。

这些小概率事件是必须要规避的。冷门数据突然变成热点数据。

突发性热点缓存重建导致系统压力暴增问题分析

加锁。使用单例模式。双重检索机制。先查询缓存,没有;加锁,然后再查询缓存,如果没有就一个请求去查询数据库,后续请求都阻塞;当其执行完毕之后,后续再来线程再试一下就有数据返回了,不用继续执行后续操作。

但是这个还是有点问题,这个就在单节点中有用,如果每个服务器节点都自己构建,那么这样也不行,还有就是锁对象的问题,不能使用类锁等;

所以可以使用分布式锁解决这个问题。此时就重新构建一次。

基于DCL机制解决热点缓存并发重建问题实战

注意:锁的命名尽量要见名知意,不能随便进行简写,除非是项目或者公司有默认的简写值才行。

代码是编写完成功能之后,再去考虑进行优化。

使用DCL,先查缓存,如果没有;就加锁,加锁之后,再查缓存一次,如果没有再去查数据库。

Redis分布式锁解决缓存与数据库双写不一致问题实战

更新数据库和缓存不是原子性的,导致数据库和缓存的数据不一致。可能多个线程并发执行,一个线程执行时间太长,导致数据不一致。

如果是先写数据库,然后删除缓存,正常情况下是没有问题;但是如果中间卡顿了一下,就可能导致数据不一致。可以进一步优化使用延时双删,但是这个还不行,因为这个时间并不确定。

当然正常情况下是必须要考虑异常情况的。

所以可以使用分布式锁来实现这个功能。这是另外一个锁,锁名称要见名知意。

要解决这样的小概率情况必须要使用这样的代码,这样会导致代码量增大,会令代码变得复杂。这样会导致查询路径变得很深,但是这只是第一次会这样;工作中百分之九十以上得场景查询得都是热数据,所以后续的请求很早就返回数据了。使用大量的代码是解决小概率事件的。然后绝大部分请求不会一直走全部的代码。

优化方案:

很多情况下都是读多写少的情况。这样的情况可以使用读写锁。读读共享,并发量升高;读写,写写是互斥要加锁的。只有写的时候才会有不一致的情况发生。

读写锁在redisson中也是通过lua脚本来实现的,加锁的时候有一个标记,mode标识,是读还是写。读的时候类似重入锁,可以并发读。解锁的时候就是重入次数减一,直到减到0.

写的时候是互斥的。锁一定要是同一个。

加锁时先判断是读锁还是写锁,读读共享;读写就阻塞等待等。如果先是写锁,后续所有的线程都要进行等待。

 

如果是有读还有写,那么使用这个读写锁就不太合适了。具体场景具体分析。针对数据库和缓存来说,可以加读写锁。多个线程并发执行才有并发安全的问题。

大促压力暴增导致分布式锁串行争用问题优化实战

还有就是多次高并发查询,如果是有上万的请求来,请求的步骤都一样,查询缓存么有值;然后就是加锁,然后再查缓存,有了值就返回,并且解锁。这样加锁和解锁也是比较耗时的。所以还是可以优化的,如果可以确认代码可以再1秒中执行完毕,或者是百分之九十九点九,就可以使用tryLock,这个加上一个过期时间,如果时间到了,就直接不等待了,直接去访问缓存。但是如果1秒无法执行完成,那么就出现bug。

这个就是权衡。这就是架构思维。

一次微博明星热点事件导致系统崩溃原因分析

缓存雪崩,刚开始缓存少量失效,但是如果请求量越来越大,那么会导致错误放大,最终可能会导致系统崩溃;请求是越来越多,会导致连接没空余的,别的功能访问就受阻,可能最后导致崩溃。

此时可以进行限流,前端进行了限流,后端也进行限流。

利用多级缓存架构解决Redis线上集群缓存雪崩问题

此时可以使用多级缓存,加上一个JVM级别的缓存。

但是这个也是有问题的,热点数据是变化的,这个要考虑;还有就是如果不同的节点数据更新,可能会导致不同节点JVM缓存数据不一致,这个也是要避免的。

使用zk,或者MQ也是可以的,当一个节点的数据发生变化,发出消息,令别的节点订阅,进行修改;此时会有短时不一致的情况,此时就不要去考虑绝对一致性了,这样就太复杂了,有些过度设计了。只要不是长时间不一致就是可以接受的。zk也不能绝对一致。

正常来说是不会这么做的,因为增删改查是很频繁的,如果这样就会导致消息太多;不便维护;

可以再进行拆分,抽取出来一个热点缓存,监听所有的请求,进行计算,判断哪些是热点缓存,保证热点缓存的值保存在缓存中。可以使用实时计算。

标签:导致,缓存,架构,请求,数据库,并发,加锁
From: https://www.cnblogs.com/0630sun/p/18171351

相关文章

  • 底层架构
    一:角色分类(1)Coordinator协调器:协调器服务监视数据服务器上的历史服务。他们负责将区段分配给特定服务器,并确保区段在历史服务器之间保持良好的平衡。(2)Overlord:控制数据摄入任务的分配,Overlord服务监视数据服务器上的MiddleManager服务,并且是将数据摄取到Druid。他们负......
  • 架构每日一学 1:成为一名架构师,你必须具有“战略意图”
    本文首发于公众号:腐烂的橘子前言最近学习了《郭东白的架构课》,受益良多。作为一名普通程序员,有时候不禁想问公司里的架构师大牛是怎么成长的,为什么他可以是一名架构师,而我们只能在公司里写代码做需求?郭在文章中提出了很多超出以往认知的观点,让我重新审视了架构师这个职业。除......
  • 浏览器缓存
    浏览器缓存基本的原理就是:浏览器每次发起请求,都会先在浏览器缓存中查找该请求的结果以及缓存标识浏览器每次拿到返回的请求结果都会将该结果和缓存标识存入浏览器缓存中按位置分类ServerworkerServiceWorker是运行在浏览器背后的独立线程,一般可以用来实现缓存功能。使......
  • 从0到10Wqps,大厂的智能客服平台,如何实现架构演进?
    文章很长,且持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录博客园版为您奉上珍贵的学习资源:免费赠送:《尼恩Java面试宝典》持续更新+史上最全+面试必备2000页+面试必备+大厂必备+涨薪必备免费赠送:《尼恩技术圣经+高并发系列PDF》,帮你实现技术自由,完成职业升级,薪......
  • Redis持久化、主从与哨兵架构详解
    参考图灵课堂https://zhuanlan.zhihu.com/p/443951927https://blog.csdn.net/weixin_37548768/article/details/124538778?spm=1001.2014.3001.5502https://www.runoob.com/redis/redis-transactions.html   redis支持持久化到磁盘,这样可用进一步保证数据的完整性。re......
  • uniapp 清除缓存
    //清除所有数据clearAppUserData(){plus.android.importClass("android.app.ActivityManager");varContext=plus.android.importClass("android.content.Context");varam=plus.android......
  • 缓存中的这7个坑,我把坑惨了!!!
    前言缓存在我们日常工作中,经常会使用,但如果用不好坑也挺多的。这篇文章总结了我工作中使用缓存遇到过的7个坑,还是非常有参考价值得,希望对你会有所帮助。1缓存穿透大部分情况下,加缓存的目的是:为了减轻数据库的压力,提升系统的性能。一般情况下,如果有用户请求过来,先查缓存,如果......
  • Redis 缓存/分布式锁/消息队列的应用
    缓存缓存是最常见的的应用类型,因为同等配置下,如果一台MySQL能支持上千的QPS,那么一台redis支持的QPS能达到上万,十倍于MySQL。客户端将热点数据存储在redis中,优先从redis读取数据,可以减轻数据库的访问压力。但将redis作为缓存,也存在一些问题,例如数据不一致。数据不一致场景:redis......
  • Redis 高可用之主从架构与哨兵集群
    在redis实例宕机后,通过AOF和RDB可以恢复数据,这是高可用的一部分。但是在宕机期间,如何持续提供服务呢?这是高可用的另一部分。redis的方案是主从库模式,在主库宕机后,由从库提供服务。主从架构遵从单线程处理原则,从库只接受读请求,写请求都在主库执行,主库执行后再同步到从库中去。在......
  • Unity游戏框架设计之缓存池管理器
    Unity游戏框架设计之缓存池管理器简单介绍在游戏运行的过程中,我们可能遇到这样的需求,即创建大量相同类型的敌人。在传统方法中,我们将对每一个敌人都重新创建,但这样是效率低且占据内存的。为此我们可以这样做,所有敌人在创建时,都从敌人缓存池中取出敌人对象,当敌人死亡时,则将敌人......