vocus logo

方格子 vocus

閒聊軟體設計:分散式鎖

更新 發佈閱讀 7 分鐘
圖片來源:ChatGPT 生成

圖片來源:ChatGPT 生成

這次開發系統的過程中,大多數都是使用樂觀鎖來避免 race condition 的情況 (參閱 閒談軟體設計:樂觀鎖 ),但樂觀鎖的使用有前提條件:要有資料本身能做為鎖的載體。但不是所有的情境都能滿足這個條件。

這次的情境比較特別,一邊使用者可能在一個範圍內批次新增或修改多筆資源 S,而另一邊背景的 Worker 則會讀取一個範圍內的資源 S 作為運算的輸入,此時會希望當批次寫入仍在進行中時,Worker 要等到批次寫入完成再讀取,不然可能會用到錯的資料進行運算。反之,Worker 在讀取資料時,會希望批次處理等到 Worker 處理完後再寫入。

樂觀鎖和序列交易

在這個情境下,無法找到合適的樂觀鎖載體,因為 Worker 只讀取資料,沒有更新任何資訊,也就無法比較版本是否有更動過,更何況,批次的操作中有新增資源的情況,這讓 Worker 無法提前知道資料的 ID 來鎖定。因此,這個情境下樂觀鎖無法上派上用場。

那 PostgreSQL 的 Serializable Isolation Level 的交易管理有機會解決這問題嗎?有機會,但處理方式需要調整,首先,讀寫兩端都要開啟 Serializable Isolation Level 的交易,接著,讀寫兩端都需要處理重試,因為PostgreSQL 在 Serializable Isolation Level 下並不會強制讓交易排隊,而是允許交易先平行執行,並在 commit 時檢查是否存在 serialization anomaly。如果發現衝突,就會中止其中一個交易並要求重試。

那如果是鎖整張 table 呢?可以,但這會讓系統的效能大幅降低,如果沒有特殊的需求,通常不會使用。

在一般的情況下,直接把錯誤傳回前端,讓使用者重試是可接受的選項,但由於這回批次寫入的資料如果讓使用者重試,體驗恐怕不會太好,若不想重試似乎要請出悲觀鎖。

分散式鎖

在過去學習作業系統或是平行處理時,當要處理 race condition,通常都會用 mutex lock 確保只有一個程序進入 critical section,其他程序要等到先進入 critical section 完成後才能進入。如果是單程序的 Java 應用程式,用語言內建的 synchronized 關鍵字,就能簡單地實現多執行緒的 mutex lock。

但在雲端環境呢?就需要分散式鎖,一般來說,很多人會想到用 Redis,確實在一開始也想過直接用 Redis,畢竟目前的系統裡,也有佈署 Redis,但後來想想,當時佈署 Redis 是為了使用 Redis Pub/Sub,所以用 k8s 簡單地佈署了只有一個 instance 的 Redis,唯一的 instance 如果重啟,那 lock 就失效了,似乎會是個風險。

那有其他選擇嗎?花了一點時間研究後,發現了一個有趣而且不用佈署任何新機器的解:PostgreSQL Advisory Lock。

PostgreSQL Advisory Lock

PostgreSQL Advisory Lock 是 PostgreSQL 內建的一種鎖,使用方式很簡單,只需要在 transaction 內執行 SELECT pg_advisory_xact_lock(key)key 是一個 64 位元整數,由應用層決定 key,只要是相同的 key,PostgreSQL 就會確保未取得鎖的程序等待已取得鎖的程序結束。

必須在 transaction 內使用,而且會隨著 transaction 結束 (commit 或 rollback),自動釋放 lock,很簡單就能避免忘記釋放 lock 的情況,相當方便,之前竟然不知道有這東西,太可惜了。

馬上將這個技術封裝並提供一個類似 Java synchronized 的抽象,在原有的 Sql2oTransactionManager 加入 synchronize 函式,第一個參數是 key,第二個參數便是取得鎖後要執行的內容:

  • runInSession 確保作為參數的 lambda 會在一個 transaction 執行,不管那個 transaction 是既有的或是新建立的
  • obtainLock 則是將 key 透過 hashtextextended 雜湊程 64 位元的整數。
  • 在取得 lock 後才執行 runnable

整個實作相當直覺簡單。

