Redis 产生阻塞的原因,如何找到阻塞的原因

本文介绍了如何通过慢查询、大对象分析、监控CPU使用率和主从同步状态来诊断Redis性能问题。重点讲解了持久化操作可能导致的阻塞,以及内存交换、网络问题和多核CPU竞争的影响。
摘要由CSDN通过智能技术生成

如何发现慢查询

slowlog get{n}  

获取最近的n条慢查询命令, 默认对于执行超过10毫秒的命令都会记录到一个定长队列中

调整方法
  1. 修改为低算法度的命令, 如hgetall改为hmget等, 禁用keys、 sort等命令。

  2. 调整大对象: 缩减大对象数据或把大对象拆分为多个小对象

如何发现大对象

redis-cli -h{ip}- p{port} bigkeys  

查询 CPU 使用率

top

info replication

通过查看 INFO REPLICATION 命令返回的信息,管理员可以了解 Redis 复制的状态、主从节点的连接情况以及同步状态。这些信息对于监视 Redis 复制的健康状态、诊断复制问题以及进行故障排除都非常有用。

  1. 主节点信息:

    • role:指示 Redis 服务器的角色,主节点为 "master"。

    • connected_slaves:连接到主节点的从节点数量。

    • master_repl_offset:主节点复制偏移量,表示主节点的复制进度。

    • master_replid:主节点复制 ID,用于标识主节点的数据集。

  2. 从节点信息:

    • role:指示 Redis 服务器的角色,从节点为 "slave"。

    • master_host:连接的主节点的地址。

    • master_port:连接的主节点的端口。

    • master_repl_offset:从节点复制偏移量,表示从节点的复制进度。

    • master_replid:连接的主节点的复制 ID。

  3. 复制连接信息:

    • 对于每个从节点,通常会显示它们的 IP 地址、端口、复制状态、复制偏移量等信息。

  4. 主从同步状态:

    • slave0:stateslave1:state 等:显示从节点的复制状态,例如 "online" 表示在线,"connecting" 表示正在连接,"sync" 表示正在进行同步,等等。

info stats

  1. 总体统计信息:

    • total_connections_received:服务器接受的连接总数。

    • total_commands_processed:服务器执行的命令总数。

    • instantaneous_ops_per_sec:服务器当前的每秒执行命令数。

    • expired_keys:过期键的数量。

    • evicted_keys:被驱逐出内存的键的数量。

  2. 客户端统计信息:

    • connected_clients:当前连接到服务器的客户端数量。

    • blocked_clients:被阻塞等待命令执行的客户端数量。

  3. 内存统计信息:

    • used_memory:服务器当前使用的内存总量(以字节为单位)。

    • used_memory_rss:Redis 占用的物理内存总量(包括操作系统使用的内存)。

    • mem_fragmentation_ratio:内存碎片比率,表示内存碎片与已分配内存的比率。

  4. 命中率和键空间统计信息:

    • keyspace_hits:成功查找键的次数。

    • keyspace_misses:未能查找键的次数。

    • expired_keys:过期的键的数量。

    • evicted_keys:因为内存满而被驱逐的键的数量。

持久化阻塞

fork 操作

fork 操作发生在RDB和AOF重写时, Redis主线程调用fork操作产生共享内存的子进程, 由子进程完成持久化文件重写工作。 如果fork操作本身耗时过长, 必然会导致主线程的阻塞。可以执行info stats命令获取到latest_fork_usec指标, 表示Redis最近一次fork操作耗时, 如果耗时很大, 比如超过1秒, 则需要做出优化调整 。

AOF 刷盘

当我们开启AOF持久化功能时, 文件刷盘的方式一般采用每秒一次, 后台线程每秒对AOF文件做fsync操作。 当硬盘压力过大时, fsync操作需要等待, 直到写入完成。 如果主线程发现距离上一次的fsync成功超过2秒, 为了数据安全性它会阻塞直到后台线程执行fsync操作完成。 这种阻塞行为主要是硬盘压力引起, 可以查看Redis日志识别出这种情况。

HugePage写操作阻塞

子进程在执行重写期间利用Linux写时复制技术降低内存开销, 因此只有写操作时Redis才复制要修改的内存页。 对于开启Transparent HugePages的操作系统, 每次写命令引起的复制内存页单位由4K变为2MB, 放大了512倍, 会拖慢写操作的执行时间, 导致大量写操作慢查询。 例如简单的incr命令也会出现在慢查询中。

