二级缓存架构极致提升系统性能

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云原生大数据计算服务 MaxCompute,5000CU*H 100GB 3个月
简介: 本文详细阐述了如何通过二级缓存架构设计提升高并发下的系统性能。

前言

随着k8s成为用云新界面,容器成为众多用户“弹性”的利器,因此容器的创建天生具备高并发特性。


高并发、大数据量下,为了提供更好的容器弹性体验,笔者通过二级缓存的设计,成功优化了系统性能、资源消耗、系统容量。


但持续压榨性能的道路是曲折的。各种缓存方案需要考虑非常多因素,包括缓存的多级架构、预热、击穿、刷新、运维等。


让我们先看看系统性能、资源消耗、系统容量,到底优化了多少?然后详细介绍带来性能提升的二级缓存架构,以及各种缓存方案的设计、比较、落地。


优化结果

笔者对系统进行多次压测,观察了二级缓存等优化手段上线前后,高QPS下的资源消耗、RT和系统容量。


1、资源消耗大幅下降

可以看到,上线了二级缓存等优化手段后,相同QPS下,CPU使用率大幅下降。

image.png

2、RT和系统容量优化

由于计算资源消耗的下降,同QPS下的平均RT也大幅下降。此外我们发现,优化前,随着QPS不断提升,RT明显变慢、变慢幅度很大,优化后,RT变慢的幅度明显减缓。这意味着,系统容量也更加深不可测了。


系统瓶颈在哪?

持续压榨性能,前提是知道瓶颈在哪。笔者怎么定位瓶颈的呢?-> cpuProfile火焰图。


高QPS下,分析了系统cpu火焰图,发现50%+的CPU瓶颈在大量的业务数据处理,主要两块:


1、从redis取业务pojoList时的fastjson array反序列化背景是和redis交互的数据量特别大笔者对缓存value进行过压缩,在解压缩后的string转为List<Pojo>的过程,本质用时间换了空间。


2、调用redis获取数据后的alibaba.cachejson的POJO解析。


在高并发、大数据量的业务背景下,这些过程的耗时被笛卡尔积地放大。


既然分布式缓存CPU资源消耗是瓶颈,那么引入本地缓存,就能解这个问题。另外,本地缓存还能提供服务容灾能力。


数据属性和缓存选型


数据属性

设计缓存方案前,先分析业务数据属性:

  • 符合key -> value的数据模式
  • 读多写少
  • 变更频率低
  • 数据一致性要求不高

简直就是缓存的绝佳使用场景!那么用本地缓存,还是分布式缓存呢?还是二级缓存?


本地/分布式缓存特性

基于业务属性,我们来match本地/分布式缓存特性:


本地缓存


  • 优点
  • 访问速度快;
  • 减少网络开销:不存在redis流量瓶颈(之前由于数据valueList量过大,导致redis网络流量超过redis实例SLA,还做过一次gzip压缩);
  • 缺点
  • 可用性相对差:如果应用实例宕机/重启, 缓存数据会丢失;
  • 资源限制:受限于单机内存大小,不适合大规模数据缓存(相对内存大小来说,本业务数据量还是较小,也是相对静态数据,在内存还是妥妥可存的核心业务数据);


分布式缓存


  • 优点
  • 高可用:数据共享,不会因为业务机器重启丢失;
  • 大容量:可以水平扩展增加存储容量;
  • 缺点
  • 序列化cpu瓶颈(本系统大数据量+高调用量下尤其突出);
  • 网络开销:存在redis流量瓶颈(本系统大数据量+高调用量下尤其突出);


本地+分布式二级缓存


  • 优点
  • 结合两者优势,层次化加速;
  • 缺点
  • 对本系统代码侵入较大,实现较复杂;
  • 资源消耗:额外的缓存层级会占用更多计算和存储资源;


缓存方案比较

系统现状

image.png

