您的位置:首页 > 房产 > 建筑 > 重庆设计院_免费咨询图片素材_近期国内新闻_seo引擎搜索网址

重庆设计院_免费咨询图片素材_近期国内新闻_seo引擎搜索网址

2024/12/25 1:30:24 来源:https://blog.csdn.net/qq_26733517/article/details/144565058  浏览:    关键词:重庆设计院_免费咨询图片素材_近期国内新闻_seo引擎搜索网址
重庆设计院_免费咨询图片素材_近期国内新闻_seo引擎搜索网址

  如果观察到,这个实例的运行延迟是正常 Redis 基准性能的 2 倍以上,即可认为这个 Redis 实例确实变慢了。

1.如何查看实例的运行延迟

  (1)redis-cli -h 127.0.0.1 -p 6379 --intrinsic-latency 60   执行该命令,就可以测试出这个实例 60 秒内的最大响应延迟,如下图:

  从输出结果可以看到,这 60 秒内的最大响应延迟为 72 微秒(0.072毫秒)

(2)redis-cli -h 127.0.0.1 -p 6379 --latency-history -i 1   通过该命令查看一段时间内 Redis 的最小、最大、平均访问延迟,如下图:

  以上输出结果是,每间隔 1 秒,采样 Redis 的平均操作耗时,其结果分布在 0.08 ~ 0.13 毫秒之间。

(3)执行redis-benchmark -h 127.0.0.1 -p 6379 -t set,lpush -n 100000 -c 50,这个命令会模拟50个并发客户端,每个客户端发送10万个请求,请求命令为set,lpush(如果省略每种命令都会执行一遍),对指定的Redis服务器进行性能测试。

2.使用复杂度过高的命令

  通过SLOWLOG get 5命令,查看 Redis 的慢日志(slowlog),找出执行慢的命令操作。

   如果应用程序执行的Redis命令有以下特点,那么有可能会导致操作延迟变大:

  • 经常使用 O(N) 以上复杂度的命令,例如 SORT、SUNION、ZUNIONSTORE 聚合类命令: 导致变慢的原因在于,Redis 在操作内存数据时,时间复杂度过高,要花费更多的 CPU 资源     优化建议:对于数据的聚合操作,放在客户端做

  • 使用 O(N) 复杂度的命令,但 N 的值非常大: 导致变慢的原因在于,Redis 一次需要返回给客户端的数据过多,更多时间花费在数据协议的组装和网络传输过程中    优化建议: 执行 O(N) 命令,保证 N 尽量的小(推荐 N <= 300),每次获取尽量少的数据,让 Redis 可以及时处理返回   N表示命令的个数

3.操作bigkey

  如果查询慢日志发现,并不是复杂度过高的命令导致的,而都是 SET / DEL 这种简单命令出现在慢日志中,那么就要怀疑实例否写入了 bigkey。

  如果一个key写入的value非常大,那么Redis在分配内存时就会比较耗时。同样的,当删除这个key时,释放内存也会比较耗时。

  通过使用bigkey的命令,扫描大值key, 其实,使用这个命令的原理,就是 Redis 在内部执行了 SCAN 命令,遍历整个实例中所有的 key,然后针对 key 的类型,分别执行 STRLEN、LLEN、HLEN、SCARD、ZCARD 命令,来获取 String 类型的长度、容器类型(List、Hash、Set、ZSet)的元素个数。

  优化建议:

  • 业务应用尽量避免写入 bigkey

  • 如果你使用的 Redis 是 4.0 以上版本,用 UNLINK 命令替代 DEL,此命令可以把释放 key 内存的操作,放到后台线程中去执行,从而降低对 Redis 的影响

  •  如果你使用的 Redis 是 6.0 以上版本,可以开启 lazy-free 机制(lazyfree-lazy-user-del = yes),在执行 DEL 命令时,释放内存也会放到后台线程中执行

4.集中过期

  如果发现,平时在操作 Redis 时,并没有延迟很大的情况发生,但在某个时间点突然出现一波延时,其现象表现为:变慢的时间点很有规律,例如某个整点,或者每间隔多久就会发生一波延迟。如果是出现这种情况,那么需要排查一下,业务代码中是否存在设置大量 key 集中过期的情况。

