Redis性能大挑战:深入剖析缓存抖动现象及有效应对的战术指南

news2024/12/24 9:00:36

        在实际应用中,你是否遇到过这样的情况,本来Redis运行的好好的,响应也挺正常,但突然就变慢了,响应时间增加了,这不仅会影响用户体验,还会牵连其他系统。

        那如何排查Redis变慢的情况呢?首先有个问题需要确定,就是确定Redis是否真的变慢了。

Redis基线性能

        要判断Redis是否变慢了,一个最直接的方法就是查看Redis的响应时间。

        大部分情况下,Redis的延迟很低,但是在某些情况下,Redis会出现很高的延迟,可能会达到几秒甚至更长,不过持续的时间又不长,这到底是怎么情况呢?如果出现了响应延迟到秒级别就可以确定Redis变慢了。

        首先需要先确定Redis的延迟绝对值,但是在不同运行环境下,Redis的绝对性能是不同的。所以就需要当前环境的基线性能,所谓基线性能,就是一个系统在低压力、无干扰下的基本性能,这个性能只由当前软硬件环境配置决定。

        基线性能可以通过Redis提供的命令来确定,具体为在redis-cli中添加--intrinsic-latency选项,可以用来检测和统计Redis在运行期间内的最大延迟,这就可以作为基线性能。

redis-cli -h localhost --intrinsic-latency 120
Max latency so far: 1 microseconds.
Max latency so far: 29 microseconds.
Max latency so far: 31 microseconds.
Max latency so far: 34 microseconds.
Max latency so far: 53 microseconds.
Max latency so far: 68 microseconds.
Max latency so far: 103 microseconds.
Max latency so far: 106 microseconds.
Max latency so far: 142 microseconds.
Max latency so far: 158 microseconds.
Max latency so far: 164 microseconds.
Max latency so far: 273 microseconds.
Max latency so far: 296 microseconds.
Max latency so far: 673 microseconds.
Max latency so far: 946 microseconds.
Max latency so far: 2138 microseconds.
Max latency so far: 2234 microseconds.
Max latency so far: 16164 microseconds.

2383205581 total runs (avg latency: 0.0504 microseconds / 50.35 nanoseconds per run).
Worst run took 321018x longer than the average latency.

        在自己的电脑上运行命令后,会打印120秒内检测到的最大延迟,可以看到这里的最大延迟为16164微妙,16ms左右。一般情况下,检测120s的时长已经够了。

        一般来说,运行时响应时间和基线性能做对比,如果响应时间达到了基线性能的2倍以上,就可以认定Redis变慢了。

