[主动]需要操作人员去操作,或者定时调度
[被动]由用户触发更新
[预加载]提前加载好数据
推荐
以上的几种更新方案我都遇到过,因为产生了各种问题,所以我想到了一个相对好的方案,类似预加载功能,先把数据加载到缓存中,缓存成功后再切换显示最新的数据,将旧数据设置过期;
-
举个栗子:
我们现在有个业务需要缓存今日上新商品数据,缓存到Hash中
更新逻辑:
后台编辑人员操作完数据的时候点击更新按钮,获取服务器当前时间=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内存不足,滥用
-
问题
-
数据不断累加,无效数据未清理,缓存未设置过期时间
-
存储数据中包含未使用到字段,整个对象序列化到redis中
-
冷数据,或者根本不会再去使用的无效数据没有清理
-
解决
-
数据区分无效时间,设置过期时间,使无效数据过期;(如:通过日期后缀命名Key)
-
区分冷数据,清理掉冷数据;
-
缓存数据从简,redis key命名从简,数据字段命名从简,无效字段不添加在缓存中;
键命名规范
其他经验
-
数值累加,get,set+1并发导致累加不准确
-
.net 类库 ServiceStack 3.9.71.0 的一个问题
SetEntryInHash 返回 bool,只有第一次新增的时候返回的是true,后面修改成功了也都是返回false
源码:SetEntryInHash 方法,读取hset的结果 判断是否等于1,返回bool
我们通过命令: hset 第一次sflyq key不存在,添加成功返回的执行结果是:1 hset 第一次sflyq key已经存在,修改成功购返回结果:0
所以结果很明显,通过SetEntryInHash 判断hash是否key value 是否设置成功是有问题的,只有第一次设置会返回 ture
|