這次會分享關於「鎖」的主題除了工作上遇到這樣的情境之外,也發現到其實軟體技術大部分跟我們生活情境息息相關,覺得非常有趣,因此嘗試將艱澀難懂的技術化為淺顯易懂的圖文知識來幫助大家快速理解,除了應用在工作上,或許對於生活過程中遇到的一些問題也能得到一些啟發。
此篇章主要著重於觀念的分享,並不會深入探討實作的細節,相信只要觀念通了,對於技術實作的道路上一定會非常順暢,好吧!廢話不多說,趕快來介紹一下樂觀鎖與悲觀鎖的基本觀念。
情境
軟體開發的過程中想必我們開會過程中常常會聽到以下的關鍵字句:
- 併發問題就應該用樂觀鎖啊!
- 最安全的併發正確性應該用悲觀鎖吧!
- Scale Out的服務怎麼保證正確呢?
- 啊!雙十節要到了,如何確保客戶的訂單與商品數量是正確的又能兼顧效能?
以上的問題都圍繞在效能、正確性, 而其中最關鍵的就是「鎖」, 雖然「鎖」難免會造成效能的下降, 但這點不足之處對於現階段的群集架構之下, 已經能夠透過橫向擴展的方式進行補足, 因此「鎖」的技術值得我們好好認識一番!
悲觀鎖(Pessimistic Lock) 😭
就如同字面上的意思, 對任何的事物都很悲觀, 而這種情緒之下的處理方式就是盡量鎖住整個資源, 保證整體一致性之後再釋放, 雖然安全但效能下降程度非常的高。
以生活化的例子來說, 當我們要去餐廳慶祝一下的時候, 通常就兩種作法, 不是預訂就是現場候位, 那麼較悲觀的人可能會事先安排, 因此會進行訂位的動作, 那麼一旦訂位之後, 該位置到某個時段就等於是被「鎖」上, 直到我們用完餐之後才釋放, 這樣的情境下確保我們能正確的慶祝用餐, 但對於資源使用上來說就相對耗費了, 尤其當我們發生非預期狀況之下無法到場時, 原本餐廳能夠服務到更多客人, 卻因為我們的「鎖」而導致服務客人的量減少了, 餐廳也少賺了一些客人的消費金額。
優點
- 保證「鎖」上的資源能夠完整處理操作後再釋放。
缺點
- 「鎖」的粒度太大導致資源的浪費。
樂觀鎖(Optimistic Lock) 😀
先做就對了, 有衝突再解決…。
一樣以餐廳為例, 這次就變成現場候位的狀況, 不採取預訂方式, 有位置再吃, 大不了下個時段再來, 這樣對於餐廳端來說, 資源閒置的狀況減少了, 每一桌吃完就服務下一桌, 以軟體技術語言的角度來說就是,先提交若「⚔️衝突」則下次提交。
上面有三個關鍵字分別是「先提交」、「衝突」、「下次提交」, 很暴力簡單的作法卻很有效, 最關鍵的就是「⚔️衝突」的偵測, 如何識別「⚔️衝突」就是相當重要的一環了。
其實偵測「⚔️衝突」的原理非常簡單, 通常最簡易的作法就是壓上一個版本號, 假若針對目標進行異動時, 發現版本號已經被異動了, 就視為「⚔️衝突」, 再更新資料到記憶體並重新進行一次操作即可。
優點
- 資源相對悲觀鎖能夠較有效的被善用。
缺點
- 併發量越高, 可能發生衝突的機率越高。
- 通常是人為實現的, 因此使用時要非常小心控制的欄位。
結語
「🔑 鎖」的概念非常的有趣, 結合到現實面也能夠藉此改善流程及效率, 大幅減少資源的浪費, 降低成本, 在雲端時代中, 軟體也漸趨複雜, 隨著無國界的發展, 一套優質的軟體勢必會服務來自世界各地的使用者, 然而當使用量倍增時, 也勢必面臨到橫向擴展與平行處理的技術, 但在這之間如何維持正確性與兼顧效能, 就取決於我們怎麼使用這把「🔑 鎖」囉。
除非有非常強烈的一致性需求才使用悲觀鎖, 否則一般的情境下樂觀鎖基本上都能夠通用。
每一項技術的背後都有其優缺點, 並非單一項就能通吃, 因此若我們能夠多認識一些技術背後的原理與優缺點, 相信遇到狀況時就能夠隨時因應變化, 端出最適用的技術應對, 如此一來才能夠打造出穩定可靠的系統軟體。
喜歡撰寫文章的你,不妨來了解一下:
歡迎加入一起練習寫作,賺取知識,累積財富!