赞
踩
Redis 会把 MySQL 中经常被查询的数据缓存起来,比如热点数据,这样当用户来访问的时候,就不需要到 MySQL 中去查询了,而是直接获取 Redis 中的缓存数据,从而降低了后端数据库的读取压力。如果说用户查询的数据 Redis 没有,此时用户的查询请求就会转到 MySQL 数据库,当 MySQL 将数据返回给客户端时,同时会将数据缓存到 Redis 中,这样用户再次读取时,就可以直接从 Redis 中获取数据。
本篇内容包括:关于 Redis 缓存,缓存相关问题(包括 Redis 缓存热 key 问题、Redis 缓存穿透问题、关于布隆过滤器、Redis 缓存击穿问题 与 Redis 缓存雪崩问题的相关内容),Redis 缓存预热,Redis 缓存过期与内存淘汰策略。
在请求达到后端之后,对需要进行缓存的接口,会先去 Redis 中找有无数据,没有的话会继续走正常的业务流程,然后将查询到的结果返回给客户端的同时也放在 Redis 中一份,下次相同请求进来后,就可以直接从 Redis中 拿到数据。
在进行缓存之后,相同的请求在缓存时间内是不会去读取数据库的,但是此时如果修改了数据库,则接口返回的数据就不能保证和数据库一致,因此在增、删、改时我们需要刷新缓存。
缓存更新的策略有很多,这里比较两种情况
所谓热 key 问题就是,突然有几十万的请求去访问 Redis 上的某个特定 key,那么这样会造成流量过于集中,达到物理网卡上限,从而导致这台 Redis 的服务器宕机引发雪崩。
针对热 key 的解决方案:
访问一个缓存和数据库都不存在的 key,此时会直接打到数据库上,并且查不到数据,没法写缓存,所以下一次同样会打到数据库上。此时,缓存起不到作用,请求每次都会走到数据库,流量大时数据库可能会被打挂。此时缓存就好像被“穿透”了一样,起不到任何作用。
缓存穿透解决方案:
接口校验:在正常业务流程中可能会存在少量访问不存在 key 的情况,但是一般不会出现大量的情况,所以这种场景最大的可能性是遭受了非法攻击。可以在最外层先做一层校验:用户鉴权、数据合法性校验等,例如商品查询中,商品的 ID 是正整数,则可以直接对非正整数直接过滤等等。
缓存空值:当访问缓存和 DB 都没有查询到值时,可以将空值写进缓存,但是设置较短的过期时间,该时间需要根据产品业务特性来设置。
布隆过滤器:使用布隆过滤器存储所有可能访问的 key,不存在的 key 直接被过滤,存在的 key 则再进一步查询缓存和数据库。
布隆过滤器的特点是判断不存在的,则一定不存在;判断存在的,大概率存在,但也有小概率不存在。并且这个概率是可控的,我们可以让这个概率变小或者变高,取决于用户本身的需求。
布隆过滤器由一个 bitSet 和 一组 Hash 函数(算法)组成,是一种空间效率极高的概率型算法和数据结构,主要用来判断一个元素是否在集合中存在。
HashMap 和 布隆过滤器:其实当数据量不大时,HashMap 实现起来一点问题都没有,而且还没有误判率。不过,当数据量上去后,布隆过滤器的空间优势就会开始体现,特别是要存储的 key 占用空间越大,布隆过滤器的优势越明显。
某一个热点 key,在缓存过期的一瞬间,同时有大量的请求打进来,由于此时缓存过期了,所以请求最终都会走到数据库,造成瞬时数据库请求量大、压力骤增,甚至可能打垮数据库。
缓存击穿解决方案:
大量的热点 key 设置了相同的过期时间,导在缓存在同一时刻全部失效,造成瞬时数据库请求量大、压力骤增,引起雪崩,甚至导致数据库被打挂。缓存雪崩其实有点像“升级版的缓存击穿”,缓存击穿是一个热点 key,缓存雪崩是一组热点 key。
缓存雪崩解决方案
缓存预热就是系统上线后,提前将相关的缓存数据直接加载到缓存系统。避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据!
缓存预热就是系统启动前,提前将相关的缓存数据直接加载到缓存系统。避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据!
缓存预热解决方案:
日常例行统计数据访问记录,统计访问频度较高的热点数据
利用 LRU 数据删除策略, 构建数据留存队列例如:Storm 与 Kafka 配合
将统计结果中的数据分类, 根据级别, Redis 优先加载级别较高的热点数据
利用分布式多服务器同时进行数据读取,提速数据加载过程
缓存预热实施:
使用脚本程序固定触发数据预热过程
如果条件允许, 使用了 CDN(内容分发网络), 效果会更好。
Redis 主要有 2 种过期删除策略:
假设 Redis 每次定期随机查询 key 的时候没有删掉,这些 key 也没有做查询的话,就会导致这些 key 一直保存在 Redis 里面无法被删除,这时候就会走到 Redis 的内存淘汰策略。
Redis 的 内存淘汰策略是指在 Redis 的用于缓存的内存不足时,怎么处理需要新写入且需要申请额外空间的数据。
Redis 的内存淘汰策略的选取并不会影响过期的 key 的处理。内存淘汰策略用于处理内存不足时的需要申请额外空间的数据;过期策略用于处理过期的缓存数据。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。