有了這個函式後,在 Worker 就可以將初始化的動作包進第二個參數,在批次更新的部分,也將寫入的部分包進第二個參數,只要 key 相同,就會確保只會有一個程序執行,另一個程序會等待先執行的程序結束後才執行。

到此,批次寫入和 Worker 讀取能按照順序執行了,也替系統添加了一個分散式鎖的實作,之後有需要時,能直接使用。

Advisory Lock 也是有限制的,要進入 critical section 的程式都要先試著取得鎖,這和多數 mutex lock 的使用是一樣的。另外,key 的範圍要小心,如果 key 鎖定的範圍太大,也會讓系統效能大幅下降,要盡量避免。

另外,這邊使用 pg_advisory_xact_lock 而非 pg_advisory_lock 就是讓 lock 的生命週期與 transaction 綁定,並免忘記釋放 lock 的問題,若真的要使用 pg_advisory_lock,請切記做好 lock 的生命週期管理。

最後,如果是不想等待,可以使用 pg_try_advisory_xact_lock,若取得鎖失敗後馬上返回 false,由應用層決定該如何處理。

小結

在需要「一組操作完成後另一組操作才能開始」的情境下,樂觀鎖或 Serializable Isolation Level 交易不一定能滿足這需求,特別是當操作涉及範圍查詢或可能新增未知資料時。若既有系統有 PostgreSQL 的情況下,可以透過 PostgreSQL 提供的Advisory Lock,加上能用 key 決定鎖的顆粒度,在不引入額外基礎設施的情況下,是相當方便的一個悲觀鎖選項。

