排查 Azure Managed Redis 错误:Max Number of Clients Reached

2026-06-12#Azure#Redis

最近应用在使用 Azure Managed Redis 时,遇到了错误 ERR max number of clients reached,导致应用无法连接到 Redis 实例。这个错误通常是由于 Redis 实例的客户端连接数达到了上限,无法接受新的连接请求。

错误信息 🔗

这个 Spring Boot 应用的错误日志如下:

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

排查过程 🔗

在 Azure Portal 中打开这个 Azure Managed Redis 实例的监控指标,查看 Connected Clients (Max) 的指标,发现大概为 15000 个客户端,即在上限附近。

首先想到连接到 Redis 实例,查看当前有哪些客户端连接。这个实例启用了 EntraID Authentication,可获取临时 Token,然后用 redis-cli 连接 Redis 实例:

REDIS_TOKEN=$(az account get-access-token --resource "https://redis.azure.com" --query accessToken --output tsv)
redis-cli -h $HOST -p $PORT --tls AUTH $TOKEN && redis-cli -h $HOST -p $PORT --tls

但是很不幸,由于客户端连接数已经达到了上限,无法连接到 Redis 实例。

那是否可以重启 Redis 实例来解决这个问题呢?很遗憾,Azure Managed Redis 不支持重启实例的操作,因此无法通过重启来解决这个问题。

最终的方法是重启所有客户端应用,来释放掉 Redis 实例上的客户端连接。经验证,在重启后 Redis 实例的客户端连接数开始逐渐上升。但这个上升是一个渐进的过程,在 Connected Clients 达到 15000 的上限之前,可以连接到 Redis 实例进行排查。可执行使用如下命令执行 CLIENT LIST 查询当前有哪些客户端连接,并将结果重定向到文件:

REDIS_TOKEN=$(az account get-access-token --resource "https://redis.azure.com" --query accessToken --output tsv)
redis-cli -h $HOST -p $PORT --tls AUTH $TOKEN && redis-cli -h $HOST -p $PORT --tls CLIENT LIST > client-lists.txt

查询结果的每一条记录如下所示:

id=xxxxxxxxxx0000 addr=[xxxx:xxxx:x:xxxx:xxxx:xxx:xxx:xx]:xxxxx laddr=[xxx:xxx:xxx::x]:10000 fd=14964 name= age=124 idle=124 flags=N db=0 sub=0 psub=0 ssub=0 multi=-1 watch=0 obl=0 events=r cmd=client|setinfo user=00000000-0000-0000-0000-000000000000 resp=2 lib-name=jedis lib-ver=5.1.3

其中 user 字段即是 UAI (User Assigned Identity)的 ID,可以根据这个 ID 来排查是哪个应用连接到了 Redis 实例。通过分析这些连接记录,发现有某个 user 的客户端连接数异常地多,达到了接近15000个。很显然,这个应用创建了大量连接,而没有及时关闭。它就是罪魁祸首。

那么应用为什么创建这么多客户端连接呢?该应用运行在 AKS 中,除了 StartupProbe 之外,还配置了 LivenessProbe 和 ReadinessProbe 。这 3 个探针配置的是同一个请求路径,并且在每次探测时都会创建一个新的 Redis 客户端连接来检查 Redis 实例的健康状况,并且没有关闭连接。这里至少有2个问题:首先,应该使用依赖注入的 redisTemplate 来复用 Redis 客户端连接,而不是每次探测都创建一个新的连接;其次,LivenessProbe 和 ReadinessProbe 的探测路径由于访问可能频繁(尤其在应用实例较多的时候),不适合用来检查 Redis 实例的健康状况,可以考虑使用 StartupProbe 来检查 Redis 实例的健康状况,而在 LivenessProbe 和 ReadinessProbe 中使用其他的探测路径来检查应用本身的健康状况。