概念:什么是缓存命中率?
所谓缓存命中(Cache Hit),通常是指用户侧程序成功地从缓存系统中获取了数据,而非因为缓存数据过期而失效,或根本不存在,或被LRU(最近最少使用到的,即least recently used)算法所淘汰导致访问不到缓存数据,甚至需要从数据库预热(获取新的)一份数据。因此,缓存命中率=缓存命中的次数/请求缓存数据的总次数。
提高缓存命中率(下面均以Redis为例,数据库以MySQL为例)
1. 缓存更新机制(这里用“时机”2字可能更恰当)。
一个比较常见的例子:更新用户信息缓存,当用户信息字段有变化的时候,系统通过MQ(假设是RabbitMQ)发送更新消息给相应的Exchange(交换器),接着交给对应的客户端去处理,从而达到更新对应Redis Key下面缓存的目的。
再例如:让更新缓存数据的操作通过消息队列以可控的速度从 MySQL 中获取更新,这样不至于让让数据库压力过大,也不至于降低缓存的命中率。
总的原则:缓存的更新速度应该保持在一个可控的范围内,高频访问的数据尤其要重视其业务使用场景,从而设计一份适合当前产品的缓存更新机制。像定时主动更新缓存这种方式要少用,除非产品规划上不得不这么做,最好是被动且丢到缓存更新消息队列中让 Worker 自己慢慢消化。
2. 缓存粒度的选择。
通常来说,一个设计良好的缓存系统,缓存Key的命名规则比较清晰,当然缓存的数据类型和数据大小也会比较适宜。若一个Key 命名为 userInfo:id:112 的缓存丢了除用户信息外的订单列表信息的话,那么每次这个id为112的用户的订单状态有变化的时候,我们都需要去更新这个Key的数据,这可能让我们面临两个问题,一个是代码可维护性降低,一个是缓存并发更新导致数据不一致的问题(什么?你想要加锁,劝你别这么做,因为锁降低了缓存访问效率的同时还增加了代码复杂度)
3. 缓存失效风暴的风险侦测
通常来说,程序应该能完全避免缓存失效带来的系统瘫痪的风险,比如我们能够通过一个通知系统的Dashboard来获得一些关键key的ttl(剩余存活时间)以及访问次数等数据,这样就有利于避免缓存失效带来的风险,从而提高缓存命中率。
小知识:在redis中可以运行info命令查看redis服务的状态信息,其中keyspace_hits为总的命中中次数,keyspace_misses为总的miss次数,命中率=keyspace_hits/(keyspace_hits+keyspace_misses)。
领取专属 10元无门槛券
私享最新 技术干货