最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Redis?Cluster?實現(xiàn)多key事務操作的示例

 更新時間:2026年02月06日 10:23:48   作者:小飛Coding  
本文主要介紹了Redis?Cluster?實現(xiàn)多key事務操作,包括HashTag+Lua腳本、應用層分步操作+補償機制、異步隊列+冪等消費等方案,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

在 Redis 集群模式下,MULTI/EXEC 事務直接報錯: “CROSSSLOT Keys in request don't hash to the same slot”。 那么,如何在保證數(shù)據(jù)一致性的前提下,同時操作多個 Key? 本文給出 生產(chǎn)級可行方案,從原子性到最終一致性全覆蓋。

如果你正在使用 Redis Cluster,一定遇到過這樣的困境:

  • 想扣用戶余額,同時創(chuàng)建訂單、記錄日志;
  • 寫了個 MULTI/EXEC,結果 Redis 報錯:key 不在同一個 slot;
  • 改用 Pipeline?但又怕中間被其他請求插隊,導致狀態(tài)不一致……

別急!Redis Cluster 雖然限制了跨 slot 的原子操作,但通過合理設計,我們依然能實現(xiàn)安全、可靠、高性能的多 Key 操作

一、為什么 Redis Cluster 不支持跨節(jié)點事務?

Redis Cluster 將 key 空間劃分為 16384 個 slot,每個 key 通過 CRC16(key) % 16384 映射到一個 slot,由某個主節(jié)點負責。

MULTI/EXEC 事務要求所有 key 必須屬于同一個 slot,否則直接拒絕:

> MULTI
> SET user:1001:name Alice
> SET order:2001:status paid
> EXEC
(error) CROSSSLOT Keys in request don't hash to the same slot

原因很簡單: 事務需要在單個節(jié)點上原子執(zhí)行,而跨 slot 意味著涉及多個物理節(jié)點 —— Redis 無法保證分布式事務的 ACID。

?? 注意:Pipeline 也不是事務!它只是網(wǎng)絡優(yōu)化,命令之間仍可能被其他客戶端插入。

