• Redis 延迟分析


    Redis 延迟分析

     

    Posted on January 31, 2016

    本文是阅读redis latency 以及 redis latency-monitor 后的总结, 部分翻译, 部分笔记


    测量延迟

    redis-cli --latency -h `host` -p `port`
    

    redis 内建延迟监控工具

    开启延迟监控

    CONFIG SET latency-monitor-threshold 100 单位为毫秒

    默认情况latency-monitor-threshold为0, 即延迟监控是关闭的

    延迟监控功能占用内存很小, 不过对于性能良好的redis也没有必要开启

    • LATENCY LATEST
    • LATENCY HISTORY event-name
    • LATENCY RESET [event-name … event-name]
    • LATENCY GRAPH event-name
    • LATENCY DOCTOR

    各种延迟的原因

    内在延迟

    操作系统会造成一定的延迟, 称作intrinsic latency

    如何测量(版本需要 2.8.7 及以上):

    ./redis-cli --intrinsic-latency 100
    

    100代表需要测试的时间, 单位为秒

    注意这个测量需要在redis server本机执行,

    intrinsic latency 会受系统负载影响

    网络通信延迟

    通常1G网卡的延迟时间是200μs, Unix domain socket延迟大概30us, 实际中, 延迟受系统和网络情况影响

    系统延迟在虚拟机中比物理机中要大很多

    虽然redis命令在微秒级别, 但是client因为命令的网络往返, 需要忍受这部分延迟

    高效的client会使用pipeline或者聚合命令

    guidelines:

    • redis server 最好使用物理机, 而不是虚拟机
    • 不要频繁连接释放, 使用长连接
    • 如果client和server在同一机器, 使用Unix domain sockets
    • 优先使用聚合命令(MSET/MGET), 而不是pipeline
    • 优先使用pipeline, 而不是频繁发送命令(多次网络往返)
    • 对不适合使用pipeline的命令, 可以考虑使用lua脚本

    redis server 命令处理是单线程, 但是redis内部还有有很多多线程, 用于处理类似bgsave, AOF等操作, 因此, redis server不适合在单核机器上运行

    redis 单线程的本质

    redis 使用一个线程处理clients的所有命令:

    • multiplexing 多路IO复用
    • 顺序执行
    • 非阻塞调用(类似nodejs)

    慢查询引起的延迟

    GET or SET or LPUSH 等命令执行时间是常数, 不过类似 SORT, LREM, SUNION等操作多个元素的命令执行时间是O(N)

    最佳时间: 对于不熟悉的命令, 一定要去查看文档, 搞清楚时间复杂度

    解决方案:

    • 减少多元素慢命令的使用
    • 特别地, 对于 KEYS命令只能用于线下调试, 生产环境可以使用 SCAN, SSCAN, HSCAN and ZSCAN等命令代替
    • 使用主从复制, 将慢的命令放到复制机器上执行

    Additionally, you can use your favorite per-process monitoring program (top, htop, prstat, etc …) to quickly check the CPU consumption of the main Redis process. If it is high while the traffic is not, it is usually a sign that slow commands are used

    使用SLOWLOG 诊断问题

    • SLOWLOG LEN 当前慢查询个数
    • SLOWLOG RESET 清空记录
    • CONFIG GET slowlog-max-len 获得最大存储量, 默认好像128
    • CONFIG GET slowlog-log-slower-than 获得慢查询阈值, 单位微秒, 默认10毫秒
    • SLOWLOG GET [number] 展示number条慢查询

      格式如下

      redis> SLOWLOG GET
      1) 1) (integer) 12                      # 唯一性(unique)的日志标识符
         2) (integer) 1324097834              # 被记录命令的执行时间点,以 UNIX 时间戳格式表示
         3) (integer) 16                      # 查询执行时间,以微秒为单位
         4) 1) "CONFIG"                       # 执行的命令,以数组的形式排列
            2) "GET"                          # 这里完整的命令是 CONFIG GET slowlog-log-slower-than
            3) "slowlog-log-slower-than"
      

    fork 引起的延迟

    生成RDB或者AOF会使redis 主线程fork后台线程, 这会造成一定延迟

    过期操作引起的延迟

    redis 数据过期有以下两种方式:

    1. 惰性过期: 操作指定key时, 检测过期时间, 如果已过期则删除
    2. 主动过期, 每100ms进行一次过期检测(每秒10次)

    主动过期算法:

    • 每次扫描ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP(默认20)个redis数据, 删除已过期数据
    • 如果有大于25%的数据过期, 则重复执行

    如果同一时刻, 有大量key过期, 主动过期算法发现大于25%的过期数据, 它将重复执行主动过期扫描, 直到过期比例小于25%, 这可能造成延迟

    这种算法是必要的, 用于避免大量过期数据占用内存, 通常来说也是无害的, 因为很少会有大量数据在同一时刻过期, 除非大量使用EXPIREAT 同一时间

    实例参看: 善待Redis里的数据

  • 相关阅读:
    Linkedin工程师是如何优化他们的Java代码的
    如何调试 Android 上 HTTP(S) 流量
    Facebook工程师是如何改进他们Android客户端的
    modified: xxx(modified content, untracked content)
    在Android工程中加入AIDL文件时,gen目录生成的文件报错-问题解决
    Ubuntu14.04LTS下使用eclipse搭建Cocos2d-x的Android环境
    Ubuntu Linux下安装Oracle JDK
    查看Android源码版本
    Ubuntu Linux下安装Oracle JDK
    Android Initializing a Build Environment
  • 原文地址:https://www.cnblogs.com/yaoyangding/p/15193388.html
Copyright © 2020-2023  润新知