Redis变慢的原因

        一旦发现变慢了,接下来就要查找原因解决这个问题了。这个过程要基于Redis本身的工作原理,并结合和它交互的操作系统、存储以及网络等外部系统的关键机制,在借助一些辅助工具来定位问题,并指定行之有效的解决方案。

        Redis变慢的原因有几下几点,如图所示:Redis变慢的原因

        慢查询指令

        慢查询命令,指在Redis中执行速度慢的命令,这会导致Redis延迟增加。Redis提供的命令操作很多,并不是所有命令都慢,这和命令操作的复杂度有关,所以我们必须知道不同命令的复杂度。

        比如,操作的value为String类型时,由于操作的事hash表,这个操作的复杂度是固定的,都是O(1),除非出现了hash碰撞严重。但操作的数据类型为集合时,如果集合中包含大量的元素,那这个操作复杂度是比较高的,会比较耗时。

        Redis官网提供了各个命令的复杂度:Commands | Redisicon-default.png?t=N7T8https://redis.io/commands/        如果有复杂的操作,就要考虑是否需要用简单的命令来替换。如果使用keys命令,查询大量的key,也会导致慢查询,因为需要扫描所有的键值对,所以生产环境要禁用这样的命令。

        删除key操作

        如果Redis中key过期了是会被自动删除的,这也是Redis的回收机制,Redis 的 key可以设置过期时间,默认情况下,每100ms就会扫描一次,删除过期的key,具体如下:

  • 采样ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP个数的key,并将其中过期的key全部删除;
  • 如果超过25%的key过期了,则重复删除过程,直到过期key的比例降至25%以下。

        如果触发了第二条规则,Redis就会一直删除以释放内存空间。注意,删除操作是阻塞的(Redis 4.0提供了异步机制减少阻塞)。所以一旦触发了就会一直删除key,这样一来,就没办法给客户端提供服务了。

        磁盘I/O:AOF

        为了保证数据的可靠性,Redis提供了AOF和RDB两种机制(想具体了解请查看:Redis持久化(AOF、RDB)用到的写时复制到底是什么-CSDN博客)。其中AOF提供了三种写回策略:always、everysec、no,这三种写回策略依赖文件系统来完成,也就是write和fsync。

        write把日志写到内核的缓冲区,就可以返回了,并不需要等待日志实际写回磁盘;而fsync需要把日志记录写回到磁盘才能返回,时间较长。

        当写回策略配置为everysec和always时,Redis需要调用fsync把日志写回磁盘。但是这两种写回策略的具体情况不一样。但不管怎么说,都会涉及到写回磁盘,而且fsync通常比较耗时,如果Redis主线程执行写回,就会造成阻塞。

        另外AOF日志重写时,也容易阻塞主线程,所以Redis使用了子线程来完成该操作。但是AOF重写会对磁盘又大量的IO操作,同时fsync又需要等到数据写到磁盘才能返回,所以,当AOF重写的压力比较大时,就会导致fsync阻塞,虽然fsync由后台子线程完成,但是主线程会监测fsync的执行进度。

        当主线程使用子线程执行了一次fsync,需要再次把接收的数据写回磁盘,如果主线程发现上一次的fsync还没有执行完,那么它就会阻塞。所以,如果后台线程执行fsync频繁阻塞的话,主线程也会阻塞,导致Redis性能变慢。

        内存大页

        内存大页机制也会影响Redis性能。Linux内核从2.6.38开始支持内存大页,支持2MB大小的内存页分配,而常规的也大小是4KB。你可能会说,Redis是内存数据库,内存大页对Redis不是有好处的吗,减少了内存的分配,但是任何事都有两面性,这时一个权衡的过程。

        Redis为了提高可靠性,提供了持久化的机制。这个过程需要额外的线程来执行,所以不会阻塞主线程为客户端提供服务。如果在持久化的过程中,客户端修改了数据,Redis会才用写时复制(Copy On Write)机制,数据一旦修改了不会直接修改内存中的数据,而是复制一份,然后再进行修改。

        如果采用了内存大页,那Redis就需要拷贝该大页。如果关闭了内存大页,那需要拷贝的页数据只有4kb,可见内存大页会复制大量数据。

        所以正常情况下,关闭内存大页就可以了。

        swap操作

        操作系统swap是将内存数据在内存和磁盘来回换入核换出的机制,涉及到磁盘的读写。所以一旦涉及到了swap,其性能都会收到磁盘性能的影响。

        Redis是内存数据库,内存使用量大,如果用Redis保存海量数据,而且没有控制好内存使用量,就可能会触发swap机制,从而影响性能。一旦触发swap机制,Redis需要操作磁盘才能完成,这回极大的降低Redis的性能。

        关于海量数据的处理请参考:面对海量数据Redis如何应对-CSDN博客

        Redis对于swap的排查有现成的命令,具体这里不做详细介绍了。

        内存碎片

        内存碎片很好理解,明明有内存空间,但是申请时就是无法分配需要的内存空间,这对于使用内存的Redis来说无疑影响巨大。

        内存碎片的原因

  1. 内存不是按需分配的,操作系统为了减少内存的分配次数,每次都是按照固定大小进行内存分配的,例如8字节、16字节、32字节等,比如申请了20字节的内存,但是实际上会分配32字节,此时如果在写入5字节数据,就不用再申请内存了,减少了内存申请的次数。
  2. Redis键值对大小不一和删除操作的影响,内存分配器只能按照固定大小分配内存。所以,分配的内存空间一般都会比申请的空间大一些,不会完全一直,这本身就会造成一定碎片,降低内存空存储效率。键值对会被修改或删除,这会导致空间的扩容和释放。一方面,如果修改后的键值对变大或变小了,就需要占用额外的空间或释放不用的空间。另一方面,删除的键值对就不在需要内存空间了,此时会把空间释放出来,变成空闲空间。

        如何判断内存碎片

        Redis是内存数据库,内存利用率的高低直接关系到Redis运行效率的高低。为了让用户能监控到实时的内存使用情况,Redis自身提供了info命令,可以用来查询内存使用的详细信息

