延迟基线测量

1
redis-cli ---intrinsic-latency 100 -h `host` -p `port`

参数 100 是测试将执行的秒数,时间越长越能发现延迟峰值,通常 100 秒足以发现延迟问题(服务端运行避免网络环境的影响)

慢指令监控

1
操作复杂度为 O(N) 即为慢指令
  • 使用 Redis 慢日志功能查出慢命令
  • latency-monitor(延迟监控)工具

    慢日志功能

    Redis 中的 slowlog 命令用来快速定位那些超出指定执行时间的慢命令,默认 10ms
    1
    2
    3
    4
    #配置慢日志的时间,以微秒为单位;即超过 6 ms 写入慢指令日志
    redis-cli CONFIG SET slowlog-log-slower-than 6000
    #获取最近2个慢查询命令
    SLOWLOG get 2

    延迟监控工具

    Redis 在 2.8.13 版本引入了 Latency Monitoring 功能,用于以秒为粒度监控各种事件的发生频率
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #设置延迟阈值,单位 ms
    CONFIG SET latency-monitor-threshold 9
    debug sleep 2
    latency latest
    1) 1) "command"
    2) (integer) 1645330616
    3) (integer) 2003
    4) (integer) 2003
    #事件名称
    #事件发生的最近延迟 Unix 时间戳
    #延迟时间,单位毫秒
    #该事件的最大延迟

    优化方案

    网络通信导致的延迟

    慢指令导致的延迟

    Fork 生成 RDB 导致的延迟

    禁用 Linux 内存大页(transparent huge pages)

    1
    echo never > /sys/kernel/mm/transparent_hugepage/enabled

    swap:操作系统分页

    AOF 和磁盘 I/O 导致的延迟

    1
    2
    3
    4
    5
    redis-cli CONFIG SET appendfsync no
    #no:Redis 不执行 fsync,唯一的延迟来自于 write 调用
    #everysec:Redis 每秒执行一次 fsync
    #always:每次写入操作都会执行 fsync
    把配置项 no-appendfsync-on-rewrite设置为 yes

    Redis 性能变慢

    获取当前 Redis 的基线性能;
  • 开启慢指令监控,定位慢指令导致的问题
  • 找到慢指令,使用 scan 的方式
  • 将实例的数据大小控制在 2-4GB,避免主从复制加载过大 RDB 文件而阻塞
  • 禁用内存大页,采用了内存大页,生成 RDB 期间,即使客户端修改的数据只有 50B 的数据,Redis 需要复制 2MB 的大页。当写的指令比较多的时候就会导致大量的拷贝,导致性能变慢
  • Redis 使用的内存是否过大导致使用 swap
  • AOF 配置是否合理,可以将配置项 no-appendfsync-on-rewrite 设置为 yes,避免 AOF 重写和 fsync 竞争磁盘 IO 资源,导致 Redis 延迟增加
  • bigkey 会带来一系列问题,我们需要进行拆分防止出现 bigkey,并通过 UNLINK 异步删除