Redis作为Cache的使用经验

redis作为缓存使用,不作数据库用途,遵循以下规则:如果缓存没有数据,即加载数据到缓存,并会设置过期时间。使用最多的三种数据类型便是:

  1. String
  2. Set
  3. SortedSet

并发环境下的缓存读取和写入方式

凡是可以用String保存的,尽量将数据用json.dumps之后再放进String,如果需要Set和SortedSet就需要警惕缓存key刚好过期时候,会有一定读取错误的问题,这个无法避免。由于我们后端使用的是MongoDB数据库,读取一般都是从库,这就必须当心读取从库后的数据还是旧的。所以在写入数据和读取数据的时候注意以下几点:

写入数据是否立刻更新缓存

如果需要立刻更新缓存的话,使用findAndModify获取最新结果并设置进缓存中,但这带来了一个弊端,有些并不是热数据,这时候放进了redis会导致占用内存,如果设置过快,redis内存的使用量增长得非常快;好处需要与另一种方式对比才明显,另一种方式是写入数据后立刻删掉该缓存,等待有需要才再加载缓存,这样的好处是redis占用缓存不会过高,总是保留着热数据,弊端就是加载缓存读取从库的数据还是未同步的,这样导致脏数据,所以前者的直接更新保证了不会是脏数据。至于采取那种方式,要看使用场景,如果不需要最新的数据,最方便是删除掉该缓存就可以了,否则就需要立刻更新缓存数据,如果键数量特别多的情况下,可以设置过期时间短一些,尽快释放redis的内存占用。

读取String数据步骤(针对Python的驱动程序)

不需要判断key是否存在,直接get回来,如果不是None就json.loads后返回,如果是None,从数据库加载数据,并setex进redis。这样做的好处:避免判断key是否存在与get的间隙,key刚好过期,这就不好处理。其实也没必要判断key是否存在,get回来的值不是None就表明有数据,None就表明key不存在,其实已经包含了exists的效果。这样基本保证并发环境下的读取不会有任何问题,可能会说操作乱序导致旧的数据覆盖新的数据,如果修改非常频繁,可以把过期时间设置短点,其实下次修改就会覆盖掉错误的,并不会有太大问题。

读取Set和SortedSet数据缓存失效问题

这种大数据集合,无法单个操作就可以判断其key存在还是该key是否有值。通常需要两个操作:加载和获取需要的数据。问题就出现在加载和获取的间隙中,这个间隙缓存刚好过期,就会出现数据错误的后果,我觉得最佳实践是这样: 保证在服务运行过程中,这些数据集合不会缓存过期。像我们使用排行榜的时候用到大量了SortedSet,当时设置了1天就过期,这样导致出现排行榜数据出现不全的问题。又如Set保存着比赛名单的数据,发现key是存在,不再加载数据,准备判断某个项是否存在该set的时候,这个set就过期了,用sismember就会返回False,就无法判断这个False的意思是该数据项不存在该set里面还是该set的key已经过期了。

    原文作者:后视镜
    原文地址: https://www.jianshu.com/p/b04fbfe000e4
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