结合业务场景和系统现状,提出以下三种方案。对多级架构、预热、击穿、刷新、运维多个角度分析。

方案1:本地缓存+guava refreshAfterWrite

image.png

1、架构

仅本地缓存。根据业务场景设置失效时间。


2、cache miss处理、刷新

使用Guava cache原生的refreshAfterWrite+异步reLoader机制,进行缓存的刷新,保证时效性。当对应key距离写入时间点存活超过TTL后,guava会自动执行我们在reLoader中写的业务逻辑,从提供实时数据的系统自动拉取最新的<key, value>,更新缓存值。


在本业务场景下,缓存的key&value设计有两种方案。


a. <key, value>。由于guava cache loader只能by key更新,所以,如果在单地域有N台机器,每个机器都查M个key,在缓存刷新时最大有M*N个查询请求打到提供实时数据的系统,无法使用批量查询能力,而M数量非常大,对下游压力会翻倍。


b. <"all_data"(hardCode), Map<key, value>>。这样可以使用到批量查询的能力,但是当某些<key, value>在本地缓存没有时,guava的loader就无法识别cache miss并从下游系统捞数据了。


3、预热

启动时全量预热。


4、运维

暴露dubbo/http服务,by host运维;或者重启机器。


因此:

  • 优点
  • 无redis相关cpu资源、网络资源损耗;
  • 直接使用了Guava cache原生的loader机制;
  • 缺点
  • 对下游压力翻倍;

由于对下游压力太大,放弃此方案。

方案2:二级缓存+刷新job

image.png

1、架构

本地+分布式二级缓存。本地缓存失效时间无穷大。


2、预热

启动时全量预热。


3、cache miss处理

不用guava cache loader。cache miss时业务上调用分布式缓存,再miss则调用下游服务。


4、刷新

使用spring单机job定时全量刷新缓存,保证一定时效性(数据变动频率很低,所以job频率设低即可)。但是由于本系统在间接引入quartz分布式定时任务框架时,没有直接支持单机job(quartz本身是支持的),所以需要额外使用spring单机job框架,会导致系统任务管理框架不统一。


5、运维

本地缓存:暴露dubbo/http服务,by host运维;或者重启机器。

分布式缓存:通过redis服务管理。


因此:

  • 优点
  • 本地缓存命中率很高,基本不会发生redis瓶颈。
  • 缺点
  • 业务自行load+write back。
  • 使用了新的定时任务框架(for单机),系统任务管理框架不统一。


方案3:二级缓存+guava expireAfterAccess

image.png

1、架构

本地+分布式二级缓存。根据业务设定本地缓存失效时间(expireAfterAccess)。


2、预热

启动时全量预热。这会导致应用重启,然后缓存预热后,部分本地缓存TTL可能批量到期失效,后面请求过来后可能直接大量击穿到下游服务,这是典型的缓存雪崩场景!

而且,当本地缓存雪崩,或者miss时,请求即使hit分布式缓存,也会导致redis相关序列化cpu瓶颈,会导致偶发的系统性能长尾。


3、cache miss处理

不用guava cache loader。cache miss时业务上调用分布式缓存,再miss则调用下游服务。


4、刷新

无刷新job。


5、运维

本地缓存:暴露dubbo/http服务,by host运维;或者重启机器。

分布式缓存:通过redis服务管理。


因此:

  • 优点
  • 不需要额外刷新job;
  • 不强依赖运维方案(因为本地和分布式缓存都有失效时间);
  • 缺点
  • 存在缓存雪崩风险;
  • redis相关序列化造成cpu瓶颈发生概率仍然较大;


落地方案

根据上述优缺点、改造量评估, 基本按照方案2来执行。


1、架构

本地+分布式二级缓存,以本地缓存为主,保证本地缓存极高命中率。


2、CacheMiss处理

业务自行处理,和现有链路保持一致,localCache -> redis -> dubbo,这样能够快速上线。


3、预热

应用启动,提供服务前预热。