二、方案一:Hash Tag + Lua 腳本(強一致性,推薦?。?/h2>

這是 唯一能在 Redis Cluster 中實現(xiàn)原子多 Key 操作的方式

? 核心思想:

  1. 利用 Hash Tag 規(guī)則,強制相關 key 落在同一 slot;
  2. Lua 腳本 在單節(jié)點內完成所有操作,天然原子。

?? 實施步驟

1. Key 設計:使用{}包裹聚合 ID

Redis 規(guī)定:只有 {} 內的內容參與 slot 計算。

# 所有與用戶 1001 相關的 key
user:{1001}:balance   → slot = CRC16("1001") % 16384
user:{1001}:orders    → slot = CRC16("1001") % 16384
user:{1001}:log       → slot = CRC16("1001") % 16384

? 這些 key 必然落在同一節(jié)點,可被原子操作。

2. 編寫 Lua 腳本(原子執(zhí)行)

-- 扣款 + 加訂單 + 記日志
local balance = tonumber(redis.call('GET', KEYS[1]) or 0)
if balance < tonumber(ARGV[2]) then
    return redis.error_reply('INSUFFICIENT_BALANCE')
end

redis.call('DECRBY', KEYS[1], ARGV[2])          -- 扣余額
redis.call('SADD', KEYS[2], ARGV[1])            -- 加訂單
redis.call('RPUSH', KEYS[3], 'Order created')   -- 記日志

return balance - tonumber(ARGV[2])

3. 客戶端調用(以 Jedis 為例)

String script = "..."; // 上述 Lua
List<String> keys = Arrays.asList(
    "user:{1001}:balance",
    "user:{1001}:orders",
    "user:{1001}:log"
);
List<String> args = Arrays.asList("order_2026", "100");

Object result = jedis.eval(script, keys, args);

? 優(yōu)勢

  • 強原子性:腳本執(zhí)行期間,其他命令無法插入;
  • 高性能:一次網(wǎng)絡往返;
  • 完全兼容 Cluster

?? 注意事項

  • 避免數(shù)據(jù)傾斜:不要用高頻 ID(如 user_id=1)作為 tag;
  • 僅適用于“聚合根”模型:所有 key 應屬于同一業(yè)務實體(用戶、訂單、會話等)。

?? 最佳實踐:在領域建模階段,就將需原子操作的數(shù)據(jù)歸為同一聚合,并用 {aggregate_id} 作為 Hash Tag。

三、方案二:應用層分步操作 + 補償機制(最終一致性)

當 key 無法歸到同一 slot(如跨用戶轉賬),且業(yè)務可接受最終一致性時,可采用 Saga 模式。

示例:用戶 A 轉賬給用戶 B

try {
    // 1. 凍結 A 的資金(帶 TTL 防死鎖)
    redis.setex("lock:A:100", 30, "100");
    
    // 2. 扣 A 余額
    redis.decrBy("user:A:balance", 100);
    
    // 3. 加 B 余額
    redis.incrBy("user:B:balance", 100);
    
    // 4. 清除鎖
    redis.del("lock:A:100");
} catch (Exception e) {
    // 補償:回滾已執(zhí)行的操作
    if (A余額已扣) redis.incrBy("user:A:balance", 100);
    if (B余額已加) redis.decrBy("user:B:balance", 100);
    redis.del("lock:A:100");
}

? 適用場景

  • 跨聚合根操作(如 A→B 轉賬);
  • 有明確補償邏輯(如退款、撤回);
  • 可容忍短暫不一致。

? 劣勢

  • 實現(xiàn)復雜(需冪等、重試、監(jiān)控);
  • 無法保證強一致性。

四、方案三:異步隊列 + 冪等消費(高吞吐場景)

將多 Key 操作拆解為消息,交由 Kafka/RocketMQ 等可靠隊列處理:

graph LR
A[發(fā)起操作] --> B[發(fā)消息到 MQ]
B --> C[消費者1: 更新 key1]
C --> D[消費者2: 更新 key2]
  • 消費者需實現(xiàn)冪等(如用 SET key value NX 防重);
  • 適合非實時場景:積分發(fā)放、通知推送、日志同步等。

五、不推薦方案:單獨部署非集群 Redis

  • 為事務單獨維護一套 standalone Redis;
  • 破壞架構統(tǒng)一性,增加運維成本;
  • 喪失 Cluster 的高可用與擴展能力
  • 僅適用于極小規(guī)模、臨時過渡場景。

?? 總結:如何選擇?

場景推薦方案
強一致性 + 多 Key 同業(yè)務實體? Hash Tag + Lua 腳本
跨實體 Key + 可接受最終一致? Saga 補償 或 異步隊列
簡單批量讀寫(同 Key)? MSET / MGET(內置原子命令)

?? 核心原則: 在 Redis Cluster 中,*不要對抗 slot 機制,而要順應它*。 通過合理的數(shù)據(jù)建模(聚合根 + Hash Tag),你可以在享受 Cluster 高可用的同時,實現(xiàn)強一致的事務操作。

到此這篇關于Redis Cluster 實現(xiàn)多key事務操作的文章就介紹到這了,更多相關Redis Cluster 多key事務操作內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Redis?異常?read?error?on?connection?的解決方案

    Redis?異常?read?error?on?connection?的解決方案

    這篇文章主要介紹了Redis異常read?error?on?connection的解決方案,文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,感興趣的小伙伴可以參考一下
    2022-08-08
  • Redis主從復制的實現(xiàn)示例

    Redis主從復制的實現(xiàn)示例

    Redis主從復制實現(xiàn)多機備份,本文就來介紹一下Redis主從復制的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-11-11
  • Redis讀寫分離搭建的完整步驟

    Redis讀寫分離搭建的完整步驟

    為滿足讀多寫少的業(yè)務場景.最大化節(jié)約用戶成本.云數(shù)據(jù)庫Redis版推出了讀寫分離規(guī)格,為用戶提供透明、高可用、高性能、高靈活的讀寫分離服務,這篇文章主要給大家介紹了關于Redis讀寫分離搭建的相關資料,需要的朋友可以參考下
    2021-09-09
  • Spring?Boot?緩存?與?Redis問題小結

    Spring?Boot?緩存?與?Redis問題小結

    本文總結SpringBoot緩存方案,對比Redis與EnCache優(yōu)劣,指出Redis支持集群但效率較低,EnCache速度快但不支持分布式,SpringBoot默認使用ConcurrentHashMapManager,本文給大家介紹Spring?Boot緩存與Redis問題小結,感興趣的朋友一起看看吧
    2025-07-07
  • Redis過期Key刪除策略和內存淘汰策略的實現(xiàn)

    Redis過期Key刪除策略和內存淘汰策略的實現(xiàn)

    當內存使用達到上限,就無法存儲更多數(shù)據(jù)了,為了解決這個問題,Redis內部會有兩套內存回收的策略,過期Key刪除策略和內存淘汰策略,本文就來詳細的介紹一下這兩種方法,感興趣的可以了解一下
    2024-02-02
  • redis實現(xiàn)分布式的方法總結

    redis實現(xiàn)分布式的方法總結

    在本篇文章中小編給大家整理了關于redis分布式怎么做的具體內容以及知識點總結,有興趣的朋友們參考下。
    2019-06-06
  • Redis分布式鎖防止緩存擊穿的實現(xiàn)

    Redis分布式鎖防止緩存擊穿的實現(xiàn)

    本文主要介紹了Redis分布式鎖防止緩存擊穿的實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • Redis 數(shù)據(jù)類型的詳解

    Redis 數(shù)據(jù)類型的詳解

    這篇文章主要介紹了Redis 數(shù)據(jù)類型的詳解的相關資料,支持五種數(shù)據(jù)類型,字符串,哈希,列表,集合及zset,需要的朋友可以參考下
    2017-08-08
  • Docker快速部署Redis完整步驟流程(含持久化配置)

    Docker快速部署Redis完整步驟流程(含持久化配置)

    Redis集群是一種分布式數(shù)據(jù)庫解決方案,旨在提供高性能、高可用性、可擴展性的數(shù)據(jù)存儲服務,這篇文章主要介紹了Docker快速部署Redis(含持久化配置)的相關資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2025-11-11
  • Redis中scan命令的深入講解

    Redis中scan命令的深入講解

    這篇文章主要給大家介紹了關于Redis中scan命令的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用redis具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-10-10

最新評論

兴国县| 赣州市| 遂川县| 昭通市| 边坝县| 岑溪市| 台安县| 固原市| 平遥县| 汕头市| 故城县| 那坡县| 金湖县| 陇西县| 克山县| 祥云县| 九江县| 富顺县| 齐齐哈尔市| 赤峰市| 桃源县| 瑞丽市| 新竹市| 明溪县| 南乐县| 郸城县| 江油市| 冕宁县| 鹤庆县| 班玛县| 万全县| 广灵县| 句容市| 长兴县| 太湖县| 汉川市| 栖霞市| 平顶山市| 和顺县| 镇江市| 扎赉特旗|