如何判断redis慢了

yizhihongxing

来自

https://mp.weixin.qq.com/s?__biz=MzIzOTU0NTQ0MA==&mid=2247532967&idx=1&sn=19790c981aa33502aa1e3a8abe9cd064&chksm=e92a7ca8de5df5befc6cc534cbabdb847eff41d0b7cef373191e49df38211e74f8064bd5b62f&from=industrynews&version=4.1.3.6112&platform=win#rd

一、Redis变慢了排查步骤

1、获取 Redis 实例在当前环境下的基线性能。

2、是否用了慢查询命令?如果是的话,就使用其他命令替代慢查询命令,或者把聚合计算命令放在客户端做。

3、是否对过期 key 设置了相同的过期时间?对于批量删除的 key,可以在每个 key 的过期时间上加一个随机数,避免同时删除。

4、是否存在 bigkey?对于 bigkey 的删除操作,如果你的 Redis 是 4.0 及以上的版本,可以直接利用异步线程机制减少主线程阻塞;如果是 Redis 4.0 以前的版本,可以使用 SCAN 命令迭代删除;对于 bigkey 的集合查询和聚合操作,可以使用 SCAN 命令在客户端完成。

5、Redis AOF 配置级别是什么?业务层面是否的确需要这一可靠性级别?如果我们需要高性能,同时也允许数据丢失,可以将配置项 no-appendfsync-on-rewrite 设置为 yes,避免 AOF 重写和 fsync 竞争磁盘 IO 资源,导致 Redis 延迟增加。当然, 如果既需要高性能又需要高可靠性,最好使用高速固态盘作为 AOF 日志的写入盘。

6、Redis 实例的内存使用是否过大?发生 swap 了吗?如果是的话,就增加机器内存,或者是使用 Redis 集群,分摊单机 Redis 的键值对数量和内存压力。同时,要避免出现 Redis 和其他内存需求大的应用共享机器的情况。

7、在 Redis 实例的运行环境中,是否启用了透明大页机制?如果是的话,直接关闭内存大页机制就行了。

8、是否运行了 Redis 主从集群?如果是的话,把主库实例的数据量大小控制在 2~4GB,以免主从复制时,从库因加载大的 RDB 文件而阻塞。

9、是否使用了多核 CPU 或 NUMA 架构的机器运行 Redis 实例?使用多核 CPU 时,可以给 Redis 实例绑定物理核;使用 NUMA 架构时,注意把 Redis 实例和网络中断处理程序运行在同一个 CPU Socket 上。

二、Redis为什么变慢了

1.Redis真的变慢了吗?

对 Redis 进行基准性能测试例如,我的机器配置比较低,当延迟为 2ms 时,我就认为 Redis 变慢了,但是如果你的硬件配置比较高,那么在你的运行环境下,可能延迟是 0.5ms 时就可以认为 Redis 变慢了。所以,你只有了解了你的 Redis 在生产环境服务器上的基准性能,才能进一步评估,当其延迟达到什么程度时,才认为 Redis 确实变慢了。为了避免业务服务器到 Redis 服务器之间的网络延迟,你需要直接在 Redis 服务器上测试实例的响应延迟情况。执行以下命令,就可以测试出这个实例 60 秒内的最大响应延迟:

./redis-cli --intrinsic-latency 120
Max latency so far: 17 microseconds.
Max latency so far: 44 microseconds.
Max latency so far: 94 microseconds.
Max latency so far: 110 microseconds.
Max latency so far: 119 microseconds.

36481658 total runs (avg latency: 3.2893 microseconds / 3289.32 nanoseconds per run).
Worst run took 36x longer than the average latency.

从输出结果可以看到,这 60 秒内的最大响应延迟为 119 微秒(0.119毫秒)。你还可以使用以下命令,查看一段时间内 Redis 的最小、最大、平均访问延迟

$ redis-cli -h 127.0.0.1 -p 6379 --latency-history -i 1
min: 0, max: 1, avg: 0.13 (100 samples) -- 1.01 seconds range
min: 0, max: 1, avg: 0.12 (99 samples) -- 1.01 seconds range
min: 0, max: 1, avg: 0.13 (99 samples) -- 1.01 seconds range
min: 0, max: 1, avg: 0.10 (99 samples) -- 1.01 seconds range
min: 0, max: 1, avg: 0.13 (98 samples) -- 1.00 seconds range
min: 0, max: 1, avg: 0.08 (99 samples) -- 1.01 seconds range

如果你观察到的 Redis 运行时延迟是其基线性能的 2 倍及以上,就可以认定 Redis 变慢了。

网络对 Redis 性能的影响,一个简单的方法是用 iPerf 这样的工具测试网络极限带宽。

服务器端

