• Redis阻塞原因


    1. 自身因素

    • api或数据结构使用不合理:例如对一个上万元素的hash结构执行hgetall操作,数据量造成堵塞。 
    • 慢查询
    • 大对象

        a. 数据库清零过后执行redis-cli --bigkeys命令的执行结果,系统没有查询到大的对象

    127.0.0.1:6379> flushall
    OK
    127.0.0.1:6379> 
    [root@localhost etc]# redis-cli --bigkeys
    
    # Scanning the entire keyspace to find biggest keys as well as
    # average sizes per key type.  You can use -i 0.1 to sleep 0.1 sec
    # per 100 SCAN commands (not usually needed).
    
    
    -------- summary -------
    
    Sampled 0 keys in the keyspace!
    Total key length in bytes is 0 (avg len 0.00)
    
    
    0 strings with 0 bytes (00.00% of keys, avg size 0.00)
    0 lists with 0 items (00.00% of keys, avg size 0.00)
    0 sets with 0 members (00.00% of keys, avg size 0.00)
    0 hashs with 0 fields (00.00% of keys, avg size 0.00)
    0 zsets with 0 members (00.00% of keys, avg size 0.00)
    [root@localhost etc]# 
    

        写入数据,执行大对象查询命令,发现String类型name为当前最大对象,确定了大对象,这样我们可以对它进行调整或缩减,分成多个小对象

    [root@localhost etc]# redis-cli
    127.0.0.1:6379> set name itxds
    OK
    127.0.0.1:6379> exit
    [root@localhost etc]# redis-cli --bigkeys
    
    # Scanning the entire keyspace to find biggest keys as well as
    # average sizes per key type.  You can use -i 0.1 to sleep 0.1 sec
    # per 100 SCAN commands (not usually needed).
    
    [00.00%] Biggest string found so far 'name' with 5 bytes
    
    -------- summary -------
    
    Sampled 1 keys in the keyspace!
    Total key length in bytes is 4 (avg len 4.00)
    
    Biggest string found 'name' has 5 bytes
    
    1 strings with 5 bytes (100.00% of keys, avg size 5.00)
    0 lists with 0 items (00.00% of keys, avg size 0.00)
    0 sets with 0 members (00.00% of keys, avg size 0.00)
    0 hashs with 0 fields (00.00% of keys, avg size 0.00)
    0 zsets with 0 members (00.00% of keys, avg size 0.00)
    

      b.生产环境查看key对应value序列化后的长度

        生产环境执行debug object key 查看key对应value序列化后的长度,或strlen key查看key的字节数

      c.info commandstats 命令分析命令不合理的开销时间,返回最近执行命令的调用次数,耗时信息

    CPU饱和:redis单线程只能用一个CPU,饱和将无法处理更多命令 可以执行命令redis-cli -h{ip} -p{port} --stat 获取当前redis使用情况

    [root@localhost etc]# redis-cli --stat
    ------- data ------ --------------------- load -------------------- - child -
    keys       mem      clients blocked requests            connections          
    1          808.23K  1       0       140 (+0)            10          
    1          808.23K  1       0       141 (+1)            10          
    1          808.23K  1       0       142 (+1)            10          
    1          808.23K  1       0       143 (+1)            10          
    1          808.23K  1       0       144 (+1)            10   

     

    2.持久化造成阻塞

          a.fork阻塞:fork操作做法神挂在RDB和AOF重写,redis主线程调用fork操作产生共享内存的子进程,柚子进程完成持久化操作,如果fork操作本身耗时过长,将导致主进程阻塞,可以执行info stats命令获取到latest_fork_usec指标,表示最近一次fork操作的耗时,若操作1s则需优化。

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

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

      亦可查看info persistence统计中的aof_delayed_fsync指标,每次发生aof刷盘阻塞主线程时会累加。

      c.HugePage写操作阻塞(求大佬指教): 子进程在执行重写期间利用Linux写时复制技术降低内存开销,因此只有写操作时Redis才复制要修改的内存页,对于开启Transparent HugePages的操作系统,每次写命令引起的复制内存页单位由4K变为2MB,放大了512倍,会拖慢写操作的执行时间,导致大量写操作慢查询。

    3.外因素

    A.CPU竞争

      a.进程竞争:当redis与其他cpu密集型服务部署在一起时可能发生

      b.绑定cpu:由于redis单线程架构,为充分利用多核cpu,一台机器部署多个redis并将redis进程绑定到cpu(可降低cpu上下文切换开销),当redis父进程fork操作创建子进程进行rdb/aof重写(很耗cpu)  时,父子进程共享同一cpu,将影响redis的稳定性

    B.内存交换:指操作系统把redis使用的部分内存换出到硬盘,导致交换后redis性能急剧下降(内存与硬盘处理速度不在一个数量级),可如下查看内存交换信息获取redis进程号→cat /proc/进程号/smaps | grep Swap

    C.网络问题:

      1)连接拒绝:

        a).网络闪段:网络割接或者带宽耗尽

        b).连接拒绝:超过客户端最大连接数

        c).连接溢出:指操作系统或redis客户端在连接时的问题,2种原因:

          原因1:进程限制 操作系统会对进程使用的资源做限制,其中之一便是对可打开最大文件数进行控制,ulimit –n可查看,超过则发送too many open files错误

          原因2:backlog队列溢出 系统对于特定端口的tcp连接使用backlog队列保存,redis默认长度为511,通过tcp-backlog参数设置,高并发场景下可增大该值,但必须大于操作系统允许值才生效,系统默认backlog为128,使用echo511>/proc/sys/net/core/somaxconn命令进行修改,可通过netstat -s命令获取因队列溢出造成的连接拒绝统计

      2)网络延迟: 可使用redis提供的测试工具进行测试,在redis-cli -h {ip} -p {port}命令后加入参数进行测试:

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

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

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

      3)网卡软中断(求大佬指教):

      网卡软中断是指由于单个网卡队列只能使用一个CPU,高并发下网卡数据交互都集中在同一个CPU,导致无法充分利用多核CPU的情况,网卡软中断瓶颈一般出现在网络高流量吞吐的场景

    摘自大佬:https://www.cnblogs.com/linguoguo/p/12046548.html

  • 相关阅读:
    [心得]如何快速利用SqlMap做安全檢測
    [心得]群裡提問的流水序號產生方式
    STL中使用reverse_iterator时,如何正确使用erase函数
    西山居面试之旅
    LAMP兄弟连 视频教程集
    [译]理解Windows消息循环
    C++设计模式 -- 解析和实现
    winsock 收发广播包
    SqlServer sysobjects_table
    查询反模式
  • 原文地址:https://www.cnblogs.com/xiangdongsheng/p/13557288.html
Copyright © 2020-2023  润新知