info memory
# Memory
used_memory:1143520
used_memory_human:1.09M
used_memory_rss:1114112
used_memory_rss_human:1.06M
used_memory_peak:1144672
used_memory_peak_human:1.09M
used_memory_peak_perc:99.90%
used_memory_overhead:1096754
used_memory_startup:1079248
used_memory_dataset:46766
used_memory_dataset_perc:72.76%
allocator_allocated:1098416
allocator_active:1076224
allocator_resident:1076224
total_system_memory:8589934592
total_system_memory_human:8.00G
used_memory_lua:37888
used_memory_lua_human:37.00K
used_memory_scripts:0
used_memory_scripts_human:0B
number_of_cached_scripts:0
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
allocator_frag_ratio:1.1
allocator_frag_bytes:18446744073709529424
allocator_rss_ratio:1.00
allocator_rss_bytes:0
rss_overhead_ratio:1.04
rss_overhead_bytes:37888
mem_fragmentation_ratio:1.01
mem_fragmentation_bytes:15696
mem_not_counted_for_evict:0
mem_replication_backlog:0
mem_clients_slaves:0
mem_clients_normal:16986
mem_aof_buffer:0
mem_allocator:libc
active_defrag_running:0
lazyfree_pending_objects:0

        mem_fragmentation_ratio指标表示内存碎片化率,该值大于1但小于1.5时,这种情况是正常的,因为内存碎片是无法避免的。如果该值大于1.5,就表名内存碎片化率比较严重了,超过了50%,这时需要采取措施来处理内存碎片化。

        Redis从4.0版本后提供了专门清理内存碎片化的参数,通过该参数来设置内存碎片化的清理的开始和结束时机,以及占用CPU比例,从而减少碎片清理对Redis本身请求处理的性能影响。

config set activedefrag yes

        这个命令只是启动了自动清理功能,但具体什么时候清理,会受下面两个参数的控制。这两个参数分别设置了触发内存清理的一个条件,如果同时满足这两个条件,就开始清理,清理过程中,只要有一个条件不满足,就停止清理。

  • active-defrag-ignore-bytes 100mb:表示内存碎片的字节数达到100MB时,就开始清理。
  • active-defrag-threshold-lower 10:表示内存碎片空间占操作系统分配给Redis的总空间比例达到10%时,开始清理。

总结

        关于Redis变慢的问题排查就介绍到这里,不知道你有没有清晰的思路,欢迎关注并留言讨论。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

隧道自动化监测系统的主要产品和监测内容

一、背景 随着交通行业的不断发展,隧道作为交通基础设施的重要组成部分,其安全和稳定性对于保障人们的生命财产安全具有重要意义。隧道自动化监测系统作为一种先进的安全监测手段,能够实时监测隧道内部的各项参数,为隧道的安全运…

Kubernetes的动态pv

pv和pvc存储卷 存储卷: emptyDir:容器内部,随着pod销毁,emptyDir也会消失,不能做数据持久化 hostPath:持久化存储数据可以和节点上目录做挂载,pod被销毁了数据还在 NfS:一台机器,提供pod内容器所有的挂…

Elasticsearch 索引文档时create、index、update的区别【学习记录】

本文基于elasticsearch7.3.0版本。 一、思维导图 elasticsearch中create、index、update都可以实现插入功能,但是实现原理并不相同。 二、验证index和create 由上面思维导图可以清晰的看出create、index的大致区别,下面我们来验证下思维导图中的场景&…

2023年山东省职业院校技能大赛高职组信息安全管理与评估 理论题(正式赛)

2023年山东省职业院校技能大赛高职组信息安全管理与评估 理论题 理论技能与职业素养(100分) 2023年山东省职业院校技能大赛高职组信息安全管理与评估 理论题 【注意事项】 Geek极安云科专注技能竞赛技术提升,基于各大赛项提供全面的系统性…

大数据系列之:腾讯云服务器性能和价格比较

大数据系列之:腾讯云服务器性能和价格比较 一、磁盘性能和价格比较二、高性能云硬盘三、ssd云硬盘四、极速型ssd云硬盘五、增强型ssd云硬盘六、查看腾讯云服务器价格 一、磁盘性能和价格比较 磁盘名称高性能ssd云硬盘极速型ssd云硬盘增强型ssd云硬盘规格500g 5800 …

九州金榜|提高孩子认知,让问题自动消失

哈佛大学教授桑斯坦曾提出一个概念,叫做“信息茧房”。 意思是说:人们关注的信息领域,会习惯性地被自己的思想所引导,当你长时间接受单一观点时,就像蚕茧一样把自己越包越紧,越来越封闭。 走不出认知逻辑…

爬虫01-爬虫原理以及爬虫前期准备工作

文章目录 1 爬虫基本原理什么是爬虫爬虫功能详解爬虫基本流程两个概念:request和response 2 一些问题爬虫能抓取什么样的数据?抓取的数据怎么提取部分内容?数据解析方式。为什么我爬虫抓取的数据和浏览器看到的不一样怎样解决JavaScript渲染的…

