0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Redis重試準(zhǔn)則是什么?

OSC開源社區(qū) ? 來源:OSC開源社區(qū) ? 2023-11-15 10:31 ? 次閱讀

網(wǎng)絡(luò)和運(yùn)行環(huán)境影響,應(yīng)用程序可能遇到暫時(shí)性故障,如瞬時(shí)網(wǎng)絡(luò)抖動(dòng)、服務(wù)暫時(shí)不可用、服務(wù)繁忙導(dǎo)致超時(shí)等。 自動(dòng)重試機(jī)制可大幅避免此類故障,保障操作成功執(zhí)行。

1 引發(fā)暫時(shí)性故障的原因

1.1 故障觸發(fā)了高可用機(jī)制

云 Redis 支持節(jié)點(diǎn)健康狀態(tài)監(jiān)測(cè),當(dāng)監(jiān)測(cè)到實(shí)例中的主節(jié)點(diǎn)不可用時(shí),會(huì)自動(dòng)觸發(fā)主備切換,例如將主節(jié)點(diǎn)和從節(jié)點(diǎn)進(jìn)行互換,保障實(shí)例的高可用性。此時(shí),客戶端可能會(huì)遇到下列暫時(shí)性故障:秒級(jí)的連接閃斷。30 秒內(nèi)的只讀狀態(tài)(用于避免主備切換引起潛在的數(shù)據(jù)丟失風(fēng)險(xiǎn)和雙寫)。 更多參見:主備切換(https://help.aliyun.com/zh/redis/user-guide/master-replica-switchovers#concept-2025502)

1.2 慢查詢引起了請(qǐng)求堵塞

執(zhí)行時(shí)間復(fù)雜度為 O (N) 的操作,引發(fā)慢查詢和請(qǐng)求的堵塞,此時(shí),客戶端發(fā)起的其他請(qǐng)求可能出現(xiàn)暫時(shí)性失敗。

1.3 復(fù)雜的網(wǎng)絡(luò)環(huán)境

由于客戶端與 Redis 服務(wù)器之間復(fù)雜網(wǎng)絡(luò)環(huán)境引起,可能出現(xiàn)偶發(fā)的網(wǎng)絡(luò)抖動(dòng)、數(shù)據(jù)重傳等問題,此時(shí),客戶端發(fā)起的請(qǐng)求可能會(huì)出現(xiàn)暫時(shí)性失敗。

2 推薦的重試準(zhǔn)則

2.1 僅重試冪等的操作

由于超時(shí)可能發(fā)生在下述任一階段:該命令由客戶端發(fā)送成功,但尚未到達(dá) Redis。命令到達(dá) Redis,但執(zhí)行超時(shí)。命令在 Redis 中執(zhí)行結(jié)束,但結(jié)果返回給客戶端時(shí)發(fā)生超時(shí)。如果執(zhí)行重試可能導(dǎo)致某個(gè)操作在 Redis 中被重復(fù)執(zhí)行,因此不是所有操作均適合設(shè)計(jì)重試機(jī)制。通常推薦僅重試冪等的操作,例如SET操作,即多次執(zhí)行SET a b命令,那么 a 的值只可能是 b 或執(zhí)行失?。蝗绻麍?zhí)行LPUSH mylist a則不是冪等的,可能導(dǎo)致 mylist 中包含多個(gè) a 元素。

2.2 適當(dāng)?shù)闹卦嚧螖?shù)與間隔

根據(jù)業(yè)務(wù)需求和實(shí)際場(chǎng)景調(diào)整適當(dāng)?shù)闹卦嚧螖?shù)與間隔,否則可能引發(fā)下述問題:如果重試次數(shù)不足或間隔太長(zhǎng),應(yīng)用程序可能無法完成操作而導(dǎo)致失敗。如果重試次數(shù)過大或間隔過短,應(yīng)用程序可能會(huì)占用過多的系統(tǒng)資源,且可能因請(qǐng)求過多而堵塞在服務(wù)器上無法恢復(fù)。常見的重試間隔方式包括立即重試、固定時(shí)間重試、指數(shù)增加時(shí)間重試、隨機(jī)時(shí)間重試等。

2.3 避免重試嵌套

避免重試嵌套,否則可能會(huì)導(dǎo)致重復(fù)的重試且無法停止。

2.4 記錄重試異常并打印失敗報(bào)告

在重試過程中,建議在 WARN 級(jí)別上打印重試錯(cuò)誤日志,同時(shí),僅在重試失敗時(shí)打印異常信息。

3 Jedis

建議使用 Jedis 4.0.0 及以上版本,推薦使用最新的 Jedis 版本,以下代碼為 Jedis 5.0.0 的重試示例。

3.1 添加 Jedis 的 Pom 依賴


    redis.clients
    jedis
    5.0.0

3.2 重試實(shí)戰(zhàn)

