一次redis缓存不均衡优化经验

背景

高并发接口,引入redis作为缓存之后,运行一段时间发现redis各个节点在高峰时段的访问量严重不均衡,有的节点访问量7000次/s,有的节点访问量500次/s

此种现象虽然暂时不影响系统使用,但是始终是个安全隐患,随着业务量逐年上涨,风险留给未来,并非一个合格码农的职业操守。必须得看看究竟是何种情况。

思考

想要优化,得现有一番思考,先得想想究竟有哪些情况会产生这种现象,才能去逐步排查,而不能盲目就去动手。

可能的原因:

  1. 数据倾斜:如果某些键的访问频率较高,而这些键又恰好分布在某几个节点上,就会导致节点的访问不均衡。这可能是因为数据分布不均匀,或者业务逻辑导致某些键的访问频率较高。
  2. 网络问题:网络延迟或带宽限制可能导致某些节点的访问速度较慢,从而使访问不均衡。
  3. 客户端连接问题:如果某些客户端连接到了某个特定节点,而其他节点上的客户端较少,就会导致节点的访问不均衡.
  4. 业务逻辑问题:是否是因为业务逻辑原因导致的频繁访问同一批数据
  5. 是否存在热key

验证

有了上述思考,就要开始去逐一排查可能的原因

1.数据倾斜排查:检查数据在节点之间的分布情况,通过查看Redis的CPU、内存指标,并未发现某个节点的负载明显高于其他节点

2.网络问题:通过监测网络延迟或带宽限制相关情况,并未发现有此种情况

3.客户端连接问题:检查客户端连接到Redis节点的方式,如果发现某些节点受到过多的请求压力,可以考虑采用负载均衡策略,将请求均匀分散到不同的节点上;通过相关检查,并未发现此类问题

4.业务逻辑问题:分析Redis访问相关业务代码及定时任务,并未发现有重复访问的逻辑存在

5.是否存在热key:通过运维获取高峰时段的访问日志,进行统计分析,

(1) 热key有两类:网点映射+以业务账号维度的数据

(2)redis访问不均衡的原因:不同客户下单高峰分布在一天不同时间段,高频访问在不同时间分布在不同节点上

方案

通过三种策略来确保redis各节点的访问均衡

1.本地缓存策略

将将要缓存的数据根据业务形态分为两类:

(1)网点类的常用数据直接缓存在本地

(2)对于高峰时期高频访问的数据,引入缓存组件Caffeine,设置相关的策略

设置大小为1M

EXPIRE_AFTER_WRITE_TIME(60s)

EXPIRE_AFTER_ACCESS_TIME(10s)

2.节点一致性策略

使用发布-订阅模式(Pub-Sub)来实现更新通知机制; 当 Redis 中的数据更新时,Redis 可以发布一个更新通知,各节点的本地缓存订阅这个通知,并根据通知更新本地缓存

3.异常解决方案

(1)异常日志记录

(2)间隔2min重试机制

(3)重试后异常告警机制

(4)数据定时同步(兜底): DB->redis、redis->本地缓存

下图为存储与访问缓存的逻辑图:

 效果

经过上述方案的实施,最终实现了:

1.redis各节点的访问量在全时段实现了均衡态

2.redis的各节点的整体QPS也下降了10%

3.像双十一双十二高峰时段接口也是稳稳的

本地缓存原理及方案选取原因

本地缓存是指将数据存储在应用程序的本地内存中,以提高数据的读取速度和访问效率。本地缓存的本质是通过将常用或热点数据保存在内存中,避免了每次访问都需要从远程或磁盘存储中读取数据的开销。

本地缓存的工作原理如下:
1.数据加载:当应用程序第一次访问某个数据时,如果该数据还未被缓存,则从远程或磁盘存储中加载数据,并将其保存在本地缓存中。
2.数据访问:当应用程序再次访问同样的数据时,首先从本地缓存中查找数据。如果数据存在于缓存中,则直接返回缓存的数据,避免了从远程或磁盘存储中读取的开销。
3.缓存更新:当数据发生变化时,需要更新缓存中的数据,以保持缓存和存储中的数据一致性。可以通过手动或自动的方式更新缓存,例如定时刷新缓存、监听数据变更事件等。
本地缓存的优势包括快速访问、低延迟、减轻了远程或磁盘存储的负载等。它适用于那些访问频率较高、数据相对稳定的场景,可以大大提高应用程序的性能和响应速度。

