什么是缓存?

通俗来讲,缓存就是提前准备好的数据,存储在内存中,方便应用快速访问。比如一个固定的查询请求,没缓存的话,查询语句会直接打到数据库上,请求数不多的时候,没有什么影响,但是当并发请求很多时,就会造成数据库负载,影响结果返回时间。 如果采用缓存技术,将这个查询结果预先存在内存中,那当请求来时,直接调用该数据,不用再去查数据库,这样就能解决并发过大时出现的问题。

redis是什么?

Redis(Remote Dictionary Server,远程字典服务)是一个速度非常快的非关系数据库。
它可以存储键值对,支持的 5 种数据类型分别是:String(字符串)、Hash(哈希)、List(列表)、Set(集合)、Zset(有序集合)。
它可以将存储在内存的键值对数据持久化到硬盘,可以使用复制特性来扩展读性能,还可以使用客户端分片来扩展写性能。
主要用于:缓存、数据共享分布式、分布式锁、全局 ID、计数器、限流、购物车、消息队列、抽奖、点赞、签到、打卡等场景。

Redis 缓存怎么用?


Redis 一般和其他数据库(如:MySQL)搭配使用,用来减轻后端数据库的压力。

 Redis 会把 MySQL 中经常被查询的数据缓存起来,这样当用户来访问的时候,直接从 Redis 中获取缓存的数据就可以了。
如果 Redis 中没有用户所要查询的数据,就会去 MySQL 查询,当数据返回给客户端时,同时也会将数据缓存到 Redis 中,下次就可以直接从 Redis 中获取了。

 如何测试redis缓存?

1. 设计的合理性
确认缓存的应用场景:

评估业务场景是否真的需要使用缓存;

评估 Redis 与 DB 数据短暂不一致对业务的影响。

规范键值对的设计:

key:

一般使用业务名或数据库名作为前缀,以冒号(:)分隔来构造 key 名,不使用含义不清的 key 或特别长的 key;命名中只能出现小写字母、数字、点(.)和冒号(:)。不要包含特殊字符,如下划线、空格、换行、单双引号以及其他转义字符;

value:

禁止超过 10KB 的 String 类型的大 key,防止网卡流量、慢查询。非 String 类型的大 key,不要使用 del 删除,要使用 hscan、sscan、zscan 方式渐进删除。

选择合适的缓存模式:

旁路缓存模式/读写穿透模式/异步缓存写入

旁路缓存模式:写:先更新 DB,然后直接删除 cache

                         读:先从 cache 中读取数据,如果读取到就直接返回

                                如果从 cache 中读取不到数据的话,就从 DB 中读取数据返回

                                同时把数据放到 cache 中,达到数据一致性

读写穿透模式: 写:先从 cache 中查数据,如果 cache 中不存在,直接更新 DB

                                 如果 cache 中存在,就先更新 cache,然后 cache 服务自己去更新 DB

                           读:先从 cache 中读取数据,如果读取到就直接返回 

                                  如果读取不到,先更新 DB 中数据到 cache 中,然后返回

异步缓存写入:异步缓存写入和读写穿透很相似,两者均是服务端把 cache 视为主要数据存储,都是由 cache 服务来负责 cache 和 DB 的读写。但是,两个又有很大的不同:1.Read/Write Through 是同步更新 cache 和 DB;2.Write Behind Caching 则是只更新缓存,不直接更新 DB,而是改为异步批量的方式来更新 DB。

确认缓存的更新策略:

1. 先更新数据库,再更新缓存;

2. 先更新缓存,再更新数据库;

3. 先淘汰缓存,再更新数据库;

4. 先更新数据库,再淘汰缓存。(推荐)

确认缓存的过期机制:

主动的定期删除/被动的惰性删除

是否有缓存预热机制:

数据量不大的时候可以不进行缓存预热,或者可以在项目启动的时候自动进行加载。

数据量很大的时候,一定要保证热点数据提前加载到缓存。

确认缓存的淘汰策略:

淘汰最久没有使用的数据:LRU(Least Recently Used)

淘汰最不频繁使用的数据:LFU(Least Frequently Used)

淘汰最先放入缓存的数据:FIFO (first in first out)

评估业务所需缓存空间大小

缓存时间设置合理性:

缓存时间太长会导致用户访问到的数据一直是老的,缓存设置时间太短对数据库访问会比较频繁,所以要设置合理,最好清楚实际数据更新的频次后再设置。
 

验证基本功能
缓存增加:增加缓存,校验功能和数据是否正确,DB 中的数据跟 Redis 是否一致,缓存过期时间与设计是否一致;

缓存更新:更新缓存,校验功能和数据是否正确,DB 中的数据跟 Redis 是否一致;缓存过期时间与设计是否一致;对同一条数据并发执行更新和查询操作,校验功能和数据是否正确,DB 中的数据跟 Redis 是否一致;缓存过期时间与设计是否一致;

缓存删除:删除缓存,校验功能和数据是否正确,再次请求,缓存是否被正确写入,DB 中的数据跟 Redis 是否一致;

缓存过期:设置 Redis 过期时间,校验缓存是否正常过期失效。再次写入缓存,缓存过期时间被更新。(可通过修改服务器时间或手动修改缓存的 TTL)

缓存读取:校验数据在缓存和 DB 中都存在时,系统功能是否正常;校验数据在 DB 存在,但缓存中不存在时,系统功能是否正常;校验数据在缓存和 DB 中都不存在时,系统功能是否正常;验证 DB 返回的数据异常时,没有去缓存;

验证特殊场景
缓存超时:校验缓存查询达到超时时间后,未返回指定的数据,对系统的影响。

缓存穿透:不断查询一个 DB 和缓存中一定不存在的数据,验证返回数据为空。

缓存雪崩:校验缓存是否采用了相同的过期时间。如果缓存大指量同时失效,验证系统功能是否正常,性能指标是否正常。

缓存击穿:缓存中的数据没有人查询过 ,第一次就大并发的访问;缓存中的某条数据刚好失效后,就进行大并发访问,校验功能是否正常,各项性能指标是否正常。

缓存预热:大批量缓存在同一时间点过期,验证缓存预热耗时及预热时机。在缓存预热期间请求更新接口和查询接口,验证返回数据的正确性。

缓存上限:

校验缓存淘汰参数配置与预期一致:增加缓存至达到 maxmemory 限制时(可修改 redis.conf 配置文件中配置的最大可用内存值),再次请求查询,数据返回正确,且缓存淘汰正确。

缓存停服:校验关闭缓存服务后,系统功能和性能的运行情况。验证重启 Redis 服务后,请求查询返回的数据正确,DB 中的数据跟 Redis 一致。

测试并发:

并发请求缓存中有的数据,校验返回数据是否正确,各项性能指标是否正常。

并发请求缓存中没有但 DB 中有的数据,校验返回数据是否正确,各项性能指标是否正常。

并发请求缓存中没有 DB 中也没有的数据,校验返回数据是否为空,各项性能指标是否正常。

性能测试:一般用 redis-benchmark 测试一些场景的性能基准,比如:

对比单机和集群 Redis 吞吐量;

评估不同类型的存储性能;

对比开启和关闭持久化的吞吐量;

对比调优前后的吞吐量;

对比不同版本的 Redis 的吞吐量;

监控线上的稳定性:

监控缓存的命中率:评估缓存的设计是否达到预期;

监控中间件:CPU、内存是否异常;

监控是否有某个 key 过大;

监控是否存在缓存的频繁更新。

 

来源:微信公众号:毕小烦

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