① 標(biāo)準(zhǔn)架構(gòu)實(shí)例或集群架構(gòu)代理(Proxy)模式

使用 JedisPool 模式。 該示例會(huì)將 SET 命令自動(dòng)重試 5 次,且總重試時(shí)間不超過 10s,每次重試之間等待類指數(shù)間隔的時(shí)間,如果最終不成功,則拋出異常。

PooledConnectionProvider provider = new PooledConnectionProvider(HostAndPort.from("127.0.0.1:6379"));
int maxAttempts = 5; // 最大重試次數(shù)
Duration maxTotalRetriesDuration = Duration.ofSeconds(10); // 最大的重試時(shí)間
UnifiedJedis jedis = new UnifiedJedis(provider, maxAttempts, maxTotalRetriesDuration);
try {
    System.out.println("set key: " + jedis.set("key", "value"));
} catch (Exception e) {
    // 表示嘗試maxAttempts次或到達(dá)了最大查詢時(shí)間maxTotalRetriesDuration仍舊沒有訪問成功。
    e.printStackTrace();
}

② 集群架構(gòu)直連模式

使用 JedisCluster 模式。 可以通過配置 maxAttempts 參數(shù)來定義失敗情況下的重試次數(shù),默認(rèn)值為 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 客戶端提供了兩個(gè)參數(shù)來控制重試邏輯:

retryAttempts:重試次數(shù),默認(rèn)為 3。

retryInterval:重試間隔,默認(rèn)為 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 客戶端目前僅支持重試時(shí)連接,重試示例如下:

var conn = ConnectionMultiplexer.Connect("redis0:6380,redis1:6380,connectRetry=3");
說明 如需實(shí)現(xiàn) API 級(jí)別的重試策略,請(qǐng)參見 Polly。

6 Lettuce

Lettuce 客戶端未提供在命令超時(shí)后重試的參數(shù),但是您可以通過下述參數(shù)來實(shí)現(xiàn)命令重試策略:

at-most-once execution:命令最多執(zhí)行 1 次,即 0 次或 1 次,如果連接斷開并重新連接,命令可能會(huì)丟失。

at-least-once execution(默認(rèn)):最少成功執(zhí)行 1 次,即可能會(huì)在執(zhí)行時(shí)進(jìn)行多次嘗試,保障最少成功執(zhí)行 1 次。使用此策略時(shí),如果 Tair 實(shí)例發(fā)生了主備切換,此時(shí)客戶端可能累積了較多的重試命令,主備切換完成后可能會(huì)引發(fā) Tair 實(shí)例的 CPU 使用率激增。

說明

更多信息,請(qǐng)參見 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

編輯:黃飛

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 服務(wù)器
    +關(guān)注

    關(guān)注

    12

    文章

    8979

    瀏覽量

    85100
  • API
    API
    +關(guān)注

    關(guān)注

    2

    文章

    1475

    瀏覽量

    61760
  • 客戶端
    +關(guān)注

    關(guān)注

    1

    文章

    289

    瀏覽量

    16645
  • Redis
    +關(guān)注

    關(guān)注

    0

    文章

    370

    瀏覽量

    10830

原文標(biāo)題:大廠都是怎么做Redis重試的?

