0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Redis重试准则是什么?

OSC开源社区 来源:OSC开源社区 2023-11-15 10:31 次阅读

网络和运行环境影响,应用程序可能遇到暂时性故障,如瞬时网络抖动、服务暂时不可用、服务繁忙导致超时等。 自动重试机制可大幅避免此类故障,保障操作成功执行。

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 依赖


    redis.clients
    jedis
    5.0.0

3.2 重试实战

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

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

PooledConnectionProvider provider = new PooledConnectionProvider(HostAndPort.from("127.0.0.1:6379"));
int maxAttempts = 5; // 最大重试次数
Duration maxTotalRetriesDuration = Duration.ofSeconds(10); // 最大的重试时间
UnifiedJedis jedis = new UnifiedJedis(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");
int connectionTimeout = 5000;
int soTimeout = 2000;
int maxAttempts = 5;
ConnectionPoolConfig config = new ConnectionPoolConfig();
JedisCluster jedisCluster = new JedisCluster(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 客户端目前仅支持重试时连接,重试示例如下:

var conn = 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

编辑:黄飞

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 服务器
    +关注

    关注

    12

    文章

    8926

    浏览量

    85045
  • API
    API
    +关注

    关注

    2

    文章

    1470

    浏览量

    61731
  • 客户端
    +关注

    关注

    1

    文章

    288

    浏览量

    16639
  • Redis
    +关注

    关注

    0

    文章

    370

    浏览量

    10824

原文标题:大厂都是怎么做Redis重试的?

文章出处:【微信号:OSC开源社区,微信公众号:OSC开源社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    如何使用Rust连接Redis

    Redis是一款快速、开源、键值存储数据库,被广泛应用于缓存、发布/订阅系统、定时任务等场景中。Rust提供了很多Redis的客户端库,本教程将会介绍如何使用Rust连接Redis,以及如何通过
    的头像 发表于 09-19 16:22 2172次阅读

    Redis Stream应用案例

    摘要: Redis Stream Redis最新的大版本5.0已经RC1了,其中最重要的Feature莫过于Redis Stream了,关于Redis Stream的基本使用介绍和设计
    发表于 06-26 17:15

    redis概述

    REmote DIctionary Server(Redis)是一个基于key-value键值对的持久化数据库存储系统。redis和大名鼎鼎的Memcached缓存服务软件很像,但是redis支持
    发表于 07-17 07:38

    如何使得redis中的数据不再有

    嵌入式Linux系统重启后如何使得redis中的数据不再有今天在工作中遇到一个问题:网页展示redis中的数据,然而再Linux系统重启后网页还能展示redis中的数据,感觉很奇怪,到网上搜了下
    发表于 11-05 08:50

    设计STM32串口驱动要遵循的两条准则是什么

    设计STM32串口驱动要遵循的两条准则是什么?如何去实现STM32串口设备驱动接口的代码呢?
    发表于 12-07 06:15

    圆形电路板设计事项和准则是什么?

    圆形电路板设计事项和准则是什么? 现如今PCB板有多种形状可供选择,尽管方形和矩形 PCB 仍然是最常见的,但随着电子行业的不断发展,圆形PCB也是逐渐崭露头角。 顾名思义,圆形PCB是板子是圆形
    的头像 发表于 09-21 18:28 1657次阅读

    如何在RocketMQ中合理使用重试机制

    RocketMQ 的重试机制包括三部分,分别是生产者重试,服务端内部数据复制遇到非预期问题时重试,消费者消费重试
    的头像 发表于 11-23 10:15 1080次阅读

    什么是 Redis

      —   1  — 什么是 RedisRedis(REmote DIctionary Service)是一个开源的键值对数据库服务器。 Redis 更准确的描述是一个数据结构服务器。Re
    的头像 发表于 05-22 15:32 1062次阅读
    什么是 <b class='flag-5'>Redis</b>

    Redis的主从、哨兵、Redis Cluster集群

      前言 今天跟小伙伴们一起学习Redis的主从、哨兵、Redis Cluster集群。 Redis主从 Redis哨兵 Redis Clu
    的头像 发表于 06-12 14:58 770次阅读
    <b class='flag-5'>Redis</b>的主从、哨兵、<b class='flag-5'>Redis</b> Cluster集群

    如何用Springboot整合Redis

    本篇文件我们来介绍如何用Springboot整合Redis。 1、Docker 安装 Redis 1.1 下载镜像 docker pull redis: 6 . 2 . 6 1.2 创建配置文件
    的头像 发表于 10-08 14:56 541次阅读
    如何用Springboot整合<b class='flag-5'>Redis</b>

    Redis持久化RDB方式介绍

    主从复制操作 原理图 设置快照保存规则 快照规则是配置在 redis.conf 文件中的,我这里我截取对应的代码片段,给大家看下。 #
    的头像 发表于 10-09 14:56 474次阅读
    <b class='flag-5'>Redis</b>持久化RDB方式介绍

    Tenacity重试模块实践

    为了避免由于一些网络或等其他不可控因素,而引起的功能性问题。比如在发送请求时,会因为网络不稳定,往往会有请求超时的问题。 这种情况下,我们通常会在代码中加入重试的代码。重试的代码本身不难实现,但
    的头像 发表于 11-02 11:33 370次阅读

    Python中retrying库的有参数重试

    有参数重试 (1) stop_max_attempt_number 在retry中传入stop_max_attempt_number参数后可以指定失败重试的次数 @retry
    的头像 发表于 11-14 11:08 675次阅读
    Python中retrying库的有参数<b class='flag-5'>重试</b>

    redis的持久化方式RDB和AOF的区别

    Redis 是一个高性能的键值对数据库,提供了两种持久化方式:RDB 和 AOF。RDB 是将 Redis 的数据快照保存到磁盘上,而 AOF 则是Redis 的操作命令追加到文件
    的头像 发表于 12-04 16:25 718次阅读

    redis容器内怎么查看redis日志

    redis是一款流行的开源内存数据库,常用于缓存、消息队列、任务管理等场景。在使用redis时,了解如何查看redis日志对于排查问题、监控性能和分析应用程序行为非常重要。在本文中,我们将介绍在
    的头像 发表于 12-05 10:10 3331次阅读