Redis(2):Redis + Lua為什么可以實現原子性

Redis 作為一款高性能的鍵值對存儲數據庫,與 Lua 腳本相結合,為實現原子性操作提供了強大的解決方案本文將深入探討 Redis + Lua 實現原子性的相關知識

原子性概念的厘清

在探討 Redis + Lua 的原子性之前,我們需要明確原子性的概念。通常我們提及的原子性,多是指關系型數據庫(如 MySQL)ACID 特性中的 Atomicity(原子性)。在 ACID 語境下,原子性要求事務中的所有操作要么全部成功執行,要么全部失敗回滾。

以常見的銀行轉賬為例,當賬戶 A 向賬戶 B 轉賬 100 元時,原子性確保賬戶 A 減去 100 元的同時,賬戶 B 必須增加 100 元。若賬戶 A 減少了 100 元,但賬戶 B 未增加 100 元,該操作就不具備原子性,需要回滾,將賬戶 A 減少的 100 元加回去。這一概念是我們理解數據操作完整性的基礎。

Lua 原子性在 Redis 中的體現

Lua 本身只是一種腳本語言,它并未直接提供原子性支持,通常被嵌入到像 Redis 這樣的宿主程序中運行。在 Redis 環境里,執行 Lua 腳本的原子性意味著整個 Lua 腳本在執行期間,不會被其他客戶端的命令打斷。這就保證了在執行 Lua 腳本時,Redis 會將其視為一個不可分割的整體來處理,不會受到其他并發操作的干擾。

Redis 的事務機制

Redis 的事務由 MULTI/EXEC 兩個核心命令完成,同時 WATCH/DISCARD 兩個命令為其增添了 CAS(Compare - And - Swap)樂觀鎖機制。不過需要注意的是,Redis 的事務與關系型數據庫(如 MySQL)遵循的 ACID 事務不同,它并不支持回滾。

Redis 執行 Lua 的方式

Redis 通過原生命令(如 EVAL/EVALSHA 命令)來執行 Lua 腳本。在編寫 Lua 腳本時,開發者需要特別留意 redis.call () 和 redis.pcall () 這兩個命令的區別。

  • redis.call():用于執行 Redis 的命令。一旦命令執行出錯,它會阻斷整個腳本的執行,并將錯誤信息返回給客戶端。這種特性適合在需要嚴格保證命令執行成功的場景中使用,若某個關鍵命令失敗,整個腳本不應繼續執行。
  • redis.pcall():同樣用于執行 Redis 的命令,但當命令執行出錯時,它不會阻斷腳本的執行,而是在內部捕獲錯誤,并繼續執行后續的命令。這種方式適用于一些對部分命令失敗有一定容忍度,希望腳本盡可能完整執行的場景。

Redis 部署方式對事務結果的影響

Redis 的部署方式在一定程度上影響著 Lua 腳本執行的原子性結果。

  • 單機部署:無論 Lua 腳本中操作的 key 是否為同一個,單機部署的 Redis 都能保證原子性。因為在單機環境下,所有操作都是在同一個進程中順序執行,不存在并發干擾的問題。
  • 主從部署:Redis 的主從復制旨在將主節點的數據同步到從節點,以維持數據一致性。由于所有寫操作都在主節點進行,所以無論 Lua 腳本操作的 key 是否相同,都能保證原子性。主節點按順序執行 Lua 腳本,從節點則通過復制機制保持數據同步。
  • Cluster 部署:情況相對復雜。如果 Lua 腳本操作的是同一個 key,能保證原子性;但如果操作的 key 不同,這些 key 可能被 hash 到不同的 slot,也可能 hash 到相同的 slot,因此不一定能保證原子性。所以,在 Cluster 集群部署環境下使用 Lua 腳本時,務必確保 Lua 腳本操作的是同一個 key,以保障原子性。

為何選擇用 Lua 實現原子性

在 Redis 事務中,事務隊列中的所有命令需在 EXEC 命令執行時才會被執行。這就導致對于多個命令之間存在依賴關系(如后面的命令需要依賴上一個命令結果)的場景,Redis 事務顯得力不從心。

