Redis(开发与运维):28---客户端之(客户端相关配置、客户端统计片段(info clients、info stats))

一、客户端相关配置

①客户端的限制maxclients

  • Redis提供了maxclients参数来限制最大客户端连接数,一旦连接数超过 maxclients,新的连接将被拒绝
  • maxclients默认值是10000
  • 可以通过info clients来查询当前Redis的连接数:

Redis(开发与运维):28---客户端之(客户端相关配置、客户端统计片段(info clients、info stats))_第1张图片

  • 可以通过config set maxclients对最大客户端连接数进行动态设置:

Redis(开发与运维):28---客户端之(客户端相关配置、客户端统计片段(info clients、info stats))_第2张图片

  • 但是这个参数会受到操作系统设置的限制,在后面“开发运维的陷阱文章中还会介绍”

②客户端的限制timeout

  • 一般来说maxclients=10000在大部分场景下已经绝对够用,但是某些情况由于业务方使用不当(例如没有主动关闭连接)可能存在大量idle连接, 无论是从网络连接的成本还是超过maxclients的后果来说都不是什么好事, 因此Redis提供了timeout(单位为秒)参数来限制连接的最大空闲时间,一 旦客户端连接的idle时间超过了timeout,连接将会被关闭
  • timeout默认为0,也就是不会检测客户端的空闲

  • 该参数也可以动态设置。例如设置timeout为30秒:

Redis(开发与运维):28---客户端之(客户端相关配置、客户端统计片段(info clients、info stats))_第3张图片

演示案例

  • 下面继续使用Jedis进行模拟,整个代码和上面是一样的,只不过第2) 步骤休息了31秒:
String key = "hello";
// 1) 生成jedis,并执行get操作
Jedis jedis = new Jedis("127.0.0.1", 6379);
System.out.println(jedis.get(key));
// 2) 休息31秒
TimeUnit.SECONDS.sleep(31);
// 3) 执行get操作
System.out.println(jedis.get(key));
// 4) 休息5秒
TimeUnit.SECONDS.sleep(5);
// 5) 关闭jedis连接
jedis.close();
  • 执行上述代码可以发现在执行完第2)步之后,client list中已经没有了 Jedis的连接,也就是说timeout已经生效,将超过30秒空闲的连接关闭掉:

  • 同时可以看到,在Jedis代码中的第3)步抛出了异常,因为此时客户端 已经被关闭,所以抛出的异常是JedisConnectionException,并且提示 Unexpected end of stream:

  • 如果将Redis的loglevel设置成debug级别,可以看到如下日志,也就是客 户端被Redis关闭的日志:

  • Redis源码中redis.c文件中clientsCronHandleTimeout函数就是针对timeout 参数进行检验的,只不过在源码中timeout被赋值给了server.maxidletime:
int clientsCronHandleTimeout(redisClient *c) {
    // 当前时间
 time_t now = server.unixtime;
    // server.maxidletime就是参数timeout
    if (server.maxidletime &&
        // 很多客户端验证,这里就不占用篇幅,最重要的验证是下面空闲时间超过了maxidletime就会
        // 被关闭掉客户端
        (now - c->lastinteraction > server.maxidletime))
    {
        redisLog(REDIS_VERBOSE,"Closing idle client");
        // 关闭客户端
        freeClient(c);
    }
}
  • Redis的默认配置给出的timeout=0,在这种情况下客户端基本不会出现上面的异常,这是基于对客户端开发的一种保护。例如很多开发人员在使用JedisPool时不会对连接池对象做空闲检测和验证,如果设置了timeout>0,可 能就会出现上面的异常,对应用业务造成一定影响,但是如果Redis的客户 端使用不当或者客户端本身的一些问题,造成没有及时释放客户端连接,可能会造成大量的idle连接占据着很多连接资源,一旦超过maxclients;后果也是不堪设想。所在在实际开发和运维中,需要将timeout设置成大于0,例如 可以设置为300秒,同时在客户端使用上添加空闲检测和验证等等措施,例如JedisPool使用common-pool提供的三个属性:minEvictableIdleTimeMillis、 testWhileIdle、timeBetweenEvictionRunsMillis

③tcp-keepalive

  • 检测TCP连接活性的周期
  • 默认值为300

  • 如果需要设置,建议为60,那么Redis会每隔60秒对它创建的TCP连接进行活性检测,防止大量死连接占用系统资源

④tcp-backlog

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

  • 修改方法也非常简单,只需要执行如下命令
echo 511 > /proc/sys/net/core/somaxconn
  • 通常来讲这个参数不需要调整,但是这个参数会受到操作系统的影响。例如在Linux操作系统 中,如果/proc/sys/net/core/somaxconn小于tcp-backlog,那么在Redis启动时会 看到如下日志,并建议将/proc/sys/net/core/somaxconn设置更大

二、客户端统计片段

info clients

  • 例如下面就是一次info clients的执行结果:

Redis(开发与运维):28---客户端之(客户端相关配置、客户端统计片段(info clients、info stats))_第4张图片

Redis(开发与运维):28---客户端之(客户端相关配置、客户端统计片段(info clients、info stats))_第5张图片

  • 说明如下:
    • connected_clients:代表当前Redis节点的客户端连接数,需要重点监控,一旦超过maxclients,新的客户端连接将被拒绝
    • client_recent_max_output_buffer:当前所有输出缓冲区中队列对象个数的最大值
    • client_recent_max_input_buffer:当前所有输入缓冲区中占用的最大容量
    • blocked_clients:正在执行阻塞命令(例如blpop、brpop、 brpoplpush)的客户端个数

info stats

Redis(开发与运维):28---客户端之(客户端相关配置、客户端统计片段(info clients、info stats))_第6张图片

  • 参数说明:
    • total_connections_received:Redis自启动以来处理的客户端连接数总数
    • rejected_connections:Redis自启动以来拒绝的客户端连接数,需要重点监控

你可能感兴趣的:(Redis(开发与运维))