亿级系统的redis缓存如何设计???(代码片段)

微观技术 微观技术     2022-11-28     243

关键词:

知识分享,以技会友。大家好,我是Tom哥。阅读本文大约需要 15 分钟。

缓存设计可谓老生常谈了,早些时候都是采用memcache,现在大家更多倾向使用redis,除了知晓常用的数据存储类型,结合业务场景有针对性选择,好像其他也没有什么大的难点。

工程中引入Redis Client二方包,初始化一个Bean实例RedisTemplate ,一切搞定,so easy。

如果是几十、几百并发的业务场景,缓存设计可能并不需要考虑那么多,但如果是亿级的系统呢?



首先,先了解缓存知识图谱


早期的缓存用于加速CPU数据交换的RAM。随着互联网的快速发展,缓存的应用更加宽泛,用于数据高速交换的存储介质都称之为缓存。

使用缓存时,我们要关注哪些指标?缓存有哪些应用模式?以及缓存设计时有哪些Tip技巧?一图胜千言,如下:


七大经典问题缓存在使用过程不可避免会遇到一些问题,对于高频的问题我们大概归为了7类。具体内容下面我们一一道来1、缓存集中失效

当业务系统查询数据时,首先会查询缓存,如果缓存中数据不存在,然后查询DB再将数据预热到Cache中,并返回。缓存的性能比 DB 高 50~100 倍以上。

很多业务场景,如:秒杀商品、微博热搜排行、或者一些活动数据,都是通过跑任务方式,将DB数据批量、集中预热到缓存中,缓存数据有着近乎相同的过期时间

当过这批数据过期时,会一起过期,此时,对这批数据的所有请求,都会出现缓存失效,从而将压力转嫁到DB,DB的请求量激增,压力变大,响应开始变慢。

那么有没有解呢?

当然有了。

我们可以从缓存的过期时间入口,将原来的固定过期时间,调整为过期时间=基础时间+随机时间,让缓存慢慢过期,避免瞬间全部过期,对DB产生过大压力。

2、缓存穿透

不是所有的请求都能查到数据,不论是从缓存中还是DB中。

假如黑客攻击了一个论坛,用了一堆肉鸡访问一个不存的帖子id。按照常规思路,每次都会先查缓存,缓存中没有,接着又查DB,同样也没有,此时不会预热到Cache中,导致每次查询,都会cache miss

由于DB的吞吐性能较差,会严重影响系统的性能,甚至影响正常用户的访问。