文章出處:【微信號(hào):OSC開源社區(qū),微信公眾號(hào):OSC開源社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    如何使用Rust連接Redis

    Redis是一款快速、開源、鍵值存儲(chǔ)數(shù)據(jù)庫(kù),被廣泛應(yīng)用于緩存、發(fā)布/訂閱系統(tǒng)、定時(shí)任務(wù)等場(chǎng)景中。Rust提供了很多Redis的客戶端庫(kù),本教程將會(huì)介紹如何使用Rust連接Redis,以及如何通過
    的頭像 發(fā)表于 09-19 16:22 ?2190次閱讀

    Redis Stream應(yīng)用案例

    摘要: Redis Stream Redis最新的大版本5.0已經(jīng)RC1了,其中最重要的Feature莫過于Redis Stream了,關(guān)于Redis Stream的基本使用介紹和設(shè)計(jì)
    發(fā)表于 06-26 17:15

    redis概述

    REmote DIctionary Server(Redis)是一個(gè)基于key-value鍵值對(duì)的持久化數(shù)據(jù)庫(kù)存儲(chǔ)系統(tǒng)。redis和大名鼎鼎的Memcached緩存服務(wù)軟件很像,但是redis支持
    發(fā)表于 07-17 07:38

    如何使得redis中的數(shù)據(jù)不再有

    嵌入式Linux系統(tǒng)重啟后如何使得redis中的數(shù)據(jù)不再有今天在工作中遇到一個(gè)問題:網(wǎng)頁(yè)展示redis中的數(shù)據(jù),然而再Linux系統(tǒng)重啟后網(wǎng)頁(yè)還能展示redis中的數(shù)據(jù),感覺很奇怪,到網(wǎng)上搜了下
    發(fā)表于 11-05 08:50

    設(shè)計(jì)STM32串口驅(qū)動(dòng)要遵循的兩條準(zhǔn)則是什么

    設(shè)計(jì)STM32串口驅(qū)動(dòng)要遵循的兩條準(zhǔn)則是什么?如何去實(shí)現(xiàn)STM32串口設(shè)備驅(qū)動(dòng)接口的代碼呢?
    發(fā)表于 12-07 06:15

    圓形電路板設(shè)計(jì)事項(xiàng)和準(zhǔn)則是什么?

    圓形電路板設(shè)計(jì)事項(xiàng)和準(zhǔn)則是什么? 現(xiàn)如今PCB板有多種形狀可供選擇,盡管方形和矩形 PCB 仍然是最常見的,但隨著電子行業(yè)的不斷發(fā)展,圓形PCB也是逐漸嶄露頭角。 顧名思義,圓形PCB是板子是圓形
    的頭像 發(fā)表于 09-21 18:28 ?1683次閱讀

    如何在RocketMQ中合理使用重試機(jī)制

    RocketMQ 的重試機(jī)制包括三部分,分別是生產(chǎn)者重試,服務(wù)端內(nèi)部數(shù)據(jù)復(fù)制遇到非預(yù)期問題時(shí)重試,消費(fèi)者消費(fèi)重試。
    的頭像 發(fā)表于 11-23 10:15 ?1090次閱讀

    什么是 Redis

    ? — ? 1 ?— 什么是 RedisRedis(REmote DIctionary Service)是一個(gè)開源的鍵值對(duì)數(shù)據(jù)庫(kù)服務(wù)器。 Redis 更準(zhǔn)確的描述是一個(gè)數(shù)據(jù)結(jié)構(gòu)服務(wù)器。Re
    的頭像 發(fā)表于 05-22 15:32 ?1072次閱讀
    什么是 <b class='flag-5'>Redis</b>

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

    ? 前言 今天跟小伙伴們一起學(xué)習(xí)Redis的主從、哨兵、Redis Cluster集群。 Redis主從 Redis哨兵 Redis Clu
    的頭像 發(fā)表于 06-12 14:58 ?780次閱讀
    <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 創(chuàng)建配置文件
    的頭像 發(fā)表于 10-08 14:56 ?548次閱讀
    如何用Springboot整合<b class='flag-5'>Redis</b>

    Redis持久化RDB方式介紹

    主從復(fù)制操作 原理圖 設(shè)置快照保存規(guī)則 快照規(guī)則是配置在 redis.conf 文件中的,我這里我截取對(duì)應(yīng)的代碼片段,給大家看下。 #
    的頭像 發(fā)表于 10-09 14:56 ?478次閱讀
    <b class='flag-5'>Redis</b>持久化RDB方式介紹

    Tenacity重試模塊實(shí)踐

    為了避免由于一些網(wǎng)絡(luò)或等其他不可控因素,而引起的功能性問題。比如在發(fā)送請(qǐng)求時(shí),會(huì)因?yàn)榫W(wǎng)絡(luò)不穩(wěn)定,往往會(huì)有請(qǐng)求超時(shí)的問題。 這種情況下,我們通常會(huì)在代碼中加入重試的代碼。重試的代碼本身不難實(shí)現(xiàn),但
    的頭像 發(fā)表于 11-02 11:33 ?378次閱讀

    Python中retrying庫(kù)的有參數(shù)重試

    有參數(shù)重試 (1) stop_max_attempt_number 在retry中傳入stop_max_attempt_number參數(shù)后可以指定失敗重試的次數(shù) @retry
    的頭像 發(fā)表于 11-14 11:08 ?687次閱讀
    Python中retrying庫(kù)的有參數(shù)<b class='flag-5'>重試</b>

    redis的持久化方式RDB和AOF的區(qū)別

    Redis 是一個(gè)高性能的鍵值對(duì)數(shù)據(jù)庫(kù),提供了兩種持久化方式:RDB 和 AOF。RDB 是將 Redis 的數(shù)據(jù)快照保存到磁盤上,而 AOF 則是Redis 的操作命令追加到文件
    的頭像 發(fā)表于 12-04 16:25 ?731次閱讀

    redis容器內(nèi)怎么查看redis日志

    redis是一款流行的開源內(nèi)存數(shù)據(jù)庫(kù),常用于緩存、消息隊(duì)列、任務(wù)管理等場(chǎng)景。在使用redis時(shí),了解如何查看redis日志對(duì)于排查問題、監(jiān)控性能和分析應(yīng)用程序行為非常重要。在本文中,我們將介紹在
    的頭像 發(fā)表于 12-05 10:10 ?3407次閱讀