您当前的位置:首页 > 电脑百科 > 数据库 > Redis

大厂都是怎么做Redis重试的?

时间:2023-11-15 13:22:48  来源:OSC开源社区  作者:

受网络和运行环境影响,应用程序可能遇到暂时性故障,如瞬时网络抖动、服务暂时不可用、服务繁忙导致超时等。

自动重试机制可大幅避免此类故障,保障操作成功执行。

1 引发暂时性故障的原因1.1 故障触发了高可用机制

redis 支持节点健康状态监测,当监测到实例中的主节点不可用时,会自动触发主备切换,例如将主节点和从节点进行互换,保障实例的高可用性。此时,客户端可能会遇到下列暂时性故障:秒级的连接闪断。30 秒内的只读状态(用于避免主备切换引起潜在的数据丢失风险和双写)。

更多参见:主备切换(https://help.aliyun.com/zh/redis/user-guide/master-replica-switchovers#concept-2025502)

1.2 慢查询引起了请求堵塞

执行时间复杂度为 O (N) 的操作,引发慢查询和请求的堵塞,此时,客户端发起的其他请求可能出现暂时性失败。

1.3 复杂的网络环境

由于客户端与 Redis 服务器之间复杂网络环境引起,可能出现偶发的网络抖动、数据重传等问题,此时,客户端发起的请求可能会出现暂时性失败。

2 推荐的重试准则2.1 仅重试幂等的操作

由于超时可能发生在下述任一阶段:该命令由客户端发送成功,但尚未到达 Redis。命令到达 Redis,但执行超时。命令在 Redis 中执行结束,但结果返回给客户端时发生超时。如果执行重试可能导致某个操作在 Redis 中被重复执行,因此不是所有操作均适合设计重试机制。通常推荐仅重试幂等的操作,例如 SET操作,即多次执行 SET a b命令,那么 a 的值只可能是 b 或执行失败;如果执行 LPUSH mylist a则不是幂等的,可能导致 mylist 中包含多个 a 元素。

2.2 适当的重试次数与间隔

根据业务需求和实际场景调整适当的重试次数与间隔,否则可能引发下述问题:如果重试次数不足或间隔太长,应用程序可能无法完成操作而导致失败。如果重试次数过大或间隔过短,应用程序可能会占用过多的系统资源,且可能因请求过多而堵塞在服务器上无法恢复。常见的重试间隔方式包括立即重试、固定时间重试、指数增加时间重试、随机时间重试等。

2.3 避免重试嵌套

避免重试嵌套,否则可能会导致重复的重试且无法停止。

2.4 记录重试异常并打印失败报告

在重试过程中,建议在 WARN 级别上打印重试错误日志,同时,仅在重试失败时打印异常信息。

3 Jedis

建议使用 Jedis 4.0.0 及以上版本,推荐使用最新的 Jedis 版本,以下代码为 Jedis 5.0.0 的重试示例。

3.1 添加 Jedis 的 Pom 依赖<dependency>

<groupId>redis.clients</groupId>

<artifactId>jedis</artifactId>

<version>5.0.0</version>

</dependency>

3.2 重试实战① 标准架构实例或集群架构代理(Proxy)模式

使用 JedisPool 模式。

该示例会将 SET 命令自动重试 5 次,且总重试时间不超过 10s,每次重试之间等待类指数间隔的时间,如果最终不成功,则抛出异常。

PooledConnectionProvider provider = newPooledConnectionProvider(HostAndPort.from("127.0.0.1:6379"));

intmaxAttempts = 5; // 最大重试次数

Duration maxTotalRetriesDuration = Duration.ofSeconds(10); // 最大的重试时间

UnifiedJedis jedis = newUnifiedJedis(provider, maxAttempts, maxTotalRetriesDuration);

try{

System.out.println("set key: "+ jedis.set("key", "value"));

} catch(Exception e) {

// 表示尝试maxAttempts次或到达了最大查询时间maxTotalRetriesDuration仍旧没有访问成功。

e.printStackTrace;

}

② 集群架构直连模式

使用 JedisCluster 模式。

可以通过配置 maxAttempts 参数来定义失败情况下的重试次数,默认值为 5,如果最终不成功,则抛出异常。

HostAndPort hostAndPort = HostAndPort.from("127.0.0.1:30001");

intconnectionTimeout = 5000;

intsoTimeout = 2000;

intmaxAttempts = 5;

ConnectionPoolConfig config = newConnectionPoolConfig;

JedisCluster jedisCluster = newJedisCluster(hostAndPort, connectionTimeout, soTimeout, maxAttempts, config);

try{

System.out.println("set key: "+ jedisCluster.set("key", "value"));

} catch(Exception e) {

// 表示尝试maxAttempts之后仍旧没有访问成功。

e.printStackTrace;

}

4 Redisson

Redisson 客户端提供了两个参数来控制重试逻辑:

  • retryAttempts:重试次数,默认为 3。
  • retryInterval:重试间隔,默认为 1,500 毫秒。

重试示例如下:

Config config= new Config;

config.useSingleServer

.setTimeout(1000)

.setRetryAttempts(3)

.setRetryInterval(1500) //ms

.setAddress("redis://127.0.0.1:6379");

RedissonClient connect = Redisson.create(config);

5 StackExchange.Redis

StackExchang.Redis 客户端目前仅支持重试时连接,重试示例如下:

varconn = ConnectionMultiplexer.Connect("redis0:6380,redis1:6380,connectRetry=3");

说明

如需实现 API 级别的重试策略,请参见 Polly。

6 Lettuce

Lettuce 客户端未提供在命令超时后重试的参数,但是您可以通过下述参数来实现命令重试策略:

  • at-most-once execution:命令最多执行 1 次,即 0 次或 1 次,如果连接断开并重新连接,命令可能会丢失。
  • at-least-once execution(默认):最少成功执行 1 次,即可能会在执行时进行多次尝试,保障最少成功执行 1 次。使用此策略时,如果 TAIr 实例发生了主备切换,此时客户端可能累积了较多的重试命令,主备切换完成后可能会引发 Tair 实例的 CPU 使用率激增。

说明

更多信息,请参见 Client-Options( https://Github.com/lettuce-io/lettuce-core/wiki/Client-Options) 和 Command execution reliability( https://github.com/lettuce-io/lettuce-core/wiki/Command-execution-reliability)。

重试示例:

clientOptions.isAutoReconnect? Reliability.AT_LEAST_ONCE: Reliability.AT_MOST_ONCE;

参考:

  • https://help.aliyun.com/zh/redis/use-cases/retry-mechanisms-for-redis-clients

  • 通过客户端程序连接 Redis

  • 客户端程序 TLS(SSL)加密连接 Redis

END



Tags:Redis   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
Redis 不再 “开源”,未来采用 SSPLv1 和 RSALv2 许可证
Redis 官方于21日宣布修改开源协议 &mdash;&mdash; 未来所有版本都将使用 “源代码可用” 的许可证 (source-available licenses)。具体来说,Redis 将不再遵循 BSD 3-Clause...【详细内容】
2024-03-27  Search: Redis  点击:(11)  评论:(0)  加入收藏
Redis“叛逃”开源,得罪了几乎所有人
内存数据库供应商Redis近日在开源界砸下了一块“巨石”。Redis即将转向双许可模式,并实施更为严格的许可条款。官方对此次变更的公告直截了当:从Redis 7.4版本开始,Redis将在Re...【详细内容】
2024-03-25  Search: Redis  点击:(9)  评论:(0)  加入收藏
如何使用 Redis 实现消息队列
Redis不仅是一个强大的内存数据存储系统,它还可以用作一个高效的消息队列。消息队列是应用程序间或应用程序内部进行异步通信的一种方式,它允许数据生产者将消息放入队列中,然...【详细内容】
2024-03-22  Search: Redis  点击:(17)  评论:(0)  加入收藏
Redis不再 “开源”
Redis 官方今日宣布修改开源协议 &mdash;&mdash; 未来所有版本都将使用 “源代码可用” 的许可证 (source-available licenses)。具体来说,Redis 将不再遵循 BSD 3-Clause 开...【详细内容】
2024-03-21  Search: Redis  点击:(8)  评论:(0)  加入收藏
在Redis中如何实现分布式锁的防死锁机制?
在Redis中实现分布式锁是一个常见的需求,可以通过使用Redlock算法来防止死锁。Redlock算法是一种基于多个独立Redis实例的分布式锁实现方案,它通过协调多个Redis实例之间的锁...【详细内容】
2024-02-20  Search: Redis  点击:(47)  评论:(0)  加入收藏
手动撸一个 Redis 分布式锁
大家好呀,我是楼仔。今天第一天开工,收拾心情,又要开始好好学习,好好工作了。对于使用 Java 的小伙伴,其实我们完全不用手动撸一个分布式锁,直接使用 Redisson 就行。但是因为这些...【详细内容】
2024-02-19  Search: Redis  点击:(39)  评论:(0)  加入收藏
工作中Redis有哪些好用的运维工具
工作中使用 Redis 时,如果大家公司没有专业运维,可能开发人员就会面临这些运维的工作,包括 Redis 的运行状态监控,数据迁移,主从集群、切片集群的部署和运维等等。本文我就从这三...【详细内容】
2024-02-06  Search: Redis  点击:(55)  评论:(0)  加入收藏
深入Go底层原理,重写Redis中间件实战
Go语言以其简洁、高效和并发性能而闻名,深入了解其底层原理可以帮助我们更好地利用其优势。在本文中,我们将探讨如何深入Go底层原理,以及如何利用这些知识重新实现一个简单的Re...【详细内容】
2024-01-25  Search: Redis  点击:(66)  评论:(0)  加入收藏
批量执行Redis命令的四种方式!
前言在我们的印象中Redis命令好像都是一个个单条进行执行的,如果有人问你如何批量执行Redis命令,你能回答的上吗,或者说能答出几种方式呢?最容易想到的是Redis的一些批量命令,例...【详细内容】
2024-01-17  Search: Redis  点击:(57)  评论:(0)  加入收藏
Redis 实现多规则限流的思考与实践
市面上很多介绍redis如何实现限流的,但是大部分都有一个缺点,就是只能实现单一的限流,比如1分钟访问1次或者60分钟访问10次这种,但是如果想一个接口两种规则都需要满足呢,我们的...【详细内容】
2024-01-03  Search: Redis  点击:(109)  评论:(0)  加入收藏
▌简易百科推荐
Redis 不再 “开源”,未来采用 SSPLv1 和 RSALv2 许可证
Redis 官方于21日宣布修改开源协议 &mdash;&mdash; 未来所有版本都将使用 “源代码可用” 的许可证 (source-available licenses)。具体来说,Redis 将不再遵循 BSD 3-Clause...【详细内容】
2024-03-27  dbaplus社群    Tags:Redis   点击:(11)  评论:(0)  加入收藏
Redis“叛逃”开源,得罪了几乎所有人
内存数据库供应商Redis近日在开源界砸下了一块“巨石”。Redis即将转向双许可模式,并实施更为严格的许可条款。官方对此次变更的公告直截了当:从Redis 7.4版本开始,Redis将在Re...【详细内容】
2024-03-25    51CTO  Tags:Redis   点击:(9)  评论:(0)  加入收藏
如何使用 Redis 实现消息队列
Redis不仅是一个强大的内存数据存储系统,它还可以用作一个高效的消息队列。消息队列是应用程序间或应用程序内部进行异步通信的一种方式,它允许数据生产者将消息放入队列中,然...【详细内容】
2024-03-22  后端Q  微信公众号  Tags:Redis   点击:(17)  评论:(0)  加入收藏
Redis不再 “开源”
Redis 官方今日宣布修改开源协议 &mdash;&mdash; 未来所有版本都将使用 “源代码可用” 的许可证 (source-available licenses)。具体来说,Redis 将不再遵循 BSD 3-Clause 开...【详细内容】
2024-03-21  OSC开源社区    Tags:Redis   点击:(8)  评论:(0)  加入收藏
在Redis中如何实现分布式锁的防死锁机制?
在Redis中实现分布式锁是一个常见的需求,可以通过使用Redlock算法来防止死锁。Redlock算法是一种基于多个独立Redis实例的分布式锁实现方案,它通过协调多个Redis实例之间的锁...【详细内容】
2024-02-20  编程技术汇    Tags:Redis   点击:(47)  评论:(0)  加入收藏
手动撸一个 Redis 分布式锁
大家好呀,我是楼仔。今天第一天开工,收拾心情,又要开始好好学习,好好工作了。对于使用 Java 的小伙伴,其实我们完全不用手动撸一个分布式锁,直接使用 Redisson 就行。但是因为这些...【详细内容】
2024-02-19  楼仔  微信公众号  Tags:Redis   点击:(39)  评论:(0)  加入收藏
工作中Redis有哪些好用的运维工具
工作中使用 Redis 时,如果大家公司没有专业运维,可能开发人员就会面临这些运维的工作,包括 Redis 的运行状态监控,数据迁移,主从集群、切片集群的部署和运维等等。本文我就从这三...【详细内容】
2024-02-06  waynaqua    Tags:Redis   点击:(55)  评论:(0)  加入收藏
批量执行Redis命令的四种方式!
前言在我们的印象中Redis命令好像都是一个个单条进行执行的,如果有人问你如何批量执行Redis命令,你能回答的上吗,或者说能答出几种方式呢?最容易想到的是Redis的一些批量命令,例...【详细内容】
2024-01-17  小许code  微信公众号  Tags:Redis命令   点击:(57)  评论:(0)  加入收藏
Redis 实现多规则限流的思考与实践
市面上很多介绍redis如何实现限流的,但是大部分都有一个缺点,就是只能实现单一的限流,比如1分钟访问1次或者60分钟访问10次这种,但是如果想一个接口两种规则都需要满足呢,我们的...【详细内容】
2024-01-03  架构精进之路  微信公众号  Tags:Redis   点击:(109)  评论:(0)  加入收藏
一站式Redis解决方案
Redis是一个高效的内存数据库,它支持包括String、List、Set、SortedSet和Hash等数据类型的存储,在Redis中通常根据数据的key查询其value值,Redis没有模糊条件查询,在面对一些需...【详细内容】
2024-01-01  大雷家吃饭    Tags:Redis   点击:(66)  评论:(0)  加入收藏
站内最新
站内热门
站内头条