文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Helios多级缓存实践

2024-12-13 21:49

关注

为缓解 CPU 压力而做缓存:譬如把方法运行结果存储起来、把原本要实时计算的内容提前算好、把一些公用的数据进行复用,这可以节省 CPU 算力,顺带提升响应性能。

2.缓存属性 

目前 ,“缓存”其实已经被看作一项技术基础设施,针对该种基础设施,除了缓存基本的存储与读取能力,通用、高效、可统计、可管理等方面的需求也被重视。通常,我们设计或者选择缓存至少会考虑以下四个维度的属性:

3.本地缓存 

下面围绕几个主流的本地缓存,HashMap, Guava, Ehcache, Caffeine对上述属性进行简单介绍。

吞吐量:因为涉及到并发读写,所以对于吞吐量影响最大的即是并发访问方式。最原始的 HashMap缓存,因为没有进行并发访问控制,其吞吐量最高, 但也决定了其无法在多线程并发下正确地工作;后续线程安全版本ConcurrentHashMap 采用分段加锁的方式进行了访问控制;ConcurrentHashMap的并发访问用于解决并发读写时的数据丢失,而在其他几种本地缓存的设计中,因为涉及到数据淘汰与驱逐能力,其主要的数据竞争源于读取数据的同时,也会伴随着对数据状态的写入操作,写入数据的同时,也会伴随着数据状态的读取操作。针对这种一种是以 Guava Cache 为代表的同步处理机制,即在访问数据时一并完成缓存淘汰、统计、失效等状态变更操作,通过分段加锁等优化手段来尽量减少竞争。另一种是以 Caffeine 为代表的异步日志提交机制,将对数据的读、写过程看作是日志(即对数据的操作指令)的提交过程,然后通过异步批量处理的方式降低锁的并发访问。下图是Caffeine官方文档中压测得到的吞吐量数据。

命中率:主要用于最大化有限物理内存的使用价值。优秀的缓存需要能够自动地实现淘汰低价值数据,而该能力则会涉及到不同的淘汰策略。目前,最基础的淘汰策略实现方案有以下三种:

在此之上,针对LFU策略最近又衍生出了以下两种变形:

扩展功能:是基础数据读写功能之外的额外功能。主要侧重于监控统计能力,过期控制,容量控制,引用方式等。

分布式支持:Caffeine只作为本地进程内缓存,而Ehcache则演变为同时能够支持分布式部署的模式。另外,Ehcache在3.x也支持了堆外缓存的能力,而该能力在本地缓存在GB以上,且对RT敏感的场景就有了用武之地。反观Caffeine,则更聚焦于单实例本地进程堆内缓存。

4.分布式缓存

在微服务的背景下,Ehcache、Infinispan 等也演进为能够同时支持分布式部署和进程内嵌部署的缓存方案。Ehcache类的缓存共享方案是通过RMI或者Jgroup多播方式进行广播缓存通知更新,缓存共享复杂,维护不方便;简单的共享可以,但是涉及到缓存恢复,大数据缓存,则不合适。

对分布式缓存来说,处理与网络相关的操作是对吞吐量影响更大的因素,目前Redis已经成为分布式缓存技术的首选,我们暂不对Redis分布式缓存技术做过多的探讨,有兴趣的读者可以参阅相关官网和技术书籍。

5.多级缓存 

分布式缓存与进程内的本地缓存各有所长,也有各有局限,它们是互补而非竞争的关系,如有需要,完全可以同时把进程内缓存和分布式缓存互相搭配,构成透明多级缓存(Transparent Multilevel Cache,TMC)。

典型的多级缓存结构如下图所示,使用进程内缓存作为一级缓存,分布式缓存作为二级缓存,DB等其他数据源作为三级缓存。应用进程首先读取一级缓存,未命中的情况下读取二级缓存并回填数据到一级缓存。如果二级缓存也查询不到,就发起对最终源的查询,将结果回填到一、二级缓存中去。各级缓存数据的读取命中率依次是: 进程内缓存 > 分布式缓存 > 数据源。

对应于上述抽象的多级缓存结构,Helios多级缓存的架构设计图如下所示:

在Helios多级缓存的设计中,缓存边界被定义为:

用户触发的数据读取99.9%以上只走本地缓存,极少数miss到分布式缓存或DB 。

DB只会被分布式调度任务访问,用以将最新的数据刷新到分布式缓存。

分布式缓存绝大部分情况只会被本地缓存和reload任务访问,用以中转最新的数据。

同时采用了如下的分层刷新机制:

下文将聚焦于在Helios多级缓存建设中的一些实践。

5.1 缓存一致性

缓存意味着副本,就必然存在着各数据副本之间的一致性问题。而从多级缓存中,存在着本地进程内缓存与分布式缓存的一致性问题,分布式缓存与DB等外部数据源的一致性问题。

关于本地进程内缓存与分布式缓存的一致性问题,因为本地进程内的缓存一般是分布式多实例的结点,所以一般做法是数据发生变动时,在集群内发送推送通知(简单点的话可采用 Redis 的 PUB/SUB,或者MQ的广播消息机制,严谨的话引入 ZooKeeper 或 Etcd 来处理),让各个节点的一级缓存自动失效或者刷新。

关于分布式缓存和DB等外部数据源之间的一致性问题,二者皆有成熟的数据访问接口,无需考虑分布式多实例之间的数据复制问题。问题的复杂性在于如何保证并发读写情况下的一致性。更新缓存的的Design Pattern有基础的有四种:cache aside, Read through, Write through, Write behind caching。其中最经常使用,成本最低的 Cache Aside 模式逻辑如下:

关于缓存更新过程中,使用失效而非刷新主要因为避免多个更新请求并发操作导致的脏数据问题。

当然Cache Aside 模式在极端情况下也会存在脏数据问题,针对该一致性问题,要么通过2PC或是Paxos协议保证强一致性,要么就是拼命的降低并发时脏数据的概率。而Facebook在论文使用了这个降低概率的玩法,因为2PC太慢,而Paxos太复杂。CacheAside更新模式是最简单也是最常用的更新模式,但在实际应用场景下,还需要考虑到业务侧对缓存Miss的容忍度,分布式缓存更新请求失败的兜底和补偿策略等等。

Helios的缓存更新策略基于实际场景稍有不同, 具体更新模式如下:

Helios多级缓存在更新策略放弃了可能出现的脏数据,而选择避免缓存穿透,相当于AP模型,而cacheAside模式则属于CP模型。在实际应用场景下,一般情况下出现脏数据的概率会非常低,但是高并发和高频更新的数据,将放大出现脏的概率。在实际的使用场景中,为了兜底可能的失败或者遗漏的更新请求,而增加的全量兜底功能:通过定时任务将DB等数据源的数据全量刷新到分布式缓存。而该兜底方案却带来了另外一个可能并发更新分布式缓存的场景。针对可能出现的脏数据以及其他管控诉求,Helios提供了KEY级别的手动驱逐与缓存刷新能力。同时为了降低全量兜底策略对数据不一致的影响,全量兜底策略也被设计成为支持流式更新,业务侧可自主选择更新。

缓存一致性的是无法避免的问题,也没有绝对合适的一致性方案。未来Helios多级缓存架构会提供多种更新模式,供业务在不同的业务场景下选择。

5.2 缓存监控

对于进程内缓存,例如Ehcache, Caffeine等都虽然都提供了成熟的访问统计指标监控能力。但该统计指标均为从运行时刻起的累计指标,无法有效反应随时间变化的监控信息。同时对于业务侧关心的大KEY和热KEY 指标均不支持。

时间敏感的统计指标监控能力需要使用滑动时间窗口的方式进行分窗口统计上报, Helios内部使用Disruptor异步消费监控事件,以避免对用户侧请求的影响。同时在访问频率统计上,又借鉴了Sketch对低频访问数据进行过滤,避免大量统计数据带来的稳定性风险。

需要注意的是,异步设计往往带来的副作用就是指标延迟,且大流量下固定缓冲队列往往会牺牲一部分的数据准确性,这点在Caffeine的异步设计中也有所体现。

5.3 缓存热点

热点缓存经常是业务需要引入多级缓存的一个重要原因,针对频繁访问的热点数据,如果每次都要从缓存服务器获取,可能导致缓存服务器负载过高、或者带宽过⾼。而针对热点数据最直接的想法就是将数据放到使用最近的地方,也就是本地内存。

针对缓存热点最简单有效的方式就是手动指定,提前预热到本地缓存,比如在大促活动前手动将秒杀的商品信息提前缓存到本地进程内缓存。但是手动预热的方式无法解决突发或者异常热点流量。这就需要多级缓存框架能够透明的支持热点发现与同步机制。上文中提到过Caffeine这种本地进程内缓存通过优秀的淘汰策略W-TinyLFU解决了热点统计,衰减和稀疏突发访问的问题,但是Caffeine本身热点统计周期,热度衰减策略可能无法match业务的统计周期,而且当业务变更时,存在一定的时间成本优化容量参数以平衡内存使用和缓存命中率。

热点发现与缓存机制整个流程必然: 热度统计,热KEY认定,热KEY同步与更新这3个流程。目前业界成熟的热点方案主要有有赞的TMC方案以及京东的HotKey方案。二者均定位于实现全局热点方案,且整体架构和流程类似。以有赞的TMC解决方案为例:

全局热点探测模式相较本地热点探测会更加精确:特别是在微服务背景下,服务实例较多的情况下,当单个实例探测到热KEY时可以快速通知其他结点;而且能够应对流量不均情况下的异常热点KEY的发现,而代价则是较高的通信成本和相对较高的架构复杂性。当前Helios热点探测放弃了全局探测的模式,转而专注于优先探索本地热点方案。因为针对目前严选应用环境 流量几乎均分到每个实例,可以使用较小的准入阈值来提升本地热点探测的灵敏度;另外一方面,严选环境的当前痛点是希望通过本地热点自管理的方式去缓解本地缓存过热,以及缓存参数调优的复杂性。Helios本地热点探测流程如下如所示:

自动化的本地热点探测,热点管理非热点驱逐能力降低了本地内存的水位占用,避免出现本地缓存过热的情况,同时热点统计模块的热点KEY调用分析统计也可以用于指导缓存实例的参数调整和性能优化。

6.总结与展望

缓存分为本地进程内缓存和分布式缓存,因为定位和使用场景的不同,二者在技术选型时候选对象及考察点存在很大不同 ,而且目前二者也已呈现不同的演进方向。透明多级缓存结构则是希望结合二者的长处,通过封装了本地进程内缓存和分布式缓存之间常用的使用模式,降低了多级缓存的接入与开发成本。而副作用是,本地缓存与分布式缓存Redis类接口命令协议上的差异性导致了多级缓存存在着诸多的限制,同时也带来缓存一致性等问题。要实现多级缓存架构的透明性仍然存在很大挑战,未来也将继续在易用性,一致性,缓存治理等方面与业务侧深入探讨继续前行。

来源:严选技术产品团队内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