客户端管理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
评论区