性能优化:Redis使用优化(2)

参考资料:

《Redis,该如何监控》

《Redis为什么变慢了?一文讲透如何排查Redis性能问题 | 万字长文》

相关文章:

《Redis:内存淘汰机制》

《Redis:持久化RDB与AOF》

《Redis:主从复制》

 《性能优化:Redis使用优化(1)》

        写在开头:本文为学习后的总结,可能有不到位的地方,错误的地方,欢迎各位指正。

前言

        上文中,我们介绍了Redis使用过程中操作命令、内存使用的注意事项,本文我们会继续介绍其余的相关注意事项。

目录

前言

一、硬件使用优化

        1、绑定CPU

        1、为什么要绑定CPU

        2、绑定方案

        2、网络阻塞或频繁建立短链接

二、性能监控

        1、info指令

        1.1、吞吐量

        1.2、内存利用率

        1.3、缓存命中率

        1.4、客户端连接数

        2、基准性能

        2.1、什么是基准性能

        2.2、基准性能如何测试

        3、慢日志

        4、延迟监控


一、硬件使用优化

        1、绑定CPU

        1、为什么要绑定CPU

        我们都知道,一般现代的服务器会有多个 CPU,而每个 CPU 又包含多个物理核心,每个物理核心又分为多个逻辑核心,每个物理核下的逻辑核共用 L1/L2 Cache。

        而 Redis Server 除了主线程服务客户端请求之外,还会创建子进程、子线程。其中子进程用于数据持久化,而子线程用于执行一些比较耗时操作,例如异步释放 fd、异步 AOF 刷盘、异步 lazy-free 等等。

        如果你把 Redis 进程只绑定了一个 CPU 逻辑核心上,那么当 Redis 在进行数据持久化时,fork 出的子进程会继承父进程的 CPU 使用偏好。

        而此时的子进程会消耗大量的 CPU 资源进行数据持久化(把实例数据全部扫描出来需要耗费CPU),这就会导致子进程会与主进程发生 CPU 争抢,进而影响到主进程服务客户端请求,访问延迟变大。这就是 Redis 绑定 CPU 带来的性能问题。

        2、绑定方案

        如果你确实想要绑定 CPU,可以优化的方案是,不要让 Redis 进程只绑定在一个 CPU 逻辑核上,而是绑定在多个逻辑核心上,而且,绑定的多个逻辑核心最好是同一个物理核心,这样它们还可以共用 L1/L2 Cache。

        当然,即便我们把 Redis 绑定在多个逻辑核心上,也只能在一定程度上缓解主线程、子进程、后台线程在 CPU 资源上的竞争。因为这些子进程、子线程还是会在这多个逻辑核心上进行切换,存在性能损耗。

        为此Redis官方提出可以让主线程、子进程、后台线程,分别绑定在固定的 CPU 核心上,不让它们来回切换,这样一来,他们各自使用的 CPU 资源互不影响。

        Redis 在 6.0 版本已经推出了这个功能,我们可以通过以下配置,对主线程、后台线程、后台 RDB 进程、AOF rewrite 进程,绑定固定的 CPU 逻辑核心

# Redis Server 和 IO 线程绑定到 CPU核心 0,2,4,6
server_cpulist 0-7:2
 
# 后台子线程绑定到 CPU核心 1,3
bio_cpulist 1,3
 
# 后台 AOF rewrite 进程绑定到 CPU 核心 8,9,10,11
aof_rewrite_cpulist 8-11
 
# 后台 RDB 进程绑定到 CPU 核心 1,10,11
# bgsave_cpulist 1,10-1

        这里我需要提醒你的是,一般来说,Redis 的性能已经足够优秀,除非你对 Redis 的性能有更加严苛的要求,否则不建议你绑定 CPU。从上面的分析你也能看出,绑定 CPU 需要你对计算机体系结构有非常清晰的了解,否则谨慎操作。

        2、网络阻塞或频繁建立短链接

        网络带宽过载的情况下,服务器在 TCP 层和网络层就会出现数据包发送延迟、丢包等情况。

        如果确实出现这种情况,你需要及时确认占满网络带宽 Redis 实例,如果属于正常的业务访问,那就需要及时扩容或迁移实例了,避免因为这个实例流量过大,影响这个机器的其他实例。

        频繁的短连接则会导致 Redis 大量时间耗费在连接的建立和释放上,TCP 的三次握手和四次挥手同样也会增加访问延迟。