# iperf -s -p 12345 -i 1 -M
iperf: option requires an argument -- M
------------------------------------------------------------
Server listening on TCP port 12345
TCP window size: 4.00 MByte (default)
------------------------------------------------------------
[  4] local 172.20.0.113 port 12345 connected with 172.20.0.114 port 56796
[ ID] Interval       Transfer     Bandwidth
[  4]  0.0- 1.0 sec   614 MBytes  5.15 Gbits/sec
[  4]  1.0- 2.0 sec   622 MBytes  5.21 Gbits/sec
[  4]  2.0- 3.0 sec   647 MBytes  5.42 Gbits/sec
[  4]  3.0- 4.0 sec   644 MBytes  5.40 Gbits/sec
[  4]  4.0- 5.0 sec   651 MBytes  5.46 Gbits/sec
[  4]  5.0- 6.0 sec   652 MBytes  5.47 Gbits/sec
[  4]  6.0- 7.0 sec   669 MBytes  5.61 Gbits/sec
[  4]  7.0- 8.0 sec   670 MBytes  5.62 Gbits/sec
[  4]  8.0- 9.0 sec   667 MBytes  5.59 Gbits/sec
[  4]  9.0-10.0 sec   667 MBytes  5.60 Gbits/sec
[  4]  0.0-10.0 sec  6.35 GBytes  5.45 Gbits/sec
客户端

# iperf -c 服务器端IP -p 12345 -i 1 -t 10 -w 20K
------------------------------------------------------------
Client connecting to 172.20.0.113, TCP port 12345
TCP window size: 40.0 KByte (WARNING: requested 20.0 KByte)
------------------------------------------------------------
[  3] local 172.20.0.114 port 56796 connected with 172.20.0.113 port 12345
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0- 1.0 sec   614 MBytes  5.15 Gbits/sec
[  3]  1.0- 2.0 sec   622 MBytes  5.21 Gbits/sec
[  3]  2.0- 3.0 sec   646 MBytes  5.42 Gbits/sec
[  3]  3.0- 4.0 sec   644 MBytes  5.40 Gbits/sec
[  3]  4.0- 5.0 sec   651 MBytes  5.46 Gbits/sec
[  3]  5.0- 6.0 sec   652 MBytes  5.47 Gbits/sec
[  3]  6.0- 7.0 sec   669 MBytes  5.61 Gbits/sec
[  3]  7.0- 8.0 sec   670 MBytes  5.62 Gbits/sec
[  3]  8.0- 9.0 sec   667 MBytes  5.59 Gbits/sec
[  3]  9.0-10.0 sec   668 MBytes  5.60 Gbits/sec
[  3]  0.0-10.0 sec  6.35 GBytes  5.45 Gbits/sec

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

首先,第一步,你需要去查看一下 Redis 的慢日志(slowlog)。Redis 提供了慢日志命令的统计功能,它记录了有哪些命令在执行时耗时比较久。查看 Redis 慢日志之前,你需要设置慢日志的阈值。例如,设置慢日志的阈值为 5 毫秒,并且保留最近 500 条慢日志记录:

# 命令执行耗时超过 5 毫秒,记录慢日志
CONFIG SET slowlog-log-slower-than 5000
# 只保留最近 500 条慢日志
CONFIG SET slowlog-max-len 500

1.经常使用 O(N) 以上复杂度的命令,例如 SORT、SUNION、ZUNIONSTORE 聚合类命令2.使用 O(N) 复杂度的命令,但 N 的值非常大第一种情况导致变慢的原因在于,Redis 在操作内存数据时,时间复杂度过高,要花费更多的 CPU 资源。第二种情况导致变慢的原因在于,Redis 一次需要返回给客户端的数据过多,更多时间花费在数据协议的组装和网络传输过程中。另外,我们还可以从资源使用率层面来分析,如果你的应用程序操作 Redis 的 OPS 不是很大,但 Redis 实例的 CPU 使用率却很高,那么很有可能是使用了复杂度过高的命令导致的。

 

 

3.操作bigkey

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

redis-cli -h 127.0.0.1 -p 6379 --bigkeys -i 1
-------- summary -------
Sampled 829675 keys in the keyspace!
Total key length in bytes is 10059825 (avg len 12.13)
Biggest string found 'key:291880' has 10 bytes
Biggest   list found 'mylist:004' has 40 items
Biggest    set found 'myset:2386' has 38 members
Biggest   hash found 'myhash:3574' has 37 fields
Biggest   zset found 'myzset:2704' has 42 members
36313 strings with 363130 bytes (04.38% of keys, avg size 10.00)
787393 lists with 896540 items (94.90% of keys, avg size 1.14)
1994 sets with 40052 members (00.24% of keys, avg size 20.09)
1990 hashs with 39632 fields (00.24% of keys, avg size 19.92)
1985 zsets with 39750 members (00.24% of keys, avg size 20.03)

