GeminiDB Redis连接检测机制和客户端重连重试建议
GeminiDB Redis连接检测机制
在网络状况良好且客户端连接正常的前提下,GeminiDB Redis不会主动断开用户的连接。和开源Redis连接机制相同,服务端启用了 TCP Keepalive 机制,可以检测并识别由于网络中断、客户端崩溃或NAT超时等原因导致的异常连接,并及时清理这些无效连接,以防止服务端的连接资源被耗尽,从而保障服务的稳定性与可用性。
参数解释
参数 |
说明 |
---|---|
ClientTimeout |
|
tcp-keepalive |
表示GeminiDB向空闲连接发送TCP Keepalive探测包的频率,默认为120s。 |
TCP_KEEPINTVL |
表示探测包发送的时间间隔(秒),默认为40s。 |
TCP_KEEPCNT |
表示发送多少次探测包,默认为3次。 |
检测机制
1. 当连接空闲时间超过tcp-keepalive设置的时间后,GeminiDB会开始发送Keepalive探测包,以确认连接是否仍然有效。
2. 如果对方没有响应,GeminiDB会每隔TCP_KEEPINTVL秒重试一次探测。
3. 如果连续TCP_KEEPCNT次探测均无响应,则判定该连接已失效,GeminiDB会主动断开该连接,以释放服务端的连接资源,保障整体服务的稳定性和可用性。

如果客户使用的GeminiDB Redis实例内核小版本低于5.0.6.4,其tcp-keepalive设置较为敏感,且不支持动态调整,建议升级至最新版本。新版本不仅优化了探活机制,降低了因网络波动导致连接误断的小概率问题,还增强了连接管理的灵活性与稳定性,有助于提升整体服务的可靠性。
客户端连接重连和命令重试使用介绍
在实际应用中,客户端与服务端之间的网络通信可能会受到各种因素的影响,如网络丢包、抖动异常或临时性故障等。为提升系统的健壮性和用户体验,建议客户端引入连接重连和命令重试机制,以降低网络抖动的影响。
在网络出现丢包、抖动等情况,或是进行GeminiDB在线滚动节点规格变更、版本升级等操作时,可能会导致客户端与GeminiDB实例之间的连接中断。为了确保操作能够成功执行,客户端应当具备自动重连机制。推荐采用主流的Redis客户端,比如Jedis,在获取连接之前先进行连接检测,或者定期检查空闲连接的状态,以此来防止因连接问题而导致的操作超时或失败。这样可以有效提升系统的连接性和可靠性。
- 设置testonBorrow,在获取连接时进行有效性检测。
JedisPoolConfig poolConfig = new JedisPoolConfig(); // 设置从连接池获取连接时进行有效性检查 poolConfig.setTestOnBorrow(true); // 其他配置... // 创建连接池时使用配置 JedisPool jedisPool = new JedisPool(poolConfig, "localhost", 6379);
当testOnBorrow设置为true时,每次从连接池获取连接时会进行连接有效性检测(即执行一次ping操作)。如果检测发现连接已失效,当前连接会被丢弃,并尝试获取另一个可用连接。这个设置可以确保每次获取到的连接都是有效的,但会带来一次额外的ping检测开销。在业务并发量较高的场景下,可以考虑启用空闲连接检测(如testWhileIdle),这样可以在连接未被使用时提前检测其有效性,减少每次获取连接时的检测开销,从而提升整体性能。
- 空闲连接检测,通过异步线程来探测连接是否正常,相比testonBorrow开销小一些。
JedisPoolConfig poolConfig = new JedisPoolConfig(); poolConfig.setTestWhileIdle(true); // 空闲连接检测周期(30-60秒) poolConfig.setTimeBetweenEvictionRunsMillis(30000); // 每次检查的连接数(建议为负值,表示检查全部空闲连接) poolConfig.setNumTestsPerEvictionRun(-1); // 连接最小空闲时间(超过此值才开始检测) poolConfig.setMinEvictableIdleTimeMillis(60000); // 60秒 JedisPool jedisPool = new JedisPool(poolConfig, "localhost", 6379);
名称 |
说明 |
默认值 |
建议 |
---|---|---|---|
testWhileIdle |
是否在空闲资源监测时通过ping命令监测连接有效性,无效连接将被销毁。 |
false |
true |
timeBetweenEvictionRunsMillis |
空闲资源的检测周期(单位为毫秒) |
-1(不检测) |
建议设置,周期自行选择,可设置30000。 |
minEvictableIdleTimeMillis |
资源池中资源的最小空闲时间(单位为毫秒),达到此值后空闲资源将被移除。 |
1,800,000(即30分钟) |
建议设置为默认值。 |
numTestsPerEvictionRun |
做空闲资源检测时,每次检测资源的个数。 |
3 |
可根据自身应用连接数进行微调,建议设置为 -1,对所有连接做空闲监测。 |
在Redis命令执行失败时,例如由于网络抖动导致的超时,对于像SET key value这类具有幂等性的操作,可以考虑进行重试,从而避免短暂网络问题带来的影响。而对于LPUSH、LPOP等非幂等操作,重试可能会导致数据被多次插入或删除,进而引发业务逻辑错误。因此,在使用重试策略时,需结合具体业务场景进行分析,判断是否适合重试,并合理设置重试次数与重试间隔,以保障操作的成功执行。
public <T> T executeWithRetry(RedisCommand<T> command, int maxAttempts) { JedisException lastException = null; for (int attempt = 1; attempt <= maxAttempts; attempt++) { try (Jedis jedis = jedisPool.getResource()) { return command.execute(jedis); } catch (JedisConnectionException e) { lastException = e; log.warn("Redis connection failed (attempt {}/{}): {}", attempt, maxAttempts, e.getMessage()); // 可通过sleep或者指数退避等待策略,间隔一段时间再重试 Thread.sleep(waitTime); } } throw new RedisOperationException("Max retry attempts reached", lastException); }