二、性能监控

        1、info指令

        1.1、吞吐量

        吞吐量包括Redis实例历史总吞吐量,以及每秒钟的吞吐量。可以通过命令info stats中的几个得到我们要监控的吞吐量:

# 从Rdis上一次启动以来总计处理的命令数
total_commands_processed:2255
# 当前Redis实例的OPS
instantaneous_ops_per_sec:12
# 网络总入量
total_net_input_bytes:34312
# 网络总出量
total_net_output_bytes:78215
# 每秒输入量,单位是kb/s
instantaneous_input_kbps:1.20
# 每秒输出量,单位是kb/s
instantaneous_output_kbps:2.62

        1.2、内存利用率

        Redis高性能保障的一个重要资源就是足够的内存。Used memory表示Redis已经分配的总内存大小。我们可以通过info memory命令获取所有内存利用了相关数据,其结果如下:

used_memory:426679232 #由 redis 分配器分配的内存总量,以字节(byte)为单位
used_memory_human:406.91M   #以可读的格式返回 redis 分配的内存总量(实际是used_memory的格式化)
used_memory_rss:443179008 #从操作系统的角度,返回 redis 已分配的内存总量(俗称常驻集大小)。这个值和 top 、 ps等命令的输出一致
used_memory_rss_human:422.65M # redis 的内存消耗峰值(以字节为单位) 
used_memory_peak:426708912
used_memory_peak_human:406.94M
total_system_memory:16658403328
total_system_memory_human:15.51G
used_memory_lua:37888   # Lua脚本存储占用的内存
used_memory_lua_human:37.00K
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
mem_fragmentation_ratio:1.04 # used_memory_rss/ used_memory
mem_allocator:jemalloc-4.0.3

        需要注意的是,如果我们没有配置maxmemory(可以通过config get/set maxmemory查询并在不重启Redis实例的前提下设置),那么Redis可能会耗尽服务器所有可用内存,从而可能导致swap甚至被系统kill掉。

        所以建议方案是配置maxmemory,并且配置maxmemory-policy(不要是默认的noviction)。即使这样还不够,因为如果并发比较大的话,缓存逐除策略可能会忙不过来,从而依然会有无法操作Redis的错误。所以强烈建议:在配置maxmemory-policy和maxmemory双策略的前提下,对used_memory进行监控,建议是maxmemory的90%。例如maxmemory为10G,那么当used_memory达到9G的时候,进行相关预警,从而准备扩容。

        1.3、缓存命中率

        缓存命中率表示缓存的使用效率,很明显,它通过公式:HitRate = keyspace_hits / (keyspace_hits + keyspace_misses) 计算得到。在info stats中恰好有这些数据:

keyspace_hits:87  #命中次数
keyspace_misses:17   #没命中次数

        缓存命中率建议不需要低于90%,越高越好。这个命中率越低,表示越多对缓存中没有的KEY进行了访问。可能是这些KEY已经过期、已经被删除、已经被evict、或者压根儿不存在的KEY非法访问等原因。

        缓存命中率越低,或导致越多的请求穿透Redis从MySQL(或者其他速度远比Redis慢的存储服务)获取数据,从而导致越多的请求有更大的延迟,导致API耗时增加,影响用户体验。

        如果是内存不足,那么需要扩容。例如info stats中的evicted_keys不为0,或者used_memory达到了内存上限。如果是用法问题,那么需要优化代码。

        1.4、客户端连接数

        这个值可以通过info clients中的字段connected_clients获取,它会受到操作系统ulimit和redis的maxclients配置的限制。如果Rdis客户端中报出获取不到连接数的错误(异常信息:ERR max number of clients reached),需要排查这两个地方是否限制了客户端连接数。当然,也可能还有其他其他原因,比如客户端BUG导致连接没有释放等。

connected_clients:2   #已连接客户端的数量(不包括通过从属服务器连接的客户端)
client_longest_output_list:0 #当前连接的客户端当中,最长的输出列表
client_biggest_input_buf:0 #当前连接的客户端当中,最大输入缓存
blocked_clients:0 #正在等待阻塞命令(BLPOP、BRPOP、BRPOPLPUSH)的客户端的数量

        2、基准性能

        2.1、什么是基准性能

        简单来讲,基准性能就是指 Redis 在一台负载正常的机器上,其最大的响应延迟和平均响应延迟分别是怎样的。

        只有了解了你的 Redis 在生产环境服务器上的基准性能,才能进一步评估,当其延迟达到什么程度时,才认为 Redis 确实变慢了。

        2.2、基准性能如何测试

        为了避免业务服务器到 Redis 服务器之间的网络延迟,你需要直接在 Redis 服务器上测试实例的响应延迟情况。执行以下命令,就可以测试出这个实例 60 秒内的最大响应延迟:

$ redis-cli -h 127.0.0.1 -p 6379 --intrinsic-latency 60
Max latency so far: 1 microseconds.
Max latency so far: 15 microseconds.
Max latency so far: 17 microseconds.
Max latency so far: 18 microseconds.
Max latency so far: 31 microseconds.
Max latency so far: 32 microseconds.
Max latency so far: 59 microseconds.
Max latency so far: 72 microseconds.
 
1428669267 total runs (avg latency: 0.0420 microseconds / 42.00 nanoseconds per run).
Worst run took 1429x longer than the average latency.

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

        你还可以使用以下命令,查看一段时间内 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
...

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

        了解了基准性能测试方法,那么你就可以按照以下几步,来判断你的 Redis 是否真的变慢了:

  • 在相同配置的服务器上,测试一个正常 Redis 实例的基准性能
  • 找到你认为可能变慢的 Redis 实例,测试这个实例的基准性能
  • 这个实例的运行延迟是正常 Redis 基准性能的 2 倍以上

        3、慢日志

        Redis和其他关系型数据库一样,也有命令执行的慢日志。慢日志收集的阈值可通过config set slowlog-log-slower-than配置,单位是微妙。默认是10000微秒,即10ms,以Rdis的性能来说,正常的执行时间一般在10微秒级别(单实例OPS可以达到10W),如果有更高的性能要求,也可以自行调整。

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

        设置完成之后,所有执行的命令如果操作耗时超过了 5 毫秒,都会被 Redis 记录下来,然后我们就可以通过如下方式进行查看了。

127.0.0.1:6379> SLOWLOG get 5
1) 1) (integer) 32693       # 慢日志ID
   2) (integer) 1593763337  # 执行时间戳
   3) (integer) 5299        # 执行耗时(微秒)
   4) 1) "LRANGE"           # 具体执行的命令和参数
      2) "user_list:2000"
      3) "0"
      4) "-1"
2) 1) (integer) 32692
   2) (integer) 1593763337
   3) (integer) 5044
   4) 1) "GET"
      2) "user_info:1000"
...

        另外,可以通过命令slowlog reset清理掉所有保存的慢日志。

        4、延迟监控

        latency monitoring是从Redis2.8.13开始引入的新特性,用来帮组定位延迟问题,它能够记录Redis产生延迟问题的可能原因。需要通过如下命令来开启这个特性,当然,也可以在redis.conf中配置。

CONFIG SET latency-monitor-threshold 100

        接下来可以通过如下命令检查是否开启成功:

redis> latency latest
1) 1) "command"             # Event name
   2) (integer) 1539479413  # Unix timestamp
   3) (integer) 381         # Latency of latest event
   4) (integer) 6802        # All time maximum latency

# 还可以查看引起延迟的历史命令:
redis> latency history command

# 延迟诊断
redis> latency  doctor

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Redis是一个高性能的键值存储系统,它具有以下几个性能优化的方面: 1. 数据结构选择:Redis提供了多种数据结构,如字符串、哈希表、列表、集合和有序集合等。在使用Redis时,根据实际需求选择合适的数据结构,可以提高性能。 2. 内存优化Redis是基于内存的数据库,因此内存的使用对性能至关重要。可以通过以下方式进行内存优化: - 使用压缩:对于存储的数据,可以使用压缩算法进行压缩,减少内存占用。 - 使用合适的数据结构:选择合适的数据结构可以减少内存占用,例如使用哈希表代替字符串列表。 - 设置合理的过期时间:对于不再使用数据,设置合理的过期时间可以及时释放内存。 3. 持久化策略:Redis支持两种持久化方式,即RDB快照和AOF日志。选择合适的持久化方式可以提高性能。RDB快照适用于数据量较大且对数据完整性要求不高的场景,而AOF日志适用于对数据完整性要求较高的场景。 4. 集群部署:当单个Redis实例无法满足需求时,可以通过搭建Redis集群来提高性能和可用性。Redis集群可以将数据分布在多个节点上,实现数据的分片和负载均衡。 5. 网络优化:在网络传输方面,可以通过以下方式进行优化: - 使用高性能的网络协议:Redis支持多种网络协议,如TCP和Unix域套接字。选择合适的网络协议可以提高性能。 - 合理设置网络参数:根据实际情况,设置合理的网络参数,如TCP连接超时时间、最大连接数等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值