4、刷新

基于SpringCronJob。


5、运维

per host运维,提供dubbo/http服务。

除此之外,对guava cache还进行了包装,各个业务场景的各种local cache,统一存储在一个Map容器Map<${prefix}, Cache<${key}, ${value}>>里,对现有的本地缓存也进行了重构,通过缓存包装层统一交互统一管理,增加可复用性和代码简洁度。


写在最后

本文对多种缓存方案的架构、预热、击穿、刷新、运维等进行了比较分析,最终进行工程落地,完成了容器场景高并发、大数据量下的系统性能极致提升。后续的优化点有:


1、其他系统瓶颈:压测pattern较单一,可能因为缓存掩盖其他依赖服务的性能瓶颈。未来会用更全面的压测pattern继续压榨系统性能。

2、批量刷新能力:对于方案1的批量刷新能力缺陷,caffeine其实有相关feature,见Bulk refresh这个issue。

3、运维方案:缺乏集群批量invalid能力,待建设。

4、架构统一:分布式和单机job使用同一个job管理框架。


这个方案的落地,特别要感谢团队同学的宝贵建议,是大家多次对技术方案“battle”后的结果。虽然笔者不是哈工大的,但借用哈工大的校训来总结,reviewers的意见、对技术的追求,如同追求“规格严格,功夫到家”。Creating great software is crafting a piece of art. 继续加油!