CPU竞争

进程竞争

Redis是典型的CPU密集型应用, 不建议和其他多核CPU密集型服务部署在一起。 当其他进程过度消耗CPU时, 将严重影响Redis吞吐量。 可以通过top、 sar等命令定位到CPU消耗的时间点和具体进程, 这个问题比较容易发现, 需要调整服务之间部署结构。

绑定CPU

部署Redis时为了充分利用多核CPU, 通常一台机器部署多个实例。 常见的一种优化是把Redis进程绑定到CPU上, 用于降低CPU频繁上下文切换的开销。

当Redis父进程创建子进程进行RDB/AOF重写时, 如果做了CPU绑定,会与父进程共享使用一个CPU。 子进程重写时对单核CPU使用率通常在90%以上, 父进程与子进程将产生激烈CPU竞争, 极大影响Redis稳定性。 因此对于开启了持久化或参与复制的主节点不建议绑定CPU。

内存交换

内存交换(swap) 对于Redis来说是非常致命的, Redis保证高性能的一个重要前提是所有的数据在内存中。 如果操作系统把Redis使用的部分内存换出到硬盘, 由于内存与硬盘读写速度差几个数量级, 会导致发生交换后的Redis性能急剧下降。

预防内存交换的方法有:

  • 保证机器充足的可用内存。

  • 确保所有Redis实例设置最大可用内存(maxmemory) , 防止极端情况下Redis内存不可控的增长。

  • 降低系统使用swap优先级, 如echo10>/proc/sys/vm/swappiness

网络问题

连接拒绝

当出现网络闪断或者连接数溢出时, 客户端会出现无法连接Redis的情况。 我们需要区分这三种情况: 网络闪断、 Redis连接拒绝、 连接溢出

网络闪断 一般发生在网络割接或者带宽耗尽的情况, 对于网络闪断的识别比较困难, 常见的做法可以通过sar-n DEV查看本机历史流量是否正常, 或者借助外部系统监控工具(如Ganglia) 进行识别。

Redis连接拒绝 Redis通过maxclients参数控制客户端最大连接数, 默认10000。 当Redis连接数大于maxclients时会拒绝新的连接进入,info statsrejected_connections统计指标记录所有被拒绝连接的数量:

# redis-cli -p 6384 info Stats | grep rejected_connections
rejected_connections:0  

连接溢出 这是指操作系统或者Redis客户端在连接时的问题。 这个问题的原因比较多, 例如 进程限制、backlog队列溢出

网络延迟

网络延迟取决于客户端到Redis服务器之间的网络环境。 主要包括它们之间的物理拓扑和带宽占用情况。 常见的物理拓扑按网络延迟由快到慢可分为: 同物理机>同机架>跨机架>同机房>同城机房>异地机房。 但它们容灾性正好相反, 同物理机容灾性最低而异地机房容灾性最高。 Redis提供了测量机器之间网络延迟的工具, 在redis-cli-h{host}-p{port}命令后面加入如下参数进行延迟测试:

  • --latency: 持续进行延迟测试, 分别统计: 最小值、 最大值、 平均值、采样次数。

  • --latency-history: 统计结果同--latency, 但默认每15秒完成一行统计,可通过-i参数控制采样时间。

  • --latency-dist: 使用统计图的形式展示延迟统计, 每1秒采样一次。

网卡软中断

网卡软中断是指由于单个网卡队列只能使用一个CPU高并发下网卡数据交互都集中在同一个CPU, 导致无法充分利用多核CPU的情况。 网卡软中断瓶颈一般出现在网络高流量吞吐的场景, 如下使用“top+数字1”命令可以很明显看到CPU1的软中断指标(si) 过高

总结

阻塞的内在原因

确认主线程是否存在阻塞, 检查慢查询等信息,发现不合理使用API或数据结构的情况, 如keys、 sort、 hgetall等。 关注CPU使用率防止单核跑满。 当硬盘IO资源紧张时, AOF追加也会阻塞主线程。

阻塞的外在原因

从CPU竞争、 内存交换、 网络问题等方面入手排查是否因为系统层面问题引起阻塞。

参考资料:《redis 开发与运维》

  • 20
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值