但是需要注意的是,本地缓存也存在一些问题,如缓存过期、缓存一致性、内存管理等。开发者需要根据具体的应用场景和需求,合理配置和管理本地缓存,以充分发挥其优势同时避免潜在的问题。

传统缓存组件方案:

FIFO:按照数据最早进入缓存的顺序进行替换。即,先进入缓存的数据先被替换掉。FIFO策略简单直观,但可能导致缓存命中率较低,因为最早进入缓存的数据可能不一定是最常用的数据。

LRU:根据数据最近被访问的时间进行替换。即,最长时间未被访问的数据会被替换掉。LRU策略基于“时间局部性”原理,认为最近被访问的数据更有可能在将来被访问,因此替换最久未被访问的数据。但实现LRU策略需要维护访问数据的顺序,可能带来一定的开销。

LFU:根据数据被访问的频率进行替换。即,最不经常被访问的数据会被替换掉。LFU策略基于“访问局部性”原理,认为最常被访问的数据更有可能在将来继续被访问,因此替换最不经常被访问的数据。但实现LFU策略需要维护数据的访问频率,可能带来更大的开销。

Caffeine
一个高性能、高命中率、接近最优的本地缓存,被称为”新一代缓存“或”现代缓存之王。

脱胎于Guava Cache , 结合LRU+LFU的优势,使用一种W-TinyLFU的算法结构

从Spring5开始,Caffeine将取代Guava Cache成为Spring默认的缓存组件

Caffeine是一个基于Java的内存缓存库,与其他缓存组件相比,它具有以下几个优势:

  1. 高性能:Caffeine被设计成高性能的缓存库,它使用了多种优化技术来提供快速的缓存访问,包括使用本地内存和原生数据结构,避免了不必要的开销。
  2. 低延迟:Caffeine的设计目标之一是提供低延迟的缓存访问。它采用了基于时间戳的缓存失效策略和预先加载机制,以减少对外部资源的依赖和等待时间。
  3. 强大的功能:Caffeine提供了丰富的功能,包括缓存过期、缓存加载、缓存刷新、缓存移除等。它支持异步加载和自定义缓存策略,可以根据具体需求进行灵活配置。
  4. 内存管理:Caffeine提供了细粒度的内存管理功能,可以设置缓存的最大大小、最大条目数、过期时间等。它还支持缓存的自动回收和大小基于权重的淘汰策略,可以有效地管理内存。
  5. 易于使用:Caffeine提供了简单易用的API,可以方便地创建和管理缓存。它还提供了详细的文档和示例代码,以帮助开发者快速上手和集成。

Caffeine在性能、延迟、功能和内存管理等方面都具有优势,适用于对缓存性能要求较高的场景。它可以作为Java应用程序的缓存解决方案,提供快速、可靠和灵活的缓存支持。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/53436.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自动化app测试python代码

环境搭建 1AppiumServer、夜神模拟器(adb连接状态)、uiautomator或Weditor 2PythonClient端想要运行,必须开启Appium服务器,因为客户端命令是发给服务端执行 3 安装依赖 pip install appium-python-client1.1.0,必…

Mr. Cappuccino的第57杯咖啡——简单手写Mybatis大致原理

简单手写Mybatis大致原理 大致原理项目结构项目代码代码测试 大致原理 底层基于JDK动态代理技术实现 项目结构 项目代码 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns…

节能延寿:ARM Cortex-M微控制器下的低功耗定时器应用

嵌入式系统的开发在现代科技中发挥着至关重要的作用。它们被广泛应用于从智能家居到工业自动化的各种领域。在本文中,我们将聚焦于使用ARM Cortex-M系列微控制器实现低功耗定时器的应用。我们将详细介绍在嵌入式系统中如何实现低功耗的定时器功能,并附上代码示例。 嵌入式系…