留言
avatar-img
Spirit 異想世界
58會員
122內容數
這是從 Medium 開始的一個專題,主要是想用輕鬆閒談的方式,分享這幾年軟體開發的心得,原本比較侷限於軟體架構,但這幾年的文章不僅限於架構,也聊不少流程相關的心得,所以趁換平台,順勢換成閒談軟體設計。
Spirit 異想世界的其他內容
2026/03/01
本文探討在軟體開發過程中,將原本並非 Aggregate 的設計,逐步重構成具有 Aggregate 精神的實作。作者分享了一個實際案例,說明如何在一致性問題和更複雜的協同作業需求出現時,透過引入樂觀鎖,並逐步思考 Aggregate 的設計原則,最終找到一個在滿足系統需求下的特殊解決方案。
Thumbnail
2026/03/01
本文探討在軟體開發過程中,將原本並非 Aggregate 的設計,逐步重構成具有 Aggregate 精神的實作。作者分享了一個實際案例,說明如何在一致性問題和更複雜的協同作業需求出現時,透過引入樂觀鎖,並逐步思考 Aggregate 的設計原則,最終找到一個在滿足系統需求下的特殊解決方案。
Thumbnail
2026/02/21
作者分享了 B2B 產品在迭代開發過程中所遇到的挑戰,特別是在追求功能完整性的過程中,如何避免設計變得過於複雜,進而影響使用者體驗。文中探討了從使用者回饋、市場變化到團隊內部認知的變化,並提出了在產品開發中「踩煞車」的重要性,以確保產品能真正符合使用者需求,而非徒增複雜度。
Thumbnail
2026/02/21
作者分享了 B2B 產品在迭代開發過程中所遇到的挑戰,特別是在追求功能完整性的過程中,如何避免設計變得過於複雜,進而影響使用者體驗。文中探討了從使用者回饋、市場變化到團隊內部認知的變化,並提出了在產品開發中「踩煞車」的重要性,以確保產品能真正符合使用者需求,而非徒增複雜度。
Thumbnail
2026/02/14
分享在不同公司期間,與客戶進行實地拜訪的豐富經,這些故事不僅是單純的客戶訪談紀錄,更揭示了產品開發過程中可能遇到的挑戰、客戶的真實痛點,以及從數據以外的角度全面理解市場需求的洞見。文章強調了工程師實地訪談的重要性,並鼓勵讀者若有機會應多加嘗試,從中獲取寶貴的經驗與啟發。
Thumbnail
2026/02/14
分享在不同公司期間,與客戶進行實地拜訪的豐富經,這些故事不僅是單純的客戶訪談紀錄,更揭示了產品開發過程中可能遇到的挑戰、客戶的真實痛點,以及從數據以外的角度全面理解市場需求的洞見。文章強調了工程師實地訪談的重要性,並鼓勵讀者若有機會應多加嘗試,從中獲取寶貴的經驗與啟發。
Thumbnail
看更多
你可能也想看
Thumbnail
《轉轉生》(Re:INCARNATION)為奈及利亞編舞家庫德斯.奧尼奎庫與 Q 舞團創作的當代舞蹈作品,結合拉各斯街頭節奏、Afrobeat/Afrobeats、以及約魯巴宇宙觀的非線性時間,建構出關於輪迴的「誕生—死亡—重生」儀式結構。本文將從約魯巴哲學概念出發,解析其去殖民的身體政治。
Thumbnail
《轉轉生》(Re:INCARNATION)為奈及利亞編舞家庫德斯.奧尼奎庫與 Q 舞團創作的當代舞蹈作品,結合拉各斯街頭節奏、Afrobeat/Afrobeats、以及約魯巴宇宙觀的非線性時間,建構出關於輪迴的「誕生—死亡—重生」儀式結構。本文將從約魯巴哲學概念出發,解析其去殖民的身體政治。
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
EP27 精華重點: 1.時間管理的觀念: 將時間視為資產,讓時間發揮最大價值 設定明確的短期和長期目標 2.制定可行計畫: 將大目標分割成可執行的小計畫和里程碑 給自己合理的獎勵作為動力 3.優先排序處理事務: 根據重要性和緊急程度劃分為四個象限 先處理緊急的事物,延後的部分要補
Thumbnail
EP27 精華重點: 1.時間管理的觀念: 將時間視為資產,讓時間發揮最大價值 設定明確的短期和長期目標 2.制定可行計畫: 將大目標分割成可執行的小計畫和里程碑 給自己合理的獎勵作為動力 3.優先排序處理事務: 根據重要性和緊急程度劃分為四個象限 先處理緊急的事物,延後的部分要補
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
在這個數位時代,幾乎人人有手機有電腦,每天都會接觸網站或 APP。你打開手機滑臉書、用foodpanda 網路訂餐、上網查資料,甚至於近兩年快速登上科技時代的最佳主角:AI ,背後都是由一群默默耕耘的軟體工程師在支撐。 今天,就讓我們從基礎的網站架構談起,一步步認識工程師的世界。
Thumbnail
在這個數位時代,幾乎人人有手機有電腦,每天都會接觸網站或 APP。你打開手機滑臉書、用foodpanda 網路訂餐、上網查資料,甚至於近兩年快速登上科技時代的最佳主角:AI ,背後都是由一群默默耕耘的軟體工程師在支撐。 今天,就讓我們從基礎的網站架構談起,一步步認識工程師的世界。
Thumbnail
在紡織業做廠長二十多年,習慣了各種挑戰:產線延誤、設備故障、排程變動、來料不齊……但有一個新挑戰,這兩年變得愈來愈明顯,卻也最難處理:碳排放管理與能源效率透明化。這不是什麼新名詞,大家都聽過。問題是:知道歸知道,要做怎麼做?
Thumbnail
在紡織業做廠長二十多年,習慣了各種挑戰:產線延誤、設備故障、排程變動、來料不齊……但有一個新挑戰,這兩年變得愈來愈明顯,卻也最難處理:碳排放管理與能源效率透明化。這不是什麼新名詞,大家都聽過。問題是:知道歸知道,要做怎麼做?
Thumbnail
將兩個JPG文件合併為一個是一項實用的技能,可用於創建拼貼、文件或演示文稿。本文探討了多種有效的方法來達成這一目標,包括使用在線工具、桌面應用程序以及操作系統內建的工具。每種方法都有其優缺點,適用於不同的需求和資源。無論您是尋求快速解決方案,還是需要高級編輯功能,這份指南將幫助您找到適合的選項。
Thumbnail
將兩個JPG文件合併為一個是一項實用的技能,可用於創建拼貼、文件或演示文稿。本文探討了多種有效的方法來達成這一目標,包括使用在線工具、桌面應用程序以及操作系統內建的工具。每種方法都有其優缺點,適用於不同的需求和資源。無論您是尋求快速解決方案,還是需要高級編輯功能,這份指南將幫助您找到適合的選項。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News