序:文由

  • 因今日排查问题,发现微服务因 ERR max number of clients reached (已达到客户端的最大数量) redis异常,而导致服务在健康检测时未通过,进而导致高频宕机。

概述:Redis 连接与会话管理

Redis 连接会话的原理

  • redis通过监听一个TCP端口或socket的方式接收来自客户端的连接,当与客户端建立连接后,redis内部会进行如下操作:

(1)客户端socket会被设置为非阻塞模式,因为redis在网络时间处理上采用的是非阻塞多路复用模型;

(2)为这个socket设置TCP_NODELAY属性,禁用Nagle算法;

(3)创建一个可读的文件事件用于监听这个客户端socket的数据发送。

常用功能与指令

连接操作类

查看连接总数 : info clients

> info clients
# Clients
connected_clients:95
client_recent_max_input_buffer:2
client_recent_max_output_buffer:0
blocked_clients:0
rx_controlled_clients:0
total_real_rx_controlled:0
total_tx_controlled:0
total_rx_controlled:824214
proxy_header_error:0

查看连接详情列表 : client list

  • client list : 命令用于返回所有连接到服务器的客户端信息和统计数据。

http://www.redis.cn/commands/client-list.html

client list

  • 返回值

bulk-string-reply: 一个独特的字符串。具体格式:

每个已连接客户端对应一行(以 LF 分割)

每行字符串由一系列 属性=值(property=value) 形式的域组成,每个域之间以空格分开。

各字段的含义::

id: 唯一的64位的客户端ID(Redis 2.8.12加入)。
addr: 客户端的地址和端口
fd: 套接字所使用的文件描述符
age: 以秒计算的已连接时长
idle: 以秒计算的空闲时长
flags: 客户端 flag
db: 该客户端正在使用的数据库 ID
sub: 已订阅频道的数量
psub: 已订阅模式的数量
multi: 在事务中被执行的命令数量
qbuf: 查询缓冲区的长度(字节为单位, 0 表示没有分配查询缓冲区)
qbuf-free: 查询缓冲区剩余空间的长度(字节为单位, 0 表示没有剩余空间)
obl: 输出缓冲区的长度(字节为单位, 0 表示没有分配输出缓冲区)
oll: 输出列表包含的对象数量(当输出缓冲区没有剩余空间时,命令回复会以字符串对象的形式被入队到这个队列里)
omem: 输出缓冲区和输出列表占用的内存总量
events: 文件描述符事件
cmd: 最近一次执行的命令

设置当前连接点redis的名称 : CLIENT SETNAME

CLIENT SETNAME

查看当前连接的名称 : CLIENT GETNAME

CLIENT GETNAME

杀死指定连接 : CLIENT KILL {ip}:{port}

CLIENT KILL {ip}:{port}

连接配置类

查看/设置连接的默认超时自动断连时间(空闲超时时间) : config [get|set] timeout [{second}]

  • 查看连接的默认超时自动断连时间(空闲超时时间)

默认值 = 0

> config get timeout
0
  • 设置连接的默认超时自动断连时间(空闲超时时间)

单位:秒钟

config set timeout 600

查询/设置允许的最大连接数 : config get maxclients

  • 查询允许的最大连接数
config get maxclients
  • 设置允许的最大连接数

方法1:在2.6之后版本,可以修改最大连接数配置,默认10000,可以在redis.conf配置文件中修改

...
# maxclients 10000
...

方法2: config set maxclients num 可以设置redis允许的最大连接数

127.0.0.1:6379> CONFIG set maxclients 10
OK
127.0.0.1:6379>

方法3:启动redis.service服务时加参数--maxclients 100000来设置最大连接数限制

redis-server --maxclients 100000 -f /etc/redis.conf

FAQ for Redis 连接与会话管理

Q: 连接过多,乃至报ERR max number of clients reached(Redis客户端连接数已达到最大限制)?

  • 问题分析
  • redis maxclients

redis maxclients 是redis server的重要配置,它决定了客户端的最大连接数量最大客户端连接数量

由于redis不区分连接是客户端连接、还是内部打开文件、或者和slave连接等。所以,maxclients最小存在32个连接数,如果超过了设置的maxclients,redis会给新的连接发送"max number of clients reached",并关闭连接

  • 硬编码限制

在Redis 2.4中,可以同时处理的最大客户端数量存在硬编码限制

