Redis缓存设计以及经典问题分析

发表于:2022-8-31 09:26

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:陈婷7981    来源:掘金

  1 缓存基本思想
  1、不同的存储介质访问延迟不一样,相同成本存储容量不一样:
  SSD/DISK、Memory、L3 cache、L2 cache、L1 cache 五种存储介质,访问延迟逐渐降低,但是同等成本的容量却逐渐增大。
  2、时间局限性原理
  被获取过一次的数据在未来会被多次获取
  3、以空间换时间
  开辟一块高速独立空间,提供高速访问
  4、性能成本权衡
  访问延迟性低、性能越高,等容量成本越高
  2 缓存优势
  提升访问性能
  降低网络拥堵
  减轻服务负载
  增强可扩展性
  3 缓存代价
  系统复杂性提高
  存储和部署成本变高
  数据一致性问题
  4 缓存的三种模式
  4.1 Cache Aside 旁路缓存
  写操作:更新 DB 之后,直接将 key 从缓存中删除;
  读操作:先读缓存,如果没有,则读 DB,同时将 DB 的数据同步到缓存中。
  特点:业务端处理所有数据访问细节,同时利用 lazy 懒加载思想,更新 DB 之后,直接删除缓存并通过 DB 更新,确保数据以 DB 为准,可以大幅降低缓存和 DB 之间的不一致的概率。
  缺点:
  1、如果删除缓存失败,可能会有问题;
  解决方法:失败增加监控
  2、如果同时有比较高的QPS访问刚插入或者更新的数据,可能会打垮DB;
  解决方法:使用多线程异步执行查询,防止这种问题。
  场景:读多写少。比如用户数据,用户修改用户信息很少,但是各种业务场景用到用户数据的读场景比较多。
  4.2 Read/Write Through
  核心思想:读写缓存和 DB 的操作,都有一个中间的数据服务代理。
  写操作:先查缓存,如果缓存不存在,则只更新 DB;如果缓存中存在,则先更新缓存,再更新DB,然后返回;
  读操作:先查缓存,如果命中则直接返回。否则从 DB 中加载,然后回种到缓存中再返回。
  特点:业务端不需要关心数据细节,系统隔离性好。
  4.3 write-Back 或者 Write-Behind
  承接 Write Through,写操作更新完缓存之后,异步回写数据到 DB 或者批量回写数据到 DB。
  缺点:异步或者批量回写,可能会导致数据丢失。
  特点:合并或者异步写 DB,DB 压力小。
  使用场景:写频率很高,但是对于数据一致性要求不太高的业务。
  5 redis 常见面试题
  5.1 redis雪崩
  概念:大量的应用请求无法在 Redis 缓存中进行处理,紧接着,
  应用将大量请求发送到数据库层,导致数据库层的压力激增。
  原因:
  1、缓存中有大量数据同时过期,导致大量请求无法得到处理
  2、Redis 缓存实例发生故障宕机了
  解决方案:
  原因1:方法1:避免给大量的数据设置相同的过期时间;方法2: 降级直接返回预定义信息、空值或是错误信息
  原因2:方法1: 在业务系统中实现服务熔断或请求限流机制;方法2: 服务端 限流
  事前预防:使用主从节点 构建Redis 缓存高可靠集群
  5.2 击穿
  概念:1、是发生在某个热点数据失效的场景下,大量请求直接访问 DB,DB 压力骤增,业务响应延迟。
  原因:热点 key 过期失效或者同时失效。
  解决办法:热点 key 不设置过期时间;或者设置过期时间为基础时间+随机时间。
  5.3 穿透
  概念:要访问的数据既不在 Redis 缓存中,也不在数据库中,导致请求在访问缓存时,发生缓存缺失,再去访问数据库时,发现数据库中也没有要访问的数据。
  原因:1、业务层误删除数据了;2、恶意攻击:专门访问数据库中没有的数据。
  解决方法:
  1、缺省值或者空值
  2、使用布隆过滤器快速判断数据是否存在,
  避免从数据库中查询数据是否存在,减轻数据库压力。
  3、前端进行请求检测
  5.4 bigkey
  概念:一个缓存 key,存储数据过多。比如一个上万记录的List;
  危害:
  1、造成内存分配不均匀。比如在 Redis cluster 或者 codis 中,会造成节点的内存使用不均匀;
  2、超时阻塞。因为 Redis 单线程特性,如果操作某个 Bigkey 耗时比较久,则后面的请求会被阻塞。
  3、网络阻塞,消耗带宽。
  4、过期删除,会很慢,会阻塞redis。如果 Bigkey 设置了过期时间,当过期后,这个 key 会被删除,假如没有使用 Redis 4.0 的过期异步删除,
  就会存在阻塞 Redis 的可能性,并且慢查询中查不到(因为这个删除是内部循环事件)。
  如何发现:
  redis命令: redis-cli --bigkeys
  解决方法:
  1、删除bigkey。
  redis4.0 之后,异步删除;
  集合类型:用scan,读取部分数据删除;
  hash类型,用Hscan,读取部分数据删除
  2、拆分
  string类型,拆分成多个key
  集合或者hash类型,拆分成多个list或者hash
  5.5 热key
  概念: 所谓热key问题就是,突然有几十万的请求去访问redis上的某个特定key。
  那么,这样会造成流量过于集中,达到物理网卡上限,从而导致这台redis的服务器宕机。
  解决:
  1、二级缓存——本地缓存。比如利用ehcache,或者一个HashMap都可以。在你发现热key以后,把热key加载到系统的JVM中。
  针对这种热key请求,会直接从jvm中取,而不会走到redis层。
  2、备份热key。不要让key走到同一台redis上不就行了。我们把这个key,在多个redis上都存一份不就好了。
  接下来,有热key请求进来的时候,我们就在有备份的redis上随机选取一台,进行访问取值,返回数据。
  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号