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

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

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

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

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

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

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

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

Redis Cluster 將 key 空間劃分為 16384 個(gè) slot,每個(gè) key 通過(guò) CRC16(key) % 16384 映射到一個(gè) slot,由某個(gè)主節(jié)點(diǎn)負(fù)責(zé)。

MULTI/EXEC 事務(wù)要求所有 key 必須屬于同一個(gè) 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ǎn)單: 事務(wù)需要在單個(gè)節(jié)點(diǎn)上原子執(zhí)行,而跨 slot 意味著涉及多個(gè)物理節(jié)點(diǎn) —— Redis 無(wú)法保證分布式事務(wù)的 ACID。

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

二、方案一:Hash Tag + Lua 腳本(強(qiáng)一致性,推薦!)

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

? 核心思想:

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

?? 實(shí)施步驟

1. Key 設(shè)計(jì):使用{}包裹聚合 ID

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

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

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

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. 客戶端調(diào)用(以 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)勢(shì)

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

?? 注意事項(xiàng)

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

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

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

當(dāng) key 無(wú)法歸到同一 slot(如跨用戶轉(zhuǎn)賬),且業(yè)務(wù)可接受最終一致性時(shí),可采用 Saga 模式。

示例:用戶 A 轉(zhuǎn)賬給用戶 B

try {
    // 1. 凍結(jié) 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) {
    // 補(bǔ)償:回滾已執(zhí)行的操作
    if (A余額已扣) redis.incrBy("user:A:balance", 100);
    if (B余額已加) redis.decrBy("user:B:balance", 100);
    redis.del("lock:A:100");
}

? 適用場(chǎng)景

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

? 劣勢(shì)

  • 實(shí)現(xiàn)復(fù)雜(需冪等、重試、監(jiān)控);
  • 無(wú)法保證強(qiáng)一致性。

四、方案三:異步隊(duì)列 + 冪等消費(fèi)(高吞吐場(chǎng)景)

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

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

五、不推薦方案:?jiǎn)为?dú)部署非集群 Redis

  • 為事務(wù)單獨(dú)維護(hù)一套 standalone Redis;
  • 破壞架構(gòu)統(tǒng)一性,增加運(yùn)維成本;
  • 喪失 Cluster 的高可用與擴(kuò)展能力
  • 僅適用于極小規(guī)模、臨時(shí)過(guò)渡場(chǎng)景。

?? 總結(jié):如何選擇?

場(chǎng)景推薦方案
強(qiáng)一致性 + 多 Key 同業(yè)務(wù)實(shí)體? Hash Tag + Lua 腳本
跨實(shí)體 Key + 可接受最終一致? Saga 補(bǔ)償 或 異步隊(duì)列
簡(jiǎn)單批量讀寫(同 Key)? MSET / MGET(內(nèi)置原子命令)

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

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

相關(guān)文章

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

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

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

    Redis主從復(fù)制的實(shí)現(xiàn)示例

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

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

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

    Spring?Boot?緩存?與?Redis問(wèn)題小結(jié)

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

    Redis過(guò)期Key刪除策略和內(nèi)存淘汰策略的實(shí)現(xiàn)

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

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

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

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

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

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

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

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

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

    Redis中scan命令的深入講解

    這篇文章主要給大家介紹了關(guān)于Redis中scan命令的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用redis具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-10-10

最新評(píng)論

和林格尔县| 新宁县| 淳安县| 靖江市| 托里县| 双鸭山市| 望城县| 木里| 开阳县| 云梦县| 庆元县| 垦利县| 庆安县| 咸宁市| 巢湖市| 民权县| 修武县| 丽江市| 绍兴县| 句容市| 台州市| 岱山县| 余庆县| 太原市| 河源市| 香港| 龙江县| 广平县| 文山县| 韶关市| 绥化市| 彭州市| 锡林浩特市| 普陀区| 洛阳市| 景东| 新疆| 手机| 安仁县| 徐州市| 平乐县|