数字档案安全与高效管理的先锋——亚信安慧AntDB数据库

档案工作在维护历史真实面貌、保障人民利益方面具有至关重要的作用。随着社会的发展,数字化转型成为档案管理领域的不可逆趋势。数字档案的存储和传输已经成为档案工作的重要组成部分,然而,这也伴随着一系列的挑战,其中安全风险是…

window11后台服务优化记录

这里:\WINDOWS\xxx\svchost.exe -k netsvcs -p 信号聚合器服务,用于根据时间、网络、地理位置、蓝牙和 CDF 因素评估信号。支持的功能包括设备解锁、动态锁定和动态 MDM 策略 参考: 优化参考v1

时间差异导致数据缺失,如何调整Grafana时间与Prometheus保持同步?

Grafana时间如何调快或调慢? 在k8s环境中,常使用prometheusgrafana做监控组件,prometheus负责采集、存储数据,grafana负责监控数据的可视化。 在实际的使用中,有时会遇到这样的问题,k8s集群中的时间比真实…

Zabbix6.4 监控系统 密码忘记怎么办

Zabbix6.4 监控系统 密码忘记怎么办? 如下图 本次主要介绍在Zabbix6.4中重置用户密码的步骤。 步骤 如果您忘记了Zabbix密码并且无法登录,请向Zabbix管理员求助。 超级管理员用户可以在用户配置表单中更改所有用户的密码。 如果超级用户忘记了密码&a…

C++指针小练习

双色球统计1-33个数字出现的次数(很详细) 做这个题一定要注意审题:题目要求是统计1-33个数字出现的次数,而不是前六个数字出现的次数 算法设计: ①:用一个数组p1来保存每一行的数据,再用一个数组p2来遍历1-33个数字,因为是要统计这33个数字出现的次数所以将数组初始化为0, ②…

2023年全国职业院校技能大赛(高职组)“云计算应用”赛项赛卷⑦

2023年全国职业院校技能大赛(高职组) “云计算应用”赛项赛卷7 目录 需要竞赛软件包环境以及备赛资源可私信博主!!! 2023年全国职业院校技能大赛(高职组) “云计算应用”赛项赛卷7 模块一 …

建模软件Rhinoceros mac介绍说明

Rhinoceros mac是一款3D设计软件“犀牛”,在当今众多三维建模软件中,Rhinoceros 版因为其体积小、功能强大、对硬件要求低而广受欢迎,对于专业的3D设计人员来说它是一款不错的3D建模软件,Rhinoceros Mac中文版能轻易整合3DS MAX与…

关于对象存储的若干事

引言 最近在阅读鸣嵩的一篇文章,数据库的下一场革命:S3 延迟已降至原先的 10%,云数据库架构该进化了 收获很多,过去时间也基于对象存储做过一些功能实现,特记录下。关于鸣嵩: 曹伟,花名鸣嵩&am…

Python爬虫—requests模块简单应用

Python爬虫—requests模块简介 requests的作用与安装 作用:发送网络请求,返回响应数据 安装:pip install requests requests模块发送简单的get请求、获取响应 需求:通过requests向百度首页发送请求,获取百度首页的…

2023 年度总结—总结我今年的AI之路-多项目实战经验谈AI发展前景

各位好,我是难忘,对人工智能方向有所研究,今年一年除了开发了几个软件项目之外的时间,基本都用到了学习研究AI上,最近几个月也是产出了几款AI领域的爆火文章,也把自己学习AI的笔记写了一个专栏,…

共融共生:智慧城市与智慧乡村的协调发展之路

随着科技的飞速发展和全球化的不断深入,智慧城市和智慧乡村作为现代社会发展的重要组成部分,正逐渐成为人们关注的焦点。然而,在追求经济发展的过程中,城乡发展不平衡的问题也日益凸显。因此,如何实现智慧城市与智慧乡…

FAST OS DOCKER 可视化Docker管理工具

介绍 FAST OS DOCKER 界面直观、简洁,非常适合新手使用,方便大家轻松上手 docker部署运行各类有趣的容器应用,同时 FAST OS DOCKER 为防止服务器负载过高,进行了底层性能优化;其以服务器安全为基础,对其进…

基于elementUI的el-table组件实现按住某一行数据上下滑动选中/选择或取消选中/选择鼠标经过的行

实现代码 <template><div :class"$options.name"><el-tablestyle"user-select: none"ref"table":data"tableData":row-class-name"row_class_name"mousedown.native"mousedownTable"row-click&q…