解决方案:

  • 方案一:查存DB 时,如果数据不存在,预热一个特殊空值到缓存中。这样,后续查询都会命中缓存,但是要对特殊值,解析处理。
  • 方案二:构造一个BloomFilter过滤器,初始化全量数据,当接到请求时,在BloomFilter中判断这个key是否存在,如果不存在,直接返回即可,无需再查询缓存和DB
  • 3、缓存雪崩

    缓存雪崩是指部分缓存节点不可用,进而导致整个缓存体系甚至服务系统不可用的情况。

    分布式缓存设计一般选择一致性Hash,当有部分节点异常时,采用 rehash 策略,即把异常节点请求平均分散到其他缓存节点。但是,当较大的流量洪峰到来时,如果大流量 key 比较集中,正好在某 1~2 个缓存节点,很容易将这些缓存节点的内存、网卡过载,缓存节点异常 Crash,然后这些异常节点下线,这些大流量 key 请求又被 rehash 到其他缓存节点,进而导致其他缓存节点也被过载 Crash,缓存异常持续扩散,最终导致整个缓存体系异常,无法对外提供服务。

    解决方案:

  • 方案一:增加实时监控,及时预警。通过机器替换、各种故障自动转移策略,快速恢复缓存对外的服务能力
  • 方案二:缓存增加多个副本,当缓存异常时,再读取其他缓存副本。为了保证副本的可用性,尽量将多个缓存副本部署在不同机架上,降低风险。
  • 4、缓存热点

    对于突发事件,大量用户同时去访问热点信息,这个突发热点信息所在的缓存节点就很容易出现过载和卡顿现象,甚至 Crash,我们称之为缓存热点。



    这个在新浪微博经常遇到,某大V明星出轨、结婚、离婚,瞬间引发数百千万的吃瓜群众围观,访问同一个key,流量集中打在一个缓存节点机器,很容易打爆网卡、带宽、CPU的上限,最终导致缓存不可用。

    解决方案:

  • 首先能先找到这个热key来,比如通过Spark实时流分析,及时发现新的热点key。
  • 将集中化流量打散,避免一个缓存节点过载。由于只有一个key,我们可以在key的后面拼上有序编号,比如key#01key#02。。。key#10多个副本,这些加工后的key位于多个缓存节点上。
  • 每次请求时,客户端随机访问一个即可
  • 可以设计一个缓存服务治理管理后台,实时监控缓存的SLA,并打通分布式配置中心,对于一些hot key可以快速、动态扩容。

    5、缓存大Key

    当访问缓存时,如果key对应的value过大,读写、加载很容易超时,容易引发网络拥堵。另外缓存的字段较多时,每个字段的变更都会引发缓存数据的变更,频繁的读写,导致慢查询。如果大key过期被缓存淘汰失效,预热数据要花费较多的时间,也会导致慢查询。

    所以我们在设计缓存的时候,要注意缓存的粒度,既不能过大,如果过大很容易导致网络拥堵;也不能过小,如果太小,查询频率会很高,每次请求都要查询多次。

    解决方案:

  • 方案一:设置一个阈值,当value的长度超过阈值时,对内容启动压缩,降低kv的大小
  • 方案二:评估大key所占的比例,由于很多框架采用池化技术,如:Memcache,可以预先分配大对象空间。真正业务请求时,直接拿来即用。
  • 方案三:颗粒划分,将大key拆分为多个小key,独立维护,成本会降低不少
  • 方案四:大key要设置合理的过期时间,尽量不淘汰那些大key
  • 6、缓存数据一致性

    缓存是用来加速的,一般不会持久化储存。所以,一份数据通常会存在DB缓存中,由此会带来一个问题,如何保证这两者的数据一致性。另外,缓存热点问题会引入多个副本备份,也可能会发生不一致现象。


    解决方案:

  • 方案一:当缓存更新失败后,进行重试,如果重试失败,将失败的key写入MQ消息队列,通过异步任务补偿缓存,保证数据的一致性。
  • 方案二:设置一个较短的过期时间,通过自修复的方式,在缓存过期后,缓存重新加载最新的数据
  • 7、数据并发竞争预热

    互联网系统典型的特点就是流量大,一旦缓存中的数据过期、或因某些原因被删除等,导致缓存中的数据为空,大量的并发线程请求(查询同一个key)就会一起并发查询数据库,数据库的压力陡然增加。


    如果请求量非常大,全部压在数据库,可能把数据库压垮,进而导致整个系统的服务不可用。

    解决方案:

  • 方案一:引入一把全局锁,当缓存未命中时,先尝试获取全局锁,如果拿到锁,才有资格去查询DB,并将数据预热到缓存中。虽然,client端发起的请求非常多,但是由于拿不到锁,只能处于等待状态,当缓存中的数据预热成功后,再从缓存中获取
  • 为了便于理解,简单画了个流程图。这里面特别注意一个点,由于有一个并发时间差,所以会有一个二次check缓存是否有值的校验,防止缓存预热重复覆盖。

  • 方案二:缓存数据创建多个备份,当一个过期失效后,可以访问其他备份。
  • 写在最后

    缓存设计时,有很多技巧,优化手段也是千变万化,但是我们要抓住核心要素。那就是,让访问尽量命中缓存,同时保持数据的一致性。




    关于我:前阿里架构师,出过专利,竞赛拿过奖,CSDN博客专家,负责过电商交易、社区、营销、金融等业务,多年团队管理经验,爱思考,喜欢结交朋友

    「长按」↓↓↓ 二维码,拉你进群,一线大厂技术交流

    推荐阅读

    淘宝双11千亿交易额的系统架构演变

    淘宝订单自动确认收货的N种实现,秒杀面试官

    如何设计一个高性能的秒杀系统


    微信小程序是如何设计百亿级用户画像分析系统的?(代码片段)

    导语| “We分析”是微信小程序官方推出的数据分析平台,其中画像洞察是其中一个非常重要的功能模块。微信开发工程师钟文波将描述We分析画像系统各模块是如何设计,在介绍基础标签模块之后,重点讲解用户分... 查看详情

    万级tps亿级流水-中台账户系统架构设计(代码片段)

    万级TPS亿级流水-中台账户系统架构设计背景业务模型应用层设计数据层设计日切对账背景我们需要给所有前台业务提供统一的账户系统,用来支撑所有前台产品线的用户资产管理,统一提供支持大并发万级TPS、亿级流水、数据... 查看详情

    万级tps亿级流水-中台账户系统架构设计(代码片段)

    万级TPS亿级流水-中台账户系统架构设计背景业务模型应用层设计数据层设计日切对账背景我们需要给所有前台业务提供统一的账户系统,用来支撑所有前台产品线的用户资产管理,统一提供支持大并发万级TPS、亿级流水、数据... 查看详情

    刷爆朋友圈,alibaba出品亿级并发设计速成笔记太香了(代码片段)

    前言如何提升系统性能,设计出一个靠谱的系统是每一个架构师或者正在往架构师方向进阶的同僚们都需要考虑的问题。公司所处的行业,业务场景决定了你设计的系统演进过程,不过万变不离其宗,系统设计和... 查看详情

    浅谈缓存写法:内存缓存该如何设计(代码片段)

    分析设计假设有个项目有比较高的并发量,要用到多级缓存,如下:在实际设计一个内存缓存前,需要考虑的问题:1:内存与Redis的数据置换,尽可能在内存中提高数据命中率,减少下一级的压力。2:内存容量的限制,需要控... 查看详情

    redis性能调优——缓存设计优化(代码片段)

    ...是一个开源的高性能的Key-Value服务器。本篇主要介绍一下缓存的设计与优化。1.缓存的受益与成本-说明缓存的受益1、加速读写,通过缓存加速读写速度,例如CPUL1/L2/L3Cache、LinuxpageCache加速硬盘读写、浏览器缓存、Ehcache缓... 查看详情

    亿级流量电商详情页系统实战(第二版)

    来源:B站 亿级流量电商详情页系统实战(第二版) 电商网站详情页架构:P3:架构1:页面静态化架构; 小电商,静态页面少Velocity/FreeMarker/Thymeleaf模板模板+数据=》最终的页面如果模板或数据有变更,则需要重新渲... 查看详情

    如何解决redis缓存雪崩击穿与穿透(代码片段)

    Redis最常用使用的场景就是作为业务系统的缓存,既然是作为缓存,那么就不免会碰到缓存常见的问题,即雪崩、击穿与穿透,什么是缓存雪崩、击穿与穿透以及如何解决这几个问题呢?今天我们一起来探讨一... 查看详情

    day749.旁路缓存:redis是如何工作的-redis核心技术与实战(代码片段)

    ...存是什么?Redis作为一个缓存软件,是一个独立的系统软件,和业务应用程序是两个软件,当我们部署了Redis实例后,它只会被动地等待客户端发送请求ÿ 查看详情

    redis学习笔记23——旁路缓存:redis是如何工作的?(代码片段)

    计算机系统中,默认有两种缓存:CPU里面的末级缓存,即LLC,用来缓存内存中的数据,避免每次从内存中存取数据;内存中的高速页缓存,即pagecache,用来缓存磁盘中的数据,避免每次从磁盘中... 查看详情

    redis学习笔记23——旁路缓存:redis是如何工作的?(代码片段)

    计算机系统中,默认有两种缓存:CPU里面的末级缓存,即LLC,用来缓存内存中的数据,避免每次从内存中存取数据;内存中的高速页缓存,即pagecache,用来缓存磁盘中的数据,避免每次从磁盘中... 查看详情

    redis-缓存设计-记录前一个小时和最新的日志(代码片段)

    需求记录最新的日志99条同时记录上一个小时和最近一个小时的日志出现次数记录日志代码/****@paramconn连接*@paramname模块名字*@parammessage日志信息*@paramlevel日志等级*@paramtimeout重试时间*/publicstaticvoidlogCommon(Jedisconn,Stringname,Stringmessag... 查看详情

    亿级京东应用架构设计与治理(代码片段)

    👇👇关注后回复 “进群” ,拉你进程序员交流群👇👇经过十年的业务快速发展,京东信息系统复杂度越来越高:一般电商系统只需关心“进销存”中的“销”,京东系统需要管理采购(进&... 查看详情

    基于redis和nginx实现高并发缓存架构(代码片段)

    目录1缓存架构设计1.1缓存架构设计2Redis集群高级应用3Nginx缓存3.1OpenRestry安装3.2浏览器缓存3.2.1NginxWeb缓存配置3.2.2Http缓存控制头3.3代理缓存3.3.1proxy_cache3.3.2缓存操作4Canal的使用1缓存架构设计一谈到缓存架构,很多人想到的是... 查看详情

    day750.redis缓存淘汰替换策略:redis是如何工作的-redis核心技术与实战(代码片段)

    Redis缓存淘汰替换策略Hi,阿昌来也,今天学习记录的是关于Redis缓存淘汰替换策略。Redis缓存使用内存来保存数据,避免业务应用从后端数据库中读取数据,可以提升应用的响应速度。那么,如果把所有要访问... 查看详情

    分布式问题

    ...统中缓存架构?  节选自:  【中华石杉】亿级流量电商详情页系统的大型高并发与高可用缓存架构实战 P1如何让redis集群支撑几十万QPS高并发+99.99%高可用+TB级海量数据+企业级数据备份与恢复?:Redis企业级集... 查看详情

    应用缓存预热方案设计(代码片段)

    ...需要对缓存数据进行预热。所以需要设计一套通用的预热系统。所谓预热,其实就是提前请求数据,使缓存生效。缓存和预热有关联,但是可以设计成独立的两套系统。缓存框架目标是实现去除样板代码getDataWithCache(L... 查看详情

    亿级流量电商详情页系统的大型高并发与高可用缓存架构实战

    对于高并发的场景来说,比如电商类,o2o,门户,等等互联网类的项目,缓存技术是Java项目中最常见的一种应用技术。然而,行业里很多朋友对缓存技术的了解与掌握,仅仅停留在掌握redis/memcached等缓存技术的基础使用,最多... 查看详情