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

这篇具有很好参考价值的文章主要介绍了大厂都是怎么做Redis重试的?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

0 前言

潜心打造国内一流,国际领先的技术干货。

文章收录在我的 GitHub 仓库,欢迎Star/fork:

JavaEdge-Interview

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

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

1 引发暂时性故障的原因

1.1 故障触发了高可用机制

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

更多参见:主备切换。

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 = 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和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

本文由博客一文多发平台 OpenWrite 发布!文章来源地址https://www.toymoban.com/news/detail-749953.html

到了这里,关于大厂都是怎么做Redis重试的?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 历经70+场面试,我发现了大厂面试的套路都是···

    今年的金三银四刚刚过去,我又想起了我在去年春招时面试了50余家,加上暑期实习面试了20余家,加起来也面试了70余场的面试场景了。 基本把国内有名的互联网公司都面了一遍,不敢说自己的面试经验很丰富,但也是不差的。 这次我专门把大厂的面试做了个总结,希望帮

    2024年02月06日
    浏览(22)
  • 07. HTTP接口请求重试怎么处理?

     目录 1、前言 2、实现方式 2.1、循环重试 2.2、递归重试 2.3、Spring Retry 2.4、Resilience4j 2.5、http请求网络工具内置重试方式 2.6、自定义重试工具 2.7、并发框架异步重试 2.8、消息队列 3、小结 HTTP接口请求重试是指在请求失败时,再次发起请求的机制。在实际应用中,由于网络波

    2024年02月03日
    浏览(22)
  • 技术大佬们都是怎么学习的?

    目录 问题 熟悉更多业务 熟悉端到端 自学 Do exercise Learning trying Teaching 今天逛帖子的时候,看到这么个问题:          这个问题我曾经也很好奇过,那些成为技术大佬的人当初是怎么学习,以及怎么成长过来的,因为我相信他们也是从 0 开始的,也会经历困难期之类的。

    2024年02月06日
    浏览(25)
  • 那些漏洞挖掘高手都是怎么挖漏洞的?

    说到安全就不能不说漏洞,而说到漏洞就不可避免地会说到三座大山: 漏洞分析 漏洞利用 漏洞挖掘 从个人的感觉上来看,这三者尽管通常水乳交融、相互依赖,但难度是不尽相同的。本文就这三者分别谈谈自己的经验和想法。 漏洞分析相对简单,通常公开的漏洞中就有一

    2024年02月17日
    浏览(28)
  • 一线大厂Redis高并发缓存架构实战与性能优化

    我们都知道,一般的互联网公司redis部署都是主从结构的,那么复制基本都是异步执行的, 那就存在一个问题,当我们设置分布式锁的时候,还没来得及将key复制到从节点,主节点挂了,那么从节点会成为主节点,但是主节点的分布式锁key就会丢失掉,如果新线程进来执行同

    2024年02月08日
    浏览(26)
  • 聊聊大厂都怎么防止重复下单?

    一、问题背景 最简单的:DB 事务。如创建订单时,同时往订单表、订单商品表插数据,这些 Insert 须在同一事务执行。 Order 服务调用 Pay 服务,刚好网络超时,然后 Order 服务开始重试机制,于是 Pay 服务对同一支付请求,就接收到了两次,而且因为轮询负载均衡算法,落在了

    2024年02月11日
    浏览(34)
  • (高阶) Redis 7 第19讲 缓存过期淘汰策略 大厂篇

    1. 生产上,redis内存设置的多少 2. 如何配置、修改Redis 内存大小 3. 如果内存满了,如何处理 4. Redis 清理内存的方式有哪些?定期删除和惰性删除了解吗 5. Redis 缓存淘汰策略有哪些?分别是什么?你用哪个 6. Redis 的LRU了解过吗?请手写LRU 7. LRU和LFU 算法的区别是什么  Redis 默

    2024年02月07日
    浏览(30)
  • 测试工程师都是怎么写测试用例的?​

    很多人不知道写测试用例有什么用,而仅仅是像工具人一样,在每次提测之前,把测试用例照着需求文档抄一遍,仿佛像是走个过场。 开发提测之后,就照着测试用例点点点,可能一天就走完用例了,开发代码写得真好,测试用例执行完毕都没有测出bug,然后美其名曰:测试

    2024年02月05日
    浏览(46)
  • 【解决方法】PPT不能编辑,按钮都是灰色,怎么办?

    PPT文件打开之后,发现无法编辑,再仔细查看发现工具栏中的功能按钮都是灰色的,无法使用,这是什么原因?该如何解决? 原因:无法编辑PPT文件,并且功能按钮都是灰色,这是因为文件设置了编辑权限导致的。 而想要取消修改权限,我们需要打开文件时输入权限密码,

    2024年01月25日
    浏览(42)
  • docker 导入镜像 REPOSITORY和tag都是null怎么解决

    当使用 docker import 命令导入镜像时, REPOSITORY 和 TAG 字段可能会为 null ,因为 docker import 命令不会保留镜像的元数据,例如镜像名称和标签。这是因为 docker import 命令主要用于将本地文件系统中的文件或目录导入为 Docker 镜像,而不涉及 Docker 镜像仓库中的镜像。 如果你想要保

    2024年02月04日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包