来源  |  阿里云开发者公众号
作者  |
 木将


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
10天前
|
监控 安全 API
使用PaliGemma2构建多模态目标检测系统:从架构设计到性能优化的技术实践指南
本文详细介绍了PaliGemma2模型的微调流程及其在目标检测任务中的应用。PaliGemma2通过整合SigLIP-So400m视觉编码器与Gemma 2系列语言模型,实现了多模态数据的高效处理。文章涵盖了开发环境构建、数据集预处理、模型初始化与配置、数据加载系统实现、模型微调、推理与评估系统以及性能分析与优化策略等内容。特别强调了计算资源优化、训练过程监控和自动化优化流程的重要性,为机器学习工程师和研究人员提供了系统化的技术方案。
130 77
使用PaliGemma2构建多模态目标检测系统:从架构设计到性能优化的技术实践指南
|
5天前
|
存储 缓存 监控
Linux缓存管理:如何安全地清理系统缓存
在Linux系统中,内存管理至关重要。本文详细介绍了如何安全地清理系统缓存,特别是通过使用`/proc/sys/vm/drop_caches`接口。内容包括清理缓存的原因、步骤、注意事项和最佳实践,帮助你在必要时优化系统性能。
112 78
|
3天前
|
机器学习/深度学习 算法 数据可视化
基于深度混合架构的智能量化交易系统研究: 融合SSDA与LSTM自编码器的特征提取与决策优化方法
本文探讨了在量化交易中结合时序特征和静态特征的混合建模方法。通过整合堆叠稀疏降噪自编码器(SSDA)和基于LSTM的自编码器(LSTM-AE),构建了一个能够全面捕捉市场动态特性的交易系统。SSDA通过降噪技术提取股票数据的鲁棒表示,LSTM-AE则专注于捕捉市场的时序依赖关系。系统采用A2C算法进行强化学习,通过多维度的奖励计算机制,实现了在可接受的风险水平下最大化收益的目标。实验结果显示,该系统在不同波动特征的股票上表现出差异化的适应能力,特别是在存在明确市场趋势的情况下,决策准确性较高。
20 5
基于深度混合架构的智能量化交易系统研究: 融合SSDA与LSTM自编码器的特征提取与决策优化方法
|
14天前
|
机器学习/深度学习 人工智能 并行计算
【AI系统】Kernel 层架构
推理引擎的Kernel层负责执行底层数学运算,如矩阵乘法、卷积等,直接影响推理速度与效率。它与Runtime层紧密配合,通过算法优化、内存布局调整、汇编优化及调度优化等手段,实现高性能计算。Kernel层针对不同硬件(如CPU、GPU)进行特定优化,支持NEON、AVX、CUDA等技术,确保在多种平台上高效运行。
68 32
|
14天前
|
存储 机器学习/深度学习 人工智能
【AI系统】计算图优化架构
本文介绍了推理引擎转换中的图优化模块,涵盖算子融合、布局转换、算子替换及内存优化等技术,旨在提升模型推理效率。计算图优化技术通过减少计算冗余、提高计算效率和减少内存占用,显著改善模型在资源受限设备上的运行表现。文中详细探讨了离线优化模块面临的挑战及解决方案,包括结构冗余、精度冗余、算法冗余和读写冗余的处理方法。此外,文章还介绍了ONNX Runtime的图优化机制及其在实际应用中的实现,展示了如何通过图优化提高模型推理性能的具体示例。
45 4
【AI系统】计算图优化架构
|
4天前
|
机器学习/深度学习 前端开发 算法
婚恋交友系统平台 相亲交友平台系统 婚恋交友系统APP 婚恋系统源码 婚恋交友平台开发流程 婚恋交友系统架构设计 婚恋交友系统前端/后端开发 婚恋交友系统匹配推荐算法优化
婚恋交友系统平台通过线上互动帮助单身男女找到合适伴侣,提供用户注册、个人资料填写、匹配推荐、实时聊天、社区互动等功能。开发流程包括需求分析、技术选型、系统架构设计、功能实现、测试优化和上线运维。匹配推荐算法优化是核心,通过用户行为数据分析和机器学习提高匹配准确性。
24 3
存储 人工智能 自然语言处理
48 6
|
2天前
|
监控 Java 数据中心
微服务架构系统稳定性的神器-Hystrix
Hystrix是由Netflix开源的库,主要用于微服务架构中的熔断器模式,防止服务调用失败引发级联故障。它通过监控服务调用的成功和失败率,在失败率达到阈值时触发熔断,阻止后续调用,保护系统稳定。Hystrix具备熔断器、资源隔离、降级机制和实时监控等功能,提升系统的容错性和稳定性。然而,Hystrix也存在性能开销、配置复杂等局限,并已于2018年进入维护模式。
11 0
|
2天前
|
前端开发 搜索推荐 安全
陪玩系统架构设计陪玩系统前后端开发,陪玩前端设计是如何让人眼前一亮的?
陪玩系统的架构设计、前后端开发及前端设计是构建吸引用户、功能完善的平台关键。架构需考虑用户需求、技术选型、安全性等,确保稳定性和扩展性。前端可选用React、Vue或Uniapp,后端用Spring Boot或Django,数据库结合MySQL和MongoDB。功能涵盖用户管理、陪玩者管理、订单处理、智能匹配与通讯。安全性方面采用SSL加密和定期漏洞扫描。前端设计注重美观、易用及个性化推荐,提升用户体验和平台粘性。
13 0
|
16天前
|
机器学习/深度学习 人工智能 调度
【AI系统】推理引擎架构
本文详细介绍了推理引擎的基本概念、特点、技术挑战及架构设计。推理引擎作为 AI 系统中的关键组件,负责将训练好的模型部署到实际应用中,实现智能决策和自动化处理。文章首先概述了推理引擎的四大特点:轻量、通用、易用和高效,接着探讨了其面临的三大技术挑战:需求复杂性与程序大小的权衡、算力需求与资源碎片化的矛盾、执行效率与模型精度的双重要求。随后,文章深入分析了推理引擎的整体架构,包括优化阶段的模型转换工具、模型压缩、端侧学习等关键技术,以及运行阶段的调度层、执行层等核心组件。最后,通过具体的开发流程示例,展示了如何使用推理引擎进行模型的加载、配置、数据预处理、推理执行及结果后处理。
46 0
下一篇
DataWorks