在Redis 2.6中,此限制是动态的:默认情况下,它设置为10000个客户端,除非Redis.conf中的maxclients指令另有说明。

  • 原因分析

绝大部分原因:由于客户端很多空闲连接都没有被及时释放掉,从而导致connected_clients非常高

其他可能:maxclients设置的太少了

还有可能:软硬件存在限制

  • 解决方法
  • 1 客户端 - 设置超时时间
JedisPoolConfig jedisPoolConfig = initPoolConfig();
jedisPool = new JedisPool(jedisPoolConfig, "*.*.*.*", 6379); =========> 修改为: JedisPoolConfig jedisPoolConfig = initPoolConfig();
jedisPool = new JedisPool(jedisPoolConfig, "*.*.*.*", 6379, 2*1000); //timeout = 2*1000 = connectionTimeout = soTimeout

public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, int port, final int connectionTimeout, final int soTimeout, final String password, final int database, final String clientName)

  • 2 客户端 - 回收连接资源
	Jedis jedis = JedisUtils.getJedis();
try {
//Todo
} catch (Exception e){
throw new RuntimeException(e.getMessage(), e);
JedisUtils.returnBrokenResource(jedis); //释放连接
} finally {
JedisUtils.returnResource(jedis); //释放连接
} ---- /**
* 回收Jedis对象资源
*
* @param jedis
*/
public synchronized void returnResource(Jedis jedis) {
if (jedis != null) {
jedisPool.returnResource(jedis);
}
} /**
* Jedis对象出异常的时候,回收Jedis对象资源
*
* @param jedis
*/
public synchronized void returnBrokenResource(Jedis jedis) {
if (jedis != null) {
jedisPool.returnBrokenResource(jedis);
} }

