• Redis客户端常见异常


    客户端读写超时

    • 读写超时时间设置得过短
    • 命令本身就比较慢
    • 客户端与服务端网络不正常
    • redis自身发生堵塞

    客户端连接超时

    • 连接超时时间设置过短
    • redis发生阻塞,造成tcp-backlog 已满,造成新的连接失败
    • 客户端与服务端网络不正常

    客户端缓冲区异常

    • 输出缓冲区满,例如将普通客户端的输出缓冲区设置为1M 1M 60;
     config set client-output-buffer-limit "normal 1048576  1048576  60  slave  268435456  67108864  60  pubsub 33554432  8388608 60"
    
    • 1

    如果使用get 命令获取一个bigkey(例如3M) ,就会出现异常,因为默认位1M(1048576字节)

    • 长时间闲置连接被服务端主动断开(timeout参数设置,当闲置时间大于这个值,就会被服务端主动断开)
    • 不正常并发读写

    Lua脚本正在执行

    如果redis 正在执行lua脚本,并且超过了lua-time-limit ,此时其它客户端调用redis 时,会收到redis busy running a script;

    可以使用脚本杀死,script kill 或者 shutdown save

    需要注意的是script kill 该命令在脚本执行过写操作是不会生效的,所以要么等待脚本执行结束或者是shutdown save 停掉redis服务,虽然redis脚本好用,但是需要谨慎使用。

    redis正在加载持久化文件

    如果redis正在加载持久化文件时,客户端调用redis ,就会报loading redis is loading the dataset in memory错误

    redis使用的内存超过maxmemory配置

    客户端在执行写操作时,如果redis 的使用内存大于maxmemory 的设置,会收到 oom used memory > maxmemory 错误;
    此时应该调整maxmemory 的值并造成内存增长的原因。当然这也是因为redis的淘汰策略使用的是默认值:maxmemory-policy:noeviction
    noeviction(默认策略):对于写请求不再提供服务,直接返回错误
    临时解决方案:config set maxmemory-policy allkeys-lru 设置

    客户端连接数过大

    如果客户端连接数超过了maxlients ,新的客户端连接就会出现报错:err max number of clients reached

    redis 默认值为10000 ,正常都是够用的,出现这种情况属于异常情况,原因很多,需要后续排查。

    临时解决方案就是: 下线一些,应用程序中不重要的部分使用,使得连接数降下来 或者调整一下maxclients 值进行问题修复。但是还是得找出根源,不然过段时间又会出现问题。

    客户端案例分析
    例如:redis 内存陡增
    客户端接收到 OOM 异常

    分析如下:
    第一:首先看是否存在主从复制出现问题,使用dbsize 查看key的对比大小
    第二:其它原因导致主节点内存使用过大,排查是否由客户端缓冲区造成主节点内存陡增,使用 info clients 命令查询信息如下:

    127.0.0.1:6379> info clients
    # Clients
    connected_clients:1   
    cluster_connections:0 
    maxclients:10000 
    client_recent_max_input_buffer:16896
    client_recent_max_output_buffer:233246000000
    blocked_clients:0
    tracking_clients:0
    clients_in_timeout_table:0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    很明显输出缓存区不太正常,client_recent_max_output_buffer这个值很大,这个时候需要通过client list 命令找到omem 不正常的连接,一般来说omem 为0 (因为速度足够快),执行如下代码可找出omem非零的客户端连接:

    ➜  ~ redis-cli client list | grep -v "omem=0"
    
    
    找到如下一条命令:
    id=5 addr=127.xxx.xx.1:55606 laddr=127.xx.0.1:6379 fd=8 name= age=0 idle=0 flags=N db=0 sub=0 psub=0 ssub=0 multi=-1 qbuf=26 qbuf-free=16864 argv-mem=10 multi-mem=0 rbs=16384 rbp=16384 obl=0 oll=1689600 omem=1682131200 tot-mem=34042 events=r cmd=monitor
    
    • 1
    • 2
    • 3
    • 4
    • 5

    很明显是因为客户端在执行monitor 命令造成的

    解决方案:

    可以使用client kill 命令杀死这个连接

    ➜  ~ client kill 127.xxx.xx.1:55606
    
    • 1

    如何避免此类问题再次发生呢:

    使用rename-command 命令重置monitor命令
    限制输出缓存区的大小

  • 相关阅读:
    猿创征文|瑞吉外卖——管理端_过滤器
    MySQL外键
    生鲜蔬果社区团购商城小程序的作用是什么
    Attention Is All You Need:Transformer论文阅读笔记
    计算机网络:局域网的基本概念和体系结构
    [附源码]java毕业设计旅游管理系统
    RPC远程调用框架Dubbo
    软件无线电系列——模拟无线电、数字无线电、软件无线电
    广东海颐开发笔试编程题回顾
    优维邀您共赴2022GOPS全球运维大会,探索精益IT运维方式
  • 原文地址:https://blog.csdn.net/weixin_40172337/article/details/128162084