智能指针shared_ptr:自定义删除器

重点&#xff1a; 1.普通指针转化成智能指针。 2.智能指针创建的时候&#xff0c;第二个参数是自定义删除器&#xff0c;默认情况下&#xff0c;shared_ptr调用delete()函数。 class A { public:void Get() { cout << b << endl; }; private:int b{ 10 }; };clas…

Gson:解析JSON为复杂对象:TypeToken

需求 通过Gson&#xff0c;将JSON字符串&#xff0c;解析为复杂类型。 比如&#xff0c;解析成如下类型&#xff1a; Map<String, List<Bean>> 依赖&#xff08;Gson&#xff09; <dependency><groupId>com.google.code.gson</groupId><art…

基于STM32CubeMX和keil采用通用定时器中断实现固定PWM可调PWM波输出分别实现LED闪烁与呼吸灯

文章目录 前言1. PWM波阐述2. 通用定时器2.1 为什么用TIM142.2 TIM14功能介绍2.3 一些配置参数解释2.4 PWM实现流程&中断2.4.1 非中断PWM输出(LED闪烁)2.4.2 中断PWM输出(LED呼吸灯) 3. STM32CubeMX配置3.1 GPIO配置3.2 时钟配置3.3 定时器相关参数配置3.4 Debug配置3.5 中…

使用Vue+CSS实现汉堡图标过渡为叉号图标,有点意思

前言 本文给大家分享三个具有过渡效果的汉堡图标&#xff0c;当点击汉堡图标时&#xff0c;过渡为叉号图标。这种具有过渡特效的图标挺炫酷的&#xff0c;感觉一下子给网页增加一点新颖特色。早在2015年左右&#xff0c;国外挺多优秀门户网站都有使用类似的图标&#xff0c;那…

性能测试基础知识(三)性能指标

性能测试基础知识&#xff08;三&#xff09;性能指标 前言一、时间特性1、响应时间2、并发数3、吞吐量&#xff08;TPS&#xff09; 二、资源特性1、CPU利用率2、内存利用率3、I/O利用率4、网络带宽使用率5、网络传输速率&#xff08;MB/s&#xff09; 三、实例场景 前言 性能…

java使用openOffice将excel转换pdf时,将所有列显示在一页

1.接上文&#xff0c;格式转换的基础问题已解决&#xff0c;但还有些细节问题需要单独处理&#xff0c;如excel转换至pdf时&#xff0c;如何将所有列显示在一页的问题&#xff0c;此问题大家都有遇到&#xff0c;解决方案也比较多&#xff0c;我也尝试过重写某类&#xff0c;来…

【NLP概念源和流】 05-引进LSTM网络(第 5/20 部分)

一、说明 在上一篇博客中,我们讨论了原版RNN架构,也讨论了它的局限性。梯度消失是一个非常重要的缺点,它限制了RNN对较短序列的建模。香草 RNN 在相关输入事件和目标信号之间存在超过 5-10 个离散时间步长的时间滞时无法学习。这基本上限制了香草RNN在许多实际问题上的应用,…

IntelliJ IDEA 如何优雅的添加文档注释(附详细图解)

IntelliJ IDEA 如何优雅的添加文档注释&#xff08;附详细图解&#xff09; &#x1f4cc;提要✍✍类注释✍✍方法注释 &#x1f4cc;提要 在开发过程中&#xff0c;最常用的注释有两种&#xff1a;类注释和方法注释&#xff0c;分别是为类和方法添加作者、日期、版本号、描述等…

基于图片、无人机、摄像头拍摄进行智能检测功能

根据要求进行无人机拍摄的视频或图片进行智能识别&#xff0c;开发过程需要事项 1、根据图片案例进行标记&#xff0c;进行模型训练 2、视频模型训练 开发语言为python 根据需求功能进行测试结果如下 根据车辆识别标记进行的测试结果截图 测经过查看视频 8月1日