大话Redis进阶-更新缓存的问题
博客专区 > ZYallers 的博客 > 博客详情
大话Redis进阶-更新缓存的问题
ZYallers 发表于4个月前
大话Redis进阶-更新缓存的问题
  • 发表于 4个月前
  • 阅读 2
  • 收藏 0
  • 点赞 0
  • 评论 0

大话Redis进阶-更新缓存的问题

使用Redis过程中,总是会遇到各种各样问题,这里进行问题的总结,作为Redis 进阶的经验分享。

更新缓存的问题

  • [主动]需要操作人员去操作,或者定时调度
  • [被动]由用户触发更新
  • [预加载]提前加载好数据

方案1

  • [主动]后台点击更新缓存按钮,从DB查找最新数据集合,删除原缓存数据,存储新数据到缓存;
  • 问题:更新过程中删除掉缓存后刚好有业务在查询,那么这个时候返回的数据会是空,会影响用户体验

方案2

  • [被动]前台获取数据时发现没有缓存数据就会去数据库同步数据到缓存
  • 问题:当并发请求获取缓存数据不存在的时候,就会产生并发的查询数据的操作。

方案3

  • [主动]后台点击更新缓存按钮,从DB查找最新数据集合,这里不删除缓存,通过遍历数据覆盖和删除掉无效的数据
  • 问题:逻辑相对麻烦,而且更新机制无法通用;

推荐

以上的几种更新方案我都遇到过,因为产生了各种问题,所以我想到了一个相对好的方案,类似预加载功能,先把数据加载到缓存中,缓存成功后再切换显示最新的数据,将旧数据设置过期;

方案4

[主动][预加载]前台获取缓存的时候需要先得到缓存数据对应的Redis Key(简称:[ShowingKey]),然后根据[ShowingKey]去读取缓存数据(简称:[缓存];

-[ShowingKey](可以是最近一次更新缓存的时间戳或者根据自己规则自定义)

  • [缓存](需要缓存的数据,如:DB数据等)

需要两块数据:

举个例子:
我们现在有个业务需要缓存今日上新商品数据,缓存到Hash中

Key string key=Goods:Todays:ing 内容=最近一次的更新时间戳

  • Hash Key=Goods:Todays:{0} {0}=时间戳

[缓存]对应Redis Key 规则

  • [ShowingKey]对应的Redis Key

更新逻辑:

后台编辑人员操作完数据的时候点击更新按钮,获取服务器当前时间=1469938351000=[更新时间戳],然后获取DB数据,缓存到Goods:Todays:1469938351000中,添加缓存数据成功后,获取Goods:Todays:ing中的时间戳1449538371020=[上一次更新时间戳],更新Goods:Todays:ing值=[更新时间戳]=1469938351000,更新成功后可以把[上一次更新时间戳]对应的缓存设置过期时间,我一般是设置5秒后过期。(注意旧数据一定要设置过期时间,不能直接删除,因为在切换[ShowingKey]的过程中可能还有业务在使用)

更新总结

  • 第1种更新方案影响用户体验一般不推荐使用
  • 第2种更新方案可以通过程序锁,锁住更新操作只能有一个进入DB查询,可以避免问题
  • 第3种更新方案不会有第1,2 的问题,但是更新逻辑写起来比较麻烦,而且更新方案不能抽象通用
  • 第4种更新方案使用提前加载到缓存,然后在切换需要显示的缓存数据,可以完美解决1,2,3中的问题

redis内存不足,滥用

问题

  1. 数据不断累加,无效数据未清理,缓存未设置过期时间
  2. 存储数据中包含未使用到字段,整个对象序列化到redis中
  3. 冷数据,或者根本不会再去使用的无效数据没有清理

解决

  1. 数据区分无效时间,设置过期时间,使无效数据过期;(如:通过日期后缀命名Key)
  2. 区分冷数据,清理掉冷数据;
  3. 缓存数据从简,redis key命名从简,数据字段命名从简,无效字段不添加在缓存中;

键命名规范

内存数据库,键名长度影响有限内存空间,所以命名应该控制长度,简短易懂;

大小写规范

根据业务命名,相同业务统一的Key前缀

其他经验

数值累加,get,set+1并发导致累加不准确,使用redis increment 自增数值的机制不会有累加不准确的问题

共有 人打赏支持
粉丝 2
博文 59
码字总数 19100
×
ZYallers
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: