今天我们一起聊聊缓存的一些事, 话不多说, 直接切入主题
我给大家介绍的是一种系统缓存, 我也把它叫做应用缓存, 用于解决系统调用耗时并发负载等问题缓存大量出现在当今互联网应用系统中, 几乎成了解决高并发高负载问题的标准解决方案, 近乎万金油
但是在缓存使用中我们常常遇到各种各样问题
首先我们先对缓存分个类, 其通常分为主动缓存与被动缓存
主动缓存:
见名知意, 这类型的缓存通常由系统主动写入和擦除(通常的做法是在数据新建时写入, 修改时擦除再写入), 在查询时直接使用缓存数据听起来不错, 但有几个运行时的复杂问题需要深思
缓存系统自身可靠性级别
写入擦除并发问题(事务问题)
被动缓存:
被动缓存, 顾名思义, 就是在系统写入或修改时不用主动写入擦除缓存在系统查询时将其结果写入缓存中, 下次查询优先看缓存是否存在, 若存在直接获取缓存数据, 若不存在, 穿透后端数据源这种缓存我们通常会设定一定时长的有效期 (具体时间应考虑业务场景和系统综合负载而定) 同样, 被动缓存也有一些必须深思的问题
修改时缓存难以即时更新
缓存集中穿透引发雪崩效应
无论单纯的主动或者被动缓存都有这样那样的弊端, 那么联合使用会不会更好?
答案是: 会
但是复杂度会急剧上升, 同时依然有比较复杂的问题
缓存并发问题依然存在
主动 + 被动极易出现缓存颠倒问题
依然容易出现的雪崩效应
那么有没有更好的办法, 今天我就跟大家介绍一种以被动为主但又能有效防止并发雪崩颠倒问题的缓存设计方式以两层缓存 Redis+JVM, 后端 Mysql 为例
看完流程图, 发现这个被动缓存中的不一样了吗?
这套被动缓存不是在缓存失效后才去穿透数据源更新缓存的, 而是在一个阈值时去构建异步更新缓存的任务可以理解为预先预判更新缓存
那么问题来了, 即时预先更新缓存依然有集中穿透的问题? 注意了, 下一步流程有个资源过载保护, 也就是说即使达到缓存更新阈值, 但是后端 Mysql 过载也不会穿透数据源, 而此时缓存并未失效, 依然能很好的保存后端数据
可是, 如果大量任务都是对统一缓存的更新岂不是让其他缓存得不到更新的机会(堆积效应), 别急看看下一个子流程
发现奇妙之处了吗, 如果是同一各缓存, 这里不会再穿透, 只穿透一次, 且快速释放后续同值 Key, 有效放在单一缓存堆积效应
那么新问题有出现了, 在分布式环境中, 检查 Key 岂不是开销很大?^_^ 为什么要分布式都检查, 只单机检查不久好了, 极端情况也就集群每台机器穿透一次, 您的集群有多大?
等等, 还有问题? 就算做到了同值 Key 不占用额外资源, 那么真正需要更新的 Key 一直超负载怎么办, 会不会有 Key 始终得不到更新, 导致强制穿透数据源
这个问题很好, 答案是: 一定会可是这个时候我们应该意识到, 我们的缓存时间是不是错了, 我们应该有更好的配置
配置来了, 很简单, 分别设置就好
说了这么多, 效果如何呢?
POP 营销中心于 2016 年采用了该装置, 使 Mysql QPS 从 80000 降到 2000 接口 TP99 降到 2ms, 支撑单接口日 PV11 亿有效提升系统稳定性, 提升接口体验
本文受原创保护, 未经作者授权, 禁止转载 linkedkeeper.com (文 / 莫迪)
来源: https://www.thinksaas.cn/group/topic/839307/