02|缓存一致:读多写少时,如何解决数据更新缓存不同步?
该思维导图由 AI 生成,仅供参考
缓存性价比
- 深入了解
- 翻译
- 解释
- 总结
本文深入探讨了在读多写少场景下,解决数据更新缓存不同步问题的技巧。作者首先强调了评估缓存有效性的重要性,提出了临时热缓存的概念,以及如何通过临时缓存有效降低数据库查询压力。此外,文章详细讨论了缓存更新不及时的问题,并提出了针对单条实体数据缓存刷新的解决方案。还介绍了关系型和统计型数据缓存刷新的常用方法,包括人工维护缓存、订阅数据库变化、版本号缓存设计等。另外,还探讨了长期热数据缓存的实现方式,以及如何避免缓存穿透问题。最后,通过代码示例展示了一种“临时缓存+长期热缓存”混用的实现方式,以及如何通过异步脚本定期扫描热缓存列表来主动推送缓存。整体而言,本文通过实际业务场景,深入浅出地介绍了在高并发查询下缓存数据一致性的相关技巧,对于需要解决类似问题的读者具有一定的参考价值。文章内容涵盖了缓存有效性评估、临时热缓存、缓存更新、长期热数据缓存、缓存穿透问题等技术特点,为读者提供了全面的解决方案和实际操作示例。
《高并发系统实战课》,新⼈⾸单¥59
全部留言(22)
- 最新
- 精选
- Daniel置顶1. 使用 Bloom Filter 识别热点 key 时,有时会识别失误,进而导致数据没有找到,那么如何避免这种情况呢? 通过我的 “机器学习的经验”,我觉得是这个布隆过滤器的哈希算法有点过拟合了,也就是说容错率高了,在资金充足的情况下先试着调低“容错率“(超参数)提升容量试试(不知道工业界上布隆过滤器的容错率能设置成 0%吗?但后期可能随着数据量的增长也是一个无限扩容的”吞金兽“呀),但我感觉我这个想法在工业界应该不成立。 第二种方法,我想到的是,如果这个 key 被误识别为”hotkey”的话,就在内存中记入“not_hotkey”列表,每次数据进来的时候,先用 缓存里的 not_hotkey里的列表来筛,要是不是hotkey就做成临时缓存,要是这个key是hotkey的话,就进行长期缓存来处理。 2. 使用 Bloom Filter 只能添加新 key,不能删除某一个 key,如果想更好地更新维护,有什么其他方式吗? 对于长时间不用的 key ,我认为可以设置一个“失效时间”,比如 一周内不用,就自动清除掉这个key。 之后在新的一周,把失效的key清理出去,再重新整理好一个列表,重新更新一遍这个布隆过滤器的新的哈希算法表。 (但感觉这个方法貌似不是最优的,也要在半夜用户量访问少的时间点去做变更处理) 老师想请教一个问题,对于 hotkey (热点数据)这个工业界的评价标准是不是不同行业会不一样呀? 比较想知道工业界上是用什么方法(一般统计方法?机器学习聚类?深度学习网络?)和工具(数据埋点?用户操作行为分析?),来做 “热点数据”的 判别的?
作者回复: 你好,Daniel,很高兴收到你的留言 第一种方法,如果使用集合检测也可以达到同样效果,你提到的方法缺陷在于not_hotkey会很大,这里需要记录所有不是hot key的所有key。目前bloomfilter只是个模糊筛选,用小量数据换更好的性能,但是他确实误判概率多一些。 第二个问题也是一个办法,但是需要我们能够精准控制这一批数据过期时间,但是我们在这节课用它主要是为了判断本地缓存中是否有这个缓存,由于无法判断所以需要每次询问,会导致系统更加复杂。 第三个问题 主要是访问量,我们可以将一些key 做一些count统计,数据埋点就足够了,机器学习和深度学习的QPS有些低,我印象里,一个1w元的显卡做发音评分,一秒钟只能处理4个请求,场景不太适合,有点小才大用了。
2022-10-27归属地:北京33 - peter置顶请教老师几个问题: Q1:缓存都是有超时时间的,从这个意义上说,都是“临时”的,为什么本文还要分为“临时”缓存和“长期”缓存? Q2:“临时”缓存和“长期”缓存在实现上可以用同一个软件吗? 比如,两者都可以用Redis实现?或者,“临时缓存”是用一个组件实现(非Redis)而“长期缓存”用Redis实现? 或者,“临时缓存”在代码中实现而“长期缓存”用Redis? Q3:人工维护缓存,怎么操作? 缓存数据一般都比较多,人工怎么能够维护一堆数据?具体是怎么操作的? 有一个界面,通过此界面来操作吗?
作者回复: 你好,peter,又见面了,感谢你的留言~ Q1:由于我们的大多数数据都是有时效性的,我们很少去做永久的内存缓存,毕竟内存还是很贵的,我们需要考虑性价比。长期缓存可以是一天,临时TTL是30秒。同时长期的更新是定期脚本刷新,临时是用到才会放进去一会儿。再来看,长期的访问很频繁,如果放开会导致数据库压力很大,但是临时的由于访问量小所以不用特意防击穿。 Q2:如果缓存压力不大可以用一个,如果很大会再做个L1缓存,在每台业务服务器上,这样能缓解核心缓存压力。 Q3:这个属于人工写代码,如我更新了用户的昵称,那么我会刷新这个用户的所有帖子的缓存,以及这个用户的所有最近留言缓存,以及这个用户的个人信息缓存。这是一种,还有一种就是你说的界面配置规则,但是这些都是要能快速定位的才可以。你可能会碰到,用户昵称以rick开头的账号有多少个,当我们改昵称为这个的时候,对于这种条件多样的,刷新哪个缓存不好确定,只能临时缓存30秒等他过期后刷新
2022-10-26归属地:北京36 - 奕1. Bloom Filter 存在误报,会把不是热点的 key 识别成热点key, 所以需要一个 0误报的算法,数据结构 所以 Cuckoo Filter 布谷鸟过滤器来了 2. 可以定期或者其他策略 重新构造 Bloom Filter > 其实上面的2个问题,都可以使用 Cuckoo Filter 来解决
作者回复: 你好,很高兴收到你的回复,没错!确实Cuckoo Filter能够解决所有问题!同时补充提醒:他也有一些缺点使用的时候要注意,性能没有bf高,同时删除存在误删情况~
2022-11-03归属地:北京34 - 传输助手读取数据库设置缓存的时候,为了不受数据库主从延迟的影响,是不是需要强制读主库?
作者回复: 你好,传输助手,很高兴收到你的留言,这里有一个前提,就是我们加缓存的服务基本都是读并发高的服务,对于MySQL主库来说,问题就是全局只有一个主库,所以他是单点,同时更脆弱,理论上这种读压力尽量不要压到主库上~
2022-10-26归属地:北京23 - 一颗苹果布隆过滤器的缺点,可以用hashmap那个链表解决,遇到冲突了延伸出一个链表,但得标注清楚这个元素是哪个key的。链表是空,直接set和普通布隆过滤器一样,不是空就追加一个元素(标注好哪个key)。删除的话遇到链表也遍历,根据匹配的key来删除。如果足够稀疏,那性能和一般布隆一样,数据越密集性能越下降。要准确性就只能牺牲性能来换吧
作者回复: 你好,一颗苹果,很高兴收到你的思路,这是个不错的办法。简单翻译一下,hashmap的hash环如果不够大,很多key都会碰撞在一个hash块内,而碰撞在一起的数据会在hashmap块内用链表保存,链表每次查找都要遍历所以会有一定性能下降,所以如果key少链表小的话会很快,当然这里没提及hash计算的时间复杂度。
2022-12-22归属地:北京2 - Elvis Lee1. 使用 Bloom Filter 识别热点 key 时,有时会识别失误,进而导致数据没有找到,那么如何避免这种情况呢? 布隆可以判断一定不存在的数据,那么是否可以认为,只要插入不成功,即为热数据,但在设计布隆的时候需要根据业务来设置好容量和容错率。同时布隆删除操作在生产上不建议,最好是持久化后用版本号去区分。如果是离线链路,更推荐生成布隆文件,推送去客户端。实时的,目前接触是保存在Redis,Redis7的版本好像已经不需要插件
作者回复: 你好,Elvis Lee,很高兴收到你的留言,不建议这样使用bloomfilter,主要原因在于,他的识别和md5计算结果一样,有的时候不同的key返回的结果是一致的,所以这样是拿不到准确结果的。
2022-10-26归属地:北京42 - hhh没有抢到锁的sleep 1s然后去查询,这样接口耗时不是就会肯定大于1s吗 ,假如超时配置小于1s,这次请求不是必定会超时嘛
作者回复: 你好,hhh,时间不是绝对的这个可以根据情况进行调整,以前我们普遍是200ms左右,相对的这个方式比直接打沉中心数据库好那么一点,前提我们前端服务器足够多。
2022-11-11归属地:北京31 - 门窗小二老师!但是课后题有答疑篇吗?
编辑回复: 建议先自己尝试回答,课后题答案后续看回答情况再公布。
2022-10-28归属地:北京1 - 黄堃健老师,看了留言:说用布谷鸟过滤器,f = fingerprint(x); i1 = hash(x); i2 = i1 ⊕ hash( f); 但是 由于存的是指纹, 用的是hash算法,不排除 data1,data2 计算的tingerprint(x),hash(x) 都相同。 这样可能存在误删,也存在误判情况
作者回复: 是的,但是,这个方式可以减少大量计算,当误判后再用一个算法复核一下就好了
2024-03-01归属地:广东 - 黄堃健不过,通过队列更新消息这一步,我们还会碰到一个问题——条件批量更新的操作无法知道具体有多少个 ID 可能有修改 这会有什么问题? 一条条更新不就是可以吗? 因为没有接触过这块,不理解为什么要合并更新?
作者回复: 你好,这里是因为如果我缓存的是一批符合特定条件的列表数据,其中有几个数据状态发生了改变,由于缓存是被动的,当基础数据发生变化,我无法准确知道当前还有那些缓存保存的是过去的数据,所以无法对他们进行更新,这对数据并发高且准确性要求高的上层服务来说很致命
2024-03-01归属地:广东