Lua 腳本由于其能夠順序執行一系列命令,并且在執行過程中不會被其他客戶端命令打斷,更適合處理這種復雜場景,從而彌補了 Redis 事務的不足。

需要重點關注的是,ACID 中的原子性強調命令要么全部執行,要么全部不執行;而 Redis 執行 Lua 腳本的原子性是指 Lua 腳本會當作一個整體被執行且不被其他事務打斷,但 Lua 腳本里面的命令并不能保證 “要么全部執行,要么全部不執行”。

通過深入了解 Redis + Lua 實現原子性的原理、Redis 的事務機制以及不同部署方式的影響,可以更加精準地運用這一技術,為分布式系統開發提供堅實的數據操作保障。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/80556.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/80556.shtml
英文地址,請注明出處:http://en.pswp.cn/web/80556.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

科普:極簡的AI亂戰江湖

本文無圖。 大模型 ?2022年2月,?文生圖應用的鼻祖Midjourney上線。 ?2022年8月,?開源版的Midjourney,也就是Stable Diffusion上線。 2022年11月30日?,OpenAI正式發布ChatGPT-3.5。 此后,不斷有【大模型】面世&…

CSS- 4.5 css + div 布局 簡易網易云音樂 官網布置實例

本系列可作為前端學習系列的筆記,代碼的運行環境是在HBuilder中,小編會將代碼復制下來,大家復制下來就可以練習了,方便大家學習。 HTML系列文章 已經收錄在前端專欄,有需要的寶寶們可以點擊前端專欄查看! 點…

【滑動窗口】LeetCode 1004題解 | 最大連續1的個數 Ⅲ

最大連續1的個數 Ⅲ 一、題目鏈接二、題目三、題目解析四、算法原理解法一:暴力枚舉 zero計數器解法二:滑動窗口 五、編寫代碼六、時空復雜度 一、題目鏈接 最大連續1的個數 Ⅲ 二、題目 三、題目解析 注意題目中說的是最多k次,在一個數組…

PyTorch音頻處理技術及應用研究:從特征提取到相似度分析

文章目錄 音頻處理技術及應用音頻處理技術音視頻摘要技術音頻識別及應用 梅爾頻率倒譜系數音頻特征爾頻率倒譜系數簡介及參數提取過程音頻處理快速傅里葉變換(FFT)能量譜處理離散余弦轉換 練習案例:音頻建模加載音頻數據源波形變換的類型繪制波形頻譜圖波形Mu-Law 編…

鴻蒙OSUniApp 實現的語音輸入與語音識別功能#三方框架 #Uniapp

UniApp 實現的語音輸入與語音識別功能 最近在開發跨平臺應用時,客戶要求添加語音輸入功能以提升用戶體驗。經過一番調研和實踐,我成功在UniApp項目中實現了語音輸入與識別功能,現將過程和方法分享出來,希望對有類似需求的開發者有…

2025年衛星遙感行業最新發展趨勢深度分析

一、國內發展趨勢:政策引領與技術突破雙輪驅動 (一)政策體系持續完善,頂層設計深化行業發展 國家級戰略與標準體系構建 中國政府將衛星遙感產業納入“十四五”規劃核心戰略,明確構建“通導遙”一體化空間基礎設施。20…

SIP協議棧--osip源碼梳理

文章目錄 osiposip主體結構體code main函數 狀態機轉化結構體code狀態轉換 sip事務結構體code osip_dialog結構體code 創建并發送200 OK響應 osip_message結構體code osip_eventcode 打印接收到的SIP消息 osip OSIP(Open Source Implementation of SIP)…

Linux之Yum源與Nginx服務篇

1.Yum源知識理論總結概括 Yum源概述 Yum 源 即軟件倉庫的標識,里面承載著軟件包集合 Yum源組成 包含模塊 【OS】、【everything】、【EPOL】、【debuginfo】、【source】、【update-source】 【os】:簡稱operator system 它內部包含操作系統的核心組件&#x…

從單體架構到微服務:架構演進之路