这里我需要提醒你的是,当执行这个命令时,要注意 2 个问题:

1.对线上实例进行 bigkey 扫描时,Redis 的 OPS 会突增,为了降低扫描过程中对 Redis 的影响,最好控制一下扫描的频率,指定 -i 参数即可,它表示扫描过程中每次扫描后休息的时间间隔,单位是秒

2.扫描结果中,对于容器类型(List、Hash、Set、ZSet)的 key,只能扫描出元素最多的 key。但一个 key 的元素多,不一定表示占用内存也多,你还需要根据业务情况,进一步评估内存占用情况。

 

原文链接:https://www.cnblogs.com/a393060727/p/17361075.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:如何判断redis慢了 - Python技术站

(0)
上一篇 2023年4月28日
下一篇 2023年4月30日

相关文章

  • 使用java实现百万级别数据导出excel的三种方式

    我来详细讲解一下“使用Java实现百万级别数据导出Excel的三种方式”的完整攻略。 一、背景介绍 随着数据量的急剧增长,在实际工作中,我们经常需要将海量数据导出到Excel中进行分析和处理。但是当数据量达到百万甚至千万级别时,传统的导出方式会遭遇一系列的问题,比如内存溢出、导出速度过慢等。在这种情况下,我们需要使用一些高效、稳定的方式实现数据的导出。本文将…

    Java 2023年5月20日
    00
  • springboot整合shiro多验证登录功能的实现(账号密码登录和使用手机验证码登录)

    SpringBoot整合Shiro多验证登录功能的实现 SpringBoot是一个快速开发Spring应用的框架,而Shiro可以方便的实现安全认证和授权,两者结合,可以非常方便的实现多验证登录功能。 SpringBoot集成Shiro 首先需要添加Shiro和SpringBoot的依赖。 <dependency> <groupId>…

    Java 2023年5月20日
    00
  • Spring配置动态数据源实现读写分离的方法

    下面是Spring配置动态数据源实现读写分离的方法的完整攻略。 什么是动态数据源? 动态数据源是指可以在应用程序运行时动态地切换不同的数据源,以便满足应用程序的需求。在实际应用程序中,常见的用途是实现数据库读写分离,将读操作分配到只读数据库,将写操作分配到主数据库。 实现步骤 引入依赖 在 pom.xml 中添加以下依赖: <dependency&gt…

    Java 2023年5月20日
    00
  • editplus怎么运行java程序?

    下面是完整的攻略: EditPlus如何运行Java程序 想要在EditPlus中运行Java程序,需要完成以下步骤: 安装Java运行时环境 配置Java环境变量 新建Java文件 编写Java代码 保存Java文件 编译Java文件 运行Java程序 接下来,将详细介绍每一步的具体操作。 1. 安装Java运行时环境 运行Java程序必须先安装Java运…

    Java 2023年5月19日
    00
  • java字符流缓冲区详解

    Java字符流缓冲区详解 在Java中,当需要对字符流进行大量读取或写入操作时,使用字符流缓冲区是一种有用的方法。本文将详细介绍Java字符流缓冲区的使用方法。 什么是字符流缓冲? Java字符流缓冲是一个内部缓冲区,用于临时存储从输入流读取的数据或要写入输出流的数据。使用缓冲区可以显著提高读写操作的性能,因为它可以减少对底层I/O的调用次数。 如何使用字符…

    Java 2023年5月27日
    00
  • jenkins+Maven从SVN上构建项目的方法

    下面我会给你详细讲解使用Jenkins和Maven从SVN上构建项目的方法,包含以下步骤: 安装Jenkins 安装Maven 构建Jenkins的SVN插件 创建Jenkins的SVN配置 创建Jenkins的Maven构建配置 创建Jenkins的构建任务 下面我们将逐一介绍这些步骤的具体内容。 1. 安装Jenkins 如果你还没有安装Jenkins,…

    Java 2023年5月20日
    00
  • 动态创建script标签实现跨域资源访问的方法介绍

    动态创建script标签实现跨域资源访问是一种常见的前端技巧,可以用于向其他域名的服务器请求数据。以下是实现该方法的具体步骤: 1. 创建一个 script 标签 在 HTML 中动态添加一个 script 标签,并设置其中的 src 属性为需要访问的资源的 URL。例如: <script src="http://example.com/da…

    Java 2023年6月15日
    00
  • Java中数组的定义与使用详解

    Java中数组的定义与使用详解 什么是数组 数组是一种线性数据结构,包含相同类型的元素,每个元素可以通过下标访问。Java 中的数组属于引用数据类型,可以动态创建并初始化,支持多维数组。 定义数组 1.一维数组 定义一维数组的方式: 数据类型[] 数组名 = new 数据类型[数组长度]; 例如: int[] nums = new int[5]; Strin…

    Java 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部