Jedis 2.6.2 以后,由于重写了jedis.close(),实现自动关闭,2.6.3以后正式使用,详见Deprecates JedisPool returnResource and returnBrokenResource ,这样可以代码使用JDK7中新增的try-with-resource语法糖,这样代码会简洁很多如下:

    try (Jedis jedis = JedisUtils.getJedis()) {
//Todo
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
  • 3 通过ip排查对应的service服务,查看是否还可以进行优化。
  • 4 查看空闲超时时间: config get timeout

0 : 默认不开启

  • 5 设置空闲超时时间 : config set timeout {second}

建议为0,尤其是有用分布式锁的情况下、具体看业务场景

如:配置默认空闲超时时间为60s : config set timeout 60

  • 6 config rewrit : 保存

可在 redis.conf 配置文件中添加重启生效。

X 参考文献

(error) ERR max number of clients reached

"我仔细审查了一下前同事写的Redis工具类,发现连接用完,全都没有归还连接"

    public <T> T get(String key, String modulePrefix, Class<T> t) {
checkJedisPool();
key = generateKey(key, modulePrefix);
try (Jedis jedis = jedisPool.getResource()) {
String valueStr = jedis.get(key);
return parse(valueStr, t);
}
}

[Redis] Redis (7) 连接与会话管理的更多相关文章

  1. 3.用Redis Desktop Manager连接Redis

    Redis Desktop Manager是Redis图形化管理工具,方便管理人员更方便直观地管理Redis数据. 然而在使用Redis Desktop Manager之前,有几个要素需要注意: 一. ...

  2. 用Redis Desktop Manager连接Redis

    Redis Desktop Manager是Redis图形化管理工具,方便管理人员更方便直观地管理Redis数据. 然而在使用Redis Desktop Manager之前,有几个要素需要注意: 一. ...

  3. Redis进阶实践之六Redis Desktop Manager连接Windows和Linux系统上的Redis服务

    一.引言 今天本来没有打算写这篇文章,当初我感觉使用这个工具应该很简单,下载的过程也不复杂,也没有打算记录下来.但是在使用的过程中还是出现了一些问题,为了给第一次使用Redis Desktop Man ...

  4. Redis进阶实践之六Redis Desktop Manager连接Windows和Linux系统上的Redis服务(转载6)

    Redis进阶实践之六Redis Desktop Manager连接Windows和Linux系统上的Redis服务 一.引言 今天本来没有打算写这篇文章,但是,今天测试Redis的时候发现了两个问题 ...

  5. Redis数据备份、安全、管理服务器笔记

    Redis 数据备份与恢复 Redis SAVE 命令用于创建当前数据库的备份. 实例 redis > SAVE OK 恢复数据 如果需要恢复数据,只需将备份文件 (dump.rdb) 移动到 ...

  6. 用Redis Desktop Manager连接Redis(CentOS)

    Redis Desktop Manager是Redis图形化管理工具,方便管理人员更方便直观地管理Redis数据. 然而在使用Redis Desktop Manager之前,有几个要素需要注意: 一. ...

  7. 《Linux 学习》01---redis安装, 并使用Redis Desktop Manager 连接

    一.环境简介: linux 系统:centos 7.X 二.安装大纲: 1.下载安装包 2.安装 3.统一管理redis 配置文件 4.编辑redis配置文件,设置常用的功能 5.(1)命令启动,连接 ...

  8. 关于python语言使用redis时,连接是否需要关闭的问题

    python操作完redis,需要关闭连接的吧,怎么关闭呢 1人赞 回复 君惜丶: redis-server会关闭空闲超时的连接redis.conf中可以设置超时时间:timeout 300 2017 ...

  9. 3.用Redis Desktop Manager连接Redis(CentOS)

    Redis Desktop Manager是Redis图形化管理工具,方便管理人员更方便直观地管理Redis数据. 然而在使用Redis Desktop Manager之前,有几个要素需要注意: 一. ...

  10. Redis Desktop Manager连接Redis 遇到的一系列问题

    最近在做一个土地项目的后台,主要是一个信息采集调查系统,使用的框架是: * 核心框架:Spring Framework 4.2 * 日志管理:SLF4J 1.7.Log4j 1.2 * 视图框架:Sp ...

随机推荐

  1. 震撼揭秘:LLM幻觉如何颠覆你的认知!

    LLM幻觉 把幻觉理解为训练流水线中的一种涌现认知效应 Prashal Ruchiranga Robina Weermeijer 在 Unsplash 上的照片 介绍 在一个名为<深入剖析像Ch ...

  2. 「一」vim简介

    什么是vim? 一个历史悠久的文本编辑器 vim采用了模式编辑的理念,提供了多种模式 底線命令模式 插入模式 命令模式 交互式教程 $: vimtutor :自带教程 $: vim -h : vim命 ...

  3. 使用form-create时修改表单数据

    FormCreate 是一个可以通过 JSON 生成具有动态渲染.数据收集.验证和提交功能的表单生成组件.支持5个UI框架,并且支持生成任何 Vue 组件.内置20种常用表单组件和自定义组件,再复杂的 ...

  4. netcore后台服务慎用BackgroundService

    在 .NET Core 开发中,BackgroundService 是一个非常方便的后台任务运行方式,但它并不适用于所有场景. BackgroundService 一时爽,并发火葬场. Backgro ...

  5. Unable to Connect: sPort: 0 C# ServiceStack.Redis 访问 redis

    需求:  对数据库中的不断抓取的文章进行缓存,因此需要定时访问数据,写入缓存中 在捕获到的异常日志发现错误:Unable to Connect: sPort: 0 使用的访问方式是线程池的方式:Poo ...

  6. C#弃元表达式的用法

    原文地址:http://cshelloworld.com/home/detail/1803462343674433536 弃元符号是什么 弃元符号在C#中只是一个下划线 _,当程序员不想关注某些变量的 ...

  7. 一款基于.NET开源、强大的网络管理和网络问题排查工具!

    前言 今天大姚给大家分享一款基于.NET开源.免费.功能强大的网络管理和网络问题排查工具:NETworkManager. 项目介绍 NETworkManager 是一个基于.NET开源(GPL-3.0 ...

  8. VirtualBox磁盘扩容

    前言 虚拟机开始时设置的磁盘空间比较小,后面使用就不够了. # 查询磁盘使用情况 df -h 虚拟硬盘扩容 关闭正在运行的虚拟机 选中工具栏 选择虚拟硬盘,并选中需要扩容的磁盘 拖动进度条,设置想要扩 ...

  9. SSH登录:WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!

    错误信息: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICAT ...

  10. 文件转十六进制出现转义字符直接通过ASCII码逐字符展开的问题与修复

    近日工作中遇到某品牌电子签章系统生成的PDF文件若直接使用十六进制查看器打开,会出现转义字符被直接以ASCII编码转换为16进制字符串的问题,导致提取的文件无法匹配ASN.1格式,无法进一步对签章有效 ...