(1)为什么集中过期会导致 Redis 延迟变大?

  答:Redis 的过期数据采用被动过期 + 主动过期两种策略:

  • 被动过期:只有当访问某个 key 时,才判断这个 key 是否已过期,如果已过期,则从实例中删除

  • 主动过期:Redis 内部维护了一个定时任务,默认每隔 100 毫秒(1秒10次)就会从全局的过期哈希表中随机取出 20 个 key,然后删除其中过期的 key,如果过期 key 的比例超过了 25%,则继续重复此过程,直到过期 key 的比例下降到 25% 以下,或者这次任务的执行耗时超过了 25 毫秒,才会退出循环

  注意,这个主动过期 key 的定时任务,是在 Redis 主线程中执行的。也就是说如果在执行主动过期的过程中,出现了需要大量删除过期 key 的情况,那么此时应用程序在访问 Redis 时,必须要等待这个过期任务执行结束,Redis 才可以服务这个客户端请求。此时就会出现,应用访问 Redis 延时变大。如果此时需要过期删除的是一个 bigkey,那么这个耗时会更久。而且,这个操作延迟的命令并不会记录在慢日志中。因为慢日志中只记录一个命令真正操作内存数据的耗时,而 Redis 主动删除过期 key 的逻辑,是在命令真正执行之前执行的。

   优化建议:

  • 集中过期 key 增加一个随机过期时间,把集中过期的时间打散,降低 Redis 清理过期 key 的压力

  • 如果你使用的 Redis 是 4.0 以上版本,可以开启 lazy-free 机制,当删除过期 key 时,把释放内存的操作放到后台线程中执行,避免阻塞主线程。  lazyfree-lazy-expire yes

5.实例内存达到上限

  如果你的Redis实例设置了内存上限maxmemory,那么也有可能导致Redis变慢,当Redis内存达到maxmemory后,每次写入新的数据之前,Redis必须先从实例中踢出一部分数据,让整个实例的内存维持在maxmemory之下,然后才能把新数据写进来。这个踢出旧数据的逻辑也是需要消耗时间的,而具体耗时的长短,要取决于你配置的淘汰策略。

    需要注意的是,Redis 的淘汰数据的逻辑与删除过期 key 的一样,也是在命令真正执行之前执行的,也就是说它也会增加我们操作 Redis 的延迟,而且,写 OPS 越高,延迟也会越明显。

  优化建议:

  • 避免存储 bigkey,降低释放内存的耗时

  • 淘汰策略改为随机淘汰,随机淘汰比 LRU 要快很多(视业务情况调整)

  • 拆分实例,把淘汰 key 的压力分摊到多个实例上

  • 如果使用的是 Redis 4.0 以上版本,开启 layz-free 机制,把淘汰 key 释放内存的操作放到后台线程中执行(配置 lazyfree-lazy-eviction = yes)

6.fork耗时严重

  主进程创建子进程( RDB 和 AOF ),会调用操作系统提供的fork函数。而fork在执行过程中,主进程需要拷贝自己的内存页表给子进程,如果这个实例很大,那么这个拷贝的过程也会比较耗时。而且这个fork过程会消耗大量的CPU资源,在完成fork之前,整个Redis实例会被阻塞住,无法处理任何客户端请求。

  (1)那如何确认确实是因为 fork 耗时导致的 Redis 延迟变大呢?

  答:在Redis上执行INFO命令,查看latest_fork_usec项,单位微秒。latest_fork_usec:59477  这个时间就是主进程在fork子进程期间,整个实例阻塞无法处理客户端请求的时间, 如果发现这个耗时很久,就要警惕起来了,这意味在这期间,整个 Redis 实例都处于不可用的状态。

  优化建议:

  • 控制 Redis 实例的内存:尽量在 10G 以下,执行 fork 的耗时与实例大小有关,实例越大,耗时越久

  • 合理配置数据持久化策略:在 slave 节点执行 RDB 备份,推荐在低峰期执行,而对于丢失数据不敏感的业务(例如把 Redis 当做纯缓存使用),可以关闭 AOF 和 AOF rewrite

  • Redis 实例不要部署在虚拟机上:fork 的耗时也与系统也有关,虚拟机比物理机耗时更久

  • 降低主从库全量同步的概率:适当调大 repl-backlog-size 参数(环形内存的大小),避免主从全量同步

7.开启内存大页

  我们都知道,应用程序向操作系统申请内存时,是按内存页进行申请的,而常规的内存页大小是 4KB。Linux 内核从 2.6.38 开始,支持了内存大页机制,该机制允许应用程序以 2MB 大小为单位,向操作系统申请内存。应用程序每次向操作系统申请的内存单位变大了,但这也意味着申请内存的耗时变长。

(1)这对 Redis 会有什么影响呢?

   答:主要跟redis的 Copy On Write机制有关。 主进程在拷贝内存数据时,这个阶段就涉及到新内存的申请,如果此时操作系统开启了内存大页,那么在此期间,客户端即便只修改 10B 的数据,Redis 在申请内存时也会以 2MB 为单位向操作系统申请,申请内存的耗时变长,进而导致每个写请求的延迟增加,影响到 Redis 性能。 同样地,如果这个写请求操作的是一个 bigkey,那主进程在拷贝这个 bigkey 内存块时,一次申请的内存会更大,时间也会更久。

  优化建议:

  对于 Redis 这种对性能和延迟极其敏感的数据库来说,我们希望Redis在每次申请内存时,耗时尽量短,所以不建议你在Redis机器上开启这个机制。

  查看 Redis 机器是否开启了内存大页 :cat /sys/kernel/mm/transparent_hugepage/enabled

  关闭redis内存大页机制 :echo never > /sys/kernel/mm/transparent_hugepage/enabled

