目 录CONTENT

文章目录

Redis运维与异常

FatFish1
2025-06-10 / 0 评论 / 0 点赞 / 1 阅读 / 0 字 / 正在检测是否收录...

客户端管理api

client list

client list命令能列出与Redis服务端相连的所有客户端连接信息

输出结果的每一行代表一个客户端的信息

其中各个属性的含义:

  • id、addr、fd、name:客户端标识,id是随redis服务端收到的连接自增的,重启后清零;fd是文件描述符,fd=-1是redis内部的伪客户端

  • qbuf、qbuf-free:输入缓冲区总容量和剩余容量

  • obl、oll、omem:输出缓冲区

  • age、idle:客户端已经连接时间和最近一次空闲时间

  • flag:客户端类型

其他

其他命令例如client pause、client kill、client getName/setName、monitor

输入缓冲区

Redis为每个客户端分配了输入缓冲区,它的作用是将客户端发送的命 令临时保存,同时Redis从会输入缓冲区拉取命令并执行,输入缓冲区为客 户端发送命令到Redis执行命令提供了缓冲功能

Redis中单个客户端输入缓冲区大小是1G,是硬编码在代码里面的,如果一个客户端一次性投放了大量的输入,超过了输入缓冲区,客户端将会关闭

总的输入缓冲区没有限制,会直接占用总内存,如果总内存是4G,已经存储了2G,这时输入缓冲区用到了3G,就会触发键的逐出、OOM等问题

但是总的来说,输入缓冲区还是不太容易出问题

输出缓冲区

Redis为每个客户端分配了输出缓冲区,它的作用是保存命令执行的结 果返回给客户端,为Redis和客户端交互返回结果提供缓冲

由于是缓存查询结果的,这个就非常容易溢出了,例如客户执行keys命令,查所有的键

因此输出缓冲区的配置和逻辑更加全面,可以通过参数client-output-buffer-limit来进行设置

和输入缓冲区相同的是,输出缓冲区也不会受到maxmemory的限制,如果使用不当同样会造成maxmemory用满产生的数据丢失、键值淘汰、OOM等情况

客户端相关配置

  • timeout:检测客户端空闲连接的超时时间,一旦idle时间达到了 timeout,客户端将会被关闭,如果设置为0就不进行检测

  • maxclients:客户端最大连接数

配置timeout和maxclient是为了辅助服务端剔除闲置/多余的客户端,因为有时客户端使用连接池的时候往往忘记做空闲回收和校验,而不及时释放的客户端则有可能产生问题

  • tcp-keepalive:检测TCP连接活性的周期,默认值为0,也就是不进行 检测,如果需要设置,建议为60,那么Redis会每隔60秒对它创建的TCP连 接进行活性检测,防止大量死连接占用系统资源

  • tcp-backlog:TCP三次握手后,会将接受的连接放入队列中,tcp-backlog就是队列的大小,它在Redis中的默认值是511

客户端常见异常

无法从连接池获取连接

redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
…
Caused by: java.util.NoSuchElementException: Timeout waiting for idle object
at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.
java:449)

这个问题一般都是客户端使用连接池不当造成的,例如:

  • 没有归还

  • 设置了blockWhenExhausted=false,即没有资源时立即返回不等待一会

客户端读写超时

redis.clients.jedis.exceptions.JedisConnectionException:
java.net.SocketTimeoutException: Read timed out

读写超时就是发过去的命令长时间没有收到回应,读写超时可能原因有:

  • 读写超时时间设置过短

  • 命令执行太慢

  • 客户端与服务端网络异常

  • redis发生阻塞

客户端连接超时

redis.clients.jedis.exceptions.JedisConnectionException:
java.net.SocketTimeoutException: connect timed out

连接超时的原因包括:

  • 连接超时设置得过短,可以设置jedis.getClient().setConnectionTimeout(time);

  • Redis发生阻塞,造成tcp-backlog已满,造成新的连接失败

  • 客户端与服务端网络不正常

客户端缓冲区异常

redis.clients.jedis.exceptions.JedisConnectionException: Unexpected end of stream

造成该问题的原因可能有:

  • 输出缓冲区大小设置不合理

  • 长时间闲置连接被服务端主动断开

  • 不正常并发读写:Jedis对象同时被多个线程并发操作,可能会出现 上述异常

lua脚本执行异常

redis.clients.jedis.exceptions.JedisDataException: BUSY Redis is busy running a
script. You can only call SCRIPT KILL or SHUTDOWN NOSAVE.

如果Redis当前正在执行Lua脚本,并且超过了lua-time-limit,此时Jedis 306 调用Redis时,会收到下面的异常

客户端连接数过大

redis.clients.jedis.exceptions.JedisDataException: ERR max number of clients reached

超过内存

redis.clients.jedis.exceptions.JedisDataException: OOM command not allowed when
used memory > 'maxmemory'.

redis正在加载持久化文件

redis.clients.jedis.exceptions.JedisDataException: LOADING Redis is loading the
dataset in memory

0

评论区