redis学习笔记4-客户端管理

1.客户端管理

1.1 client list指令

redis学习笔记4-客户端管理

    id:客户端连接标识

    addr:客户端IP和端口

    fd:如果为-1表示是redis内部的伪装客户端

    name:客户端名字

    1.1.1输入缓冲区:qbuf、qbuf-free

        qbuf:输入缓冲区总容量

        qbuf-free:输入缓冲区剩余容量

        注意:

            某个客户端的输入缓冲区超过1G,客户端将会被关闭

            输入缓冲区不受redis的maxmemory参数的控制,如果所有客户端输入缓冲区之和加上redis缓存数据大于maxmemory,则可能会产生数据丢失、键值淘汰、OOM等情况

        可能出问题的原因:

            redis的处理速度跟不上输入缓冲区的增长速度,即并发太大

            客户端提交的数据包含大量bigkey,造成输入缓冲区过大

            redis发生了阻塞,短期内不能处理命令,需要进行慢查询分析

        解决方案:

            定期执行client list指令,收集和分析输入缓冲区数据,找到可能出问题的客户端

            通过修改连接数和每个客户端连接的输入输出缓冲区大小

        总结:在开发中要减少bigkey、减少redis阻塞指令、合理的监控报警

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

        obl:固定缓冲区长度

        oll:动态缓冲区列表的长度

        omem:输出缓冲区使用的字节数

        注意:

            输出缓冲区可以通过client-output-buffer-limit按照客户端的不同进行配置,客户端分为普通客户端、发布订阅客户端、slave客户端。

            client-output-buffer-limit <class> <hard limit> <soft-limit> <soft-seconds>

            class:客户端类型

            hard limit:如果输出缓冲区大于这个值,客户端将被关闭

            oft-limit soft-seconds:客户端输出缓冲区超过oft-limit并且持续了soft-seconds秒后客户端将被关闭

            如下为redis默认配置:

                client-output-buffer-limit normal 0 0 0 //表示不限制

                client-output-buffer-limit slave 256mb 64mb 60

                client-output-buffer-limit pubsub 32mb 8mb 60

        预防方案:

            进行监控,设置阈值,超过阈值及时处理

            限制普通客户端的输出缓冲区

            根据并发情况,适当增大slave的输出缓冲区

            限制容易让输出缓冲区增大的命令,如在高并发下的monitor命令

            及时监控内存,如果出现内存抖动频繁,可能是输出缓冲区过大

    1.1.3 客户端的存活状态:age idle

        age:客户端连接上redis到现在一共经历了多少秒

        idle:客户端最后一次提交指令到现在空闲了多少秒

        注意:

            redis默认的最大空闲时间参数为timeout=0,表示连接上来的客户端不管空闲多久都不会被断开,如果设置大于0,则在时间到了后会断开客户端的连接。

        解决方案:

            redis设置timeout大于0,同时在客户端如jedis中添加空闲检测和连接是否断开的验证措施

        1.1.4 客户端类型:flag

redis学习笔记4-客户端管理

    1.2 client kill 指令

    如client kill 127.0.0.1:52343,手动杀掉某客户端。

    1.3 monitor指令

    用于监控redis正在执行的指令,如果redis并发量过大,则可能导致monitor客户端的输出缓冲区暴涨,进而影响redis服务。

    1.4 其他配置

    timeout配置:检测客户端空闲连接超时时间

    maxclients配置:客户端最大连接数

    tcp-keepalive配置:检测TCP连接活性的周期,建议设置为60,则redis每60秒就会对它创建的TCP连接进行活性检测,防止大量死连接占用系统资源。

    1.5 其他指令

        1.5.1 info clients

            connected_clients:代表当前Redis节点的客户端连接数,需要重点监控,一旦超过maxclients,新的客户端连接将被拒绝。

            client_longest_output_list:当前所有输出缓冲区中队列对象个数的最大值。

            client_biggest_input_buf:当前所有输入缓冲区中占用的最大容量。

            blocked_clients:正在执行阻塞命令(例如blpop、brpop、brpoplpush)的客户端个数。

        1.5.2 info stats

            ·total_connections_received:Redis自启动以来处理的客户端连接数总数。

            ·rejected_connections:Redis自启动以来拒绝的客户端连接数,需要重点监控。

2. 客户端常见异常

    2.1 无法从连接池获取连接

        Could not get a resoure from the pool

        客户端连接池设置过小,出现供不应求

        客户端没有正确使用连接池,比如没有进行释放

        客户端存在慢查询,这些慢查询持有的jedis对象归还速度慢,造成连接池满了

        redis服务端由于一些原因造成了客户端命令执行过程的阻塞

    2.2 客户端读写超时

        java.net.SocketTimeoutException: Read timed out

        读写超时时间设置过短

        命令本身就是慢查询

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

        redis发生阻塞

    2.3 客户端连接超时

        java.net.SocketTimeoutException: connect timed out

        连接超时时间设置过短

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

        网络问题

    2.4 客户端缓冲区异常

         Unexpected end of stre

        输出缓冲区满,如输出缓冲区设置为1m1m60,那么get一个2M的bigkey,就会出现这个异常

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

    2.5 redis正在加载持久化文件

        LOADING Redis is loading the dataset in memory

        jedis调用redis时,如果redis正在加载持久化文件时。

    2.6 redis使用的内存超过maxmemory

         OOM command not allowed when used memory > 'maxmemory'

    2.7 客户端连接数过大,超过了maxclients

        ERR max number of clients reached

        这个问题可能会比较棘手,因为此时无法执行Redis命令进行问题修复,一般来说可以从两个方面进行着手解决:

        客户端下线部分应用,在通过查找程序bug或调整maxclients

        如果是高可用或集群,服务端考虑将当前redis做故障转移

3. 故障案例

    3.1 redis内存陡增

    表现:redis主节点内存陡增,几乎用满maxmemory,而从节点很正常,客户端几乎都会产生OOM异常

    原因:

        需要查询主从节点的键数,如执行dbsize,看是否是主从复制出现问题

        是否是输入输出缓冲区造成主节点内存陡增,执行info clients指令

    解决方法:

        执行client kill指令杀掉输出缓冲区大的连接

        禁止开发层面使用如monitor命令,运维层面可以适当使用

        限制输出缓冲区的大小

        使用专业的redis运维工具,如cachecloud

    3.2 客户端周期性的超时

     表现:客户端周期性的出现大量超时,而服务端没有明显异常,只是有一些慢查询

    定位问题:慢查询和周期性超时时间是否吻合,程序是否定期执行慢查询

    解决方案:

        运维层面,监控慢查询,一旦超过阈值,就发出警报

        开发层面,控制批量查询的个数、时间复杂度高的指令

        使用专业的运维工具,如cachecloud

总结:

    因为redis是单线程架构模式,因此需要特别注意慢查询和时间复杂度高的指令,这会影响整个redis的并发,可能造成多种问题。