8.AOF刷盘机制

  根据业务需求选择AOF三种不同的刷盘时机,不同的处理策略会提升redis的性能。

  在 Redis.conf 配置文件中的 appendfsync 配置项可以有以下 3 种参数可填:

  • Always,这个单词的意思是「总是」,所以它的意思是每次写操作命令执行完后,同步将 AOF 日志数据写回硬盘;主线程

  • Everysec,这个单词的意思是「每秒」,所以它的意思是每次写操作命令执行完后,先将命令写入到 AOF 文件的内核缓冲区,然后每隔一秒将缓冲区里的内容写回到硬盘; AOF 刷盘线程(异步)

  • No,意味着不由 Redis 控制写回硬盘的时机,转交给操作系统控制写回的时机,也就是每次写操作命令执行完后,先将命令写入到 AOF 文件的内核缓冲区,再由操作系统决定何时将缓冲区内容写回硬盘。

9.使用Swap

  如果发现 Redis 突然变得非常慢,每次的操作耗时都达到了几百毫秒甚至秒级,那此时就需要检查Redis是否使用到了 Swap,在这种情况下Redis基本上已经无法提供高性能的服务了。

  (1)什么是swap?

   答:如果对操作系统有些了解,就会知道操作系统为了缓解内存不足对应用程序的影响,允许把一部分内存中的数据换到磁上,以达到应用程序对内存使用的缓冲,这些内存数据被换到磁盘上的区域,就是 Swap。问题就在于,当内存中的数据被换到磁盘上后,Redis 再访问这些数据时,就需要从磁盘上读取,访问磁盘的速度要比访问内存慢几百倍!

(2) 查看Redis 进程是否使用到了 Swap?

  答:# 先找到 Redis 的进程 ID               $ ps -aux | grep redis-server

   # 查看 Redis Swap 使用情况           $ cat /proc/$pid/smaps | egrep '^(Swap|Size)'

  输出结果如下:

   每一行Size表示Redis所用的一块内存大小,Size下面的Swap就表示这块Size大小的内存,有多少数据已经被换到磁盘上了,如果这两个值相等,说明这块内存的数据都已经完全被换到磁盘上了。如果只是少量数据被换到磁盘上,例如每一块Swap占对应Size的比例很小,那影响并不是很大。如果是几百兆甚至上GB的内存被换到了磁盘上,那么你就需要警惕了,这种情况Redis的性能肯定会急剧下降。

  优化建议:

  • 增加机器的内存,让 Redis 有足够的内存可以使用

  • 整理内存空间,释放出足够的内存供 Redis 使用,然后释放 Redis 的 Swap,让 Redis 重新使用内存

10.碎片整理

  Redis 的数据都存储在内存中,当我们的应用程序频繁修改 Redis 中的数据时,就有可能会导致 Redis 产生内存碎片,内存碎片会降低 Redis 的内存使用率

(1)如何计算碎片率?

  答:可以通过执行 INFO 命令,得到这个实例的内存碎片率, mem_fragmentation_ratio = used_memory_rss / used_memory。其中 used_memory 表示 Redis 存储数据的内存大小,而 used_memory_rss 表示操作系统实际分配给 Redis 进程的大小。如果 mem_fragmentation_ratio > 1.5,说明内存碎片率已经超过了 50%,这时我们就需要采取一些措施来降低内存碎片了。

  优化建议:

  • 如果你使用的是 Redis 4.0 以下版本,只能通过重启实例来解决

  • 如果你使用的是 Redis 4.0 版本,它正好提供了自动碎片整理的功能,可以通过配置开启碎片自动整理:开启自动内存碎片整理(总开关):activedefrag yes;当碎片达到 100mb 时,开启内存碎片整理:active-defrag-ignore-bytes 100mb; 当碎片超过 10% 时,开启内存碎片整理:active-defrag-threshold-lower 10;内存碎片超过 100%,则尽最大努力整理:active-defrag-threshold-upper 100;内存自动整理占用资源最小百分比:active-defrag-cycle-min 25; 内存自动整理占用资源最大百分比:active-defrag-cycle-max 75。

  但是,开启内存碎片整理,它也有可能会导致 Redis 性能下降,原因在于,Redis 的碎片整理工作是也在主线程中执行的,当其进行碎片整理时,必然会消耗 CPU 资源,产生更多的耗时,从而影响到客户端的请求。所以,当你需要开启这个功能时,最好提前测试评估它对 Redis 的影响。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com