引言:當“大貨車”遇上“集裝箱運輸” 在軟件開發領域,單體架構曾像一輛載滿貨物的大貨車,將所有功能打包在一個應用中。但隨著業務復雜度飆升,這輛“大貨車”逐漸陷入泥潭:啟動慢如蝸牛、故障波及全局、升級如履薄冰……

AM32電調學習解讀九:ESC上電啟動關閉全流程波形分析

這是第九篇,前面的文章把各個模塊的實現都介紹了一輪,本章是從運行的角度結合波形圖,把整個流程走一遍。 先看下一運行的配置,我把一些配置關閉了,這樣跑起來會好分析一些,不同配置跑起來效果會有差異。使用…

全球寵物經濟新周期下的亞馬遜跨境采購策略革新——寵物用品賽道成本優化三維路徑

在全球"孤獨經濟"與"銀發經濟"雙輪驅動下,寵物用品市場正經歷結構性增長。Euromonitor數據顯示,2023年全球市場規模突破1520億美元,其中中國供應鏈貢獻度達38%,跨境電商出口增速連續三年超25%。在亞馬遜流量紅…

reshape/view/permute的原理

在pytorch中,Tensor的存儲是行主序的,也就是意味著最后一個維度的元素的存儲時連續的,reshape和view并不改變元素存儲的內存,僅僅改變訪問的間隔,下面舉例說明; 比如一個23的Tensor在內存中的存儲是連續的&…

upload-labs靶場通關詳解:第11關

一、分析源代碼 $is_upload false; $msg null; if (isset($_POST[submit])) {if (file_exists(UPLOAD_PATH)) {$deny_ext array("php","php5","php4","php3","php2","html","htm","phtml"…

L1-7 最短字母串【保姆級詳細講解】

請你設計一個程序,該程序接受起始字母和目標字母作為輸入,通過在字母表中向前或向后移動來計算兩個給定字母之間的最短路徑。然后,程序會沿著最短路徑打印出從起始字母到目標字母的所有字母。例如,如果輸入“c”和“k”作為起始字…

項目QT+ffmpeg+rtsp(三)——延遲巨低的項目+雙屏顯示

文章目錄 前言雙屏顯示widget.cppwidget.h前言 對于復現情況,分為兩種情況 第一種,對于我而言,是直接解壓后,就能直接運行了 第二種,對于師兄而言,需要你構建debug后,會產生這個文件夾,執行的時候,地址應該在這,我猜的,這里面沒有dll,exe程序就找不到dll這些庫,你…

ansible進階06

復雜的循環結構 循環基礎 [studentworktest myansible]$ cat users.yml --- - name: create usershosts: serveratasks:- name: create some usersuser:name: "{{item}}"password: "{{123456|password_hash(sha512)}}"state: presentloop:- zhangsan- li…

Go 模塊版本管理

Go 模塊版本管理指南 1、創建帶注釋的 Git 標簽 基本命令 # 創建帶注釋的標簽 git tag -a v1.0.0 -m "Release version 1.0.0 - initial stable release" -a:創建帶注釋的標簽 -m:添加標簽注釋信息 # 推送標簽到遠程倉庫 git push origin v…

Java—— IO流 第一期

什么是IO流 存儲和讀取數據的解決方案 I:input O:output 流:像水流一樣傳輸數據 IO流的作用 用于讀寫數據(本地文件,網絡) IO流的分類 按照流向分類 輸出流:程序 --> 文件 輸入流:文件 --> 程序 按照…

物聯網安全技術的最新進展與挑戰

隨著物聯網(IoT)技術的飛速發展,越來越多的設備被連接到互聯網,從智能家居設備到工業控制系統,物聯網正在深刻改變我們的生活和生產方式。然而,物聯網的安全問題也日益凸顯,成為制約其發展的關鍵…

【深度學習基礎】損失函數與優化算法詳解:從理論到實踐

【深度學習基礎】損失函數與優化算法詳解:從理論到實踐 一、引言 1. 損失函數與優化算法在深度學習中的核心作用 在深度學習中,模型訓練的本質是通過不斷調整參數,使模型輸出盡可能接近真實值。這一過程的核心驅動力是損失函數(…