缓存的伪随机策略
有时候在业务逻辑上,我们需要返回一些随机的数据,越随机越好,这时候缓存较短的时间、不缓存等方式均不理想。缓存一定的时间会导致用户会以为页面没刷新,没取到数据,体验不好。
而若不缓存,大量的请求可能会造成数据库、中间件的巨大压力。
可以通过设置特定的键值+随机数的方式,来人为造成一定数量随机出来的缓存,完美解决随机问题。
1 | $key = 'key:sample:'.rand(1, 500); |
缓存时间随机+key键值随机,可以产生500种(甚至更多)组合,满足线上的需求。
长期缓存,定期清理
当我们做了缓存之后,有时候缓存的时间不能设置太长,因为总会有一些数据在变更。变更后,如果很长的时间内,缓存一直有效,那么修改的操作等于没有成功。
缓存的时间短,也导致了缓存命中率不高,内存利用率较小,反而增加了多余的两次缓存读写(缓存取不到数据,从数据库/中间件获取,再次写入缓存),性能提升不够明显。
其实对比热数据而言,99%的在库数据,是长时间不会变化的,可以通过检测数据库插入/变更/删除时间,通过特定的调度脚本,及时从缓存种移除。
如果做了这些工作,那么缓存的设置就可以大胆的设置为长期缓存,半年,整月等策略,缓存的命中率能提升一个大台阶。
缓存置换策略的选择
在redis中,当缓存的内存占用量达到峰值maxmemory的时候,这时候就需要用到置换策略了,这个策略不设置或设置错误,都会导致浪费,甚至影响系统正常运行,抛出错误,502网关错误等等。redis一共支持6种策略。
noeviction
: 不进行置换,表示即使内存达到上限也不进行置换,所有能引起内存增加的命令都会返回errorallkeys-lru
: 优先删除掉最近最不经常使用的key,用以保存新数据volatile-lru
: 只从设置失效(expire set)的key中选择最近最不经常使用的key进行删除,用以保存新数据allkeys-random
: 随机从all-keys中选择一些key进行删除,用以保存新数据volatile-random
: 只从设置失效(expire set)的key中,选择一些key进行删除,用以保存新数据volatile-ttl
: 只从设置失效(expire set)的key中,选出存活时间(TTL)最短的key进行删除,用以保存新数据
缓存与基础业务系统分离
如果基础业务系统与缓存放在同一redis库,那么设置了volatile-lru
,就会导致正常用户可能被迫下线。设置了volatile-ttl
就会导致一些缓存时间较短的缓存,没有起到作用,频繁被擦除,影响命中率,缓存效果也不理想。
若缓存与基础业务系统分离,既可以优化缓存的命中率等考核条件。同时也可以保证用户正常的使用不受影响,如session、用户登录状态、邮箱/手机验证码等数据。
session
在使用session时,应选择按照volatile-ttl
策略,并发量高时,删除长期不在线的用户。
缓存
在缓存方面,通过volatile-lru
,近期最少使用算法,讲命中率低的缓存及时删除,把空间让给更需要的缓存。