日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

DDD實戰:應對并發挑戰,五個技巧讓你輕松應對

來源: 責編: 時間:2023-10-23 17:05:32 315觀看
導讀在業務開發中,事務一致性核心在于“原子性”,則并發管理的核心在于“隔離性”。原子性:一個業務操作被視為一個不可分割的邏輯單元,要么全部執行成功,要么全部失敗回滾;隔離性:并發業務操作之間要相互隔離,不能互相干擾;1. 無

在業務開發中,事務一致性核心在于“原子性”,則并發管理的核心在于“隔離性”。zgD28資訊網——每日最新資訊28at.com

  1. 原子性:一個業務操作被視為一個不可分割的邏輯單元,要么全部執行成功,要么全部失敗回滾;
  2. 隔離性:并發業務操作之間要相互隔離,不能互相干擾;

1. 無處不在的并發

并發管理是指在多個用戶同時訪問、修改同一數據時,如何保證數據的準確性、一致性和完整性的一系列管理措施。zgD28資訊網——每日最新資訊28at.com

并發無處不在是指在當前的業務系統和應用程序中,幾乎所有的操作都是并發的。無論是網絡請求、數據庫操作、I/O讀寫操作等,都可能在同一時刻被多個線程或進程同時執行。這意味著在業務開發中,必須充分考慮并發處理問題,避免出現數據競爭、死鎖等問題,同時合理利用多線程、協程等技術來提高系統的性能和處理能力。zgD28資訊網——每日最新資訊28at.com

1.1. 常見業務流程

首先看以下流程:zgD28資訊網——每日最新資訊28at.com

圖片圖片zgD28資訊網——每日最新資訊28at.com

這是一個聚合根更新操作,包括:zgD28資訊網——每日最新資訊28at.com

  1. 從 DB 中加載數據;
  2. 修改內存中的數據;
  3. 將變更更新到 DB;

也許還沒有使用DDD,對聚合根不太熟悉,那再看一個流程:zgD28資訊網——每日最新資訊28at.com

圖片圖片zgD28資訊網——每日最新資訊28at.com

這是一個更為通用的數據編輯流程,包括:zgD28資訊網——每日最新資訊28at.com

  1. 打開編輯頁面,從 DB 中加載數據,完成數據展示;
  2. 通過 UI 界面對數據進行編輯;
  3. 點擊保存按鈕,將新的變更保存到 DB;

仔細對比這兩張圖,其實他們都在做同樣的事情:zgD28資訊網——每日最新資訊28at.com

  1. 加載數據;
  2. 修改數據;
  3. 更新數據;

在這里便存在并發問題。zgD28資訊網——每日最新資訊28at.com

1.2. 并發問題

上面所提到的流程是否存在并發問題,仔細看下圖:zgD28資訊網——每日最新資訊28at.com

圖片圖片zgD28資訊網——每日最新資訊28at.com

同一個流程,操作同一數據,只是操作順序不同,也會出現并發安全問題:zgD28資訊網——每日最新資訊28at.com

  1. Action2 首先加載數據 V1;
  2. Action1 其次也加載數據 V1;
  3. Action2 對數據進行修改,并成功保存變更后的數據 V2(V1 + Action2 = V2);
  4. Action1 對數據進行修改,并成功保存變更后的數據 V3 (V1 + Action1 = V3);

看起來沒什么問題,但 V3 是業務期望的嗎?V2 的變更又去哪里了呢?zgD28資訊網——每日最新資訊28at.com

此時,V2 被 V3 覆蓋,V2 的變更丟失了。zgD28資訊網——每日最新資訊28at.com

如果還不清楚,明確業務操作為 count++,如下圖所示:zgD28資訊網——每日最新資訊28at.com

圖片圖片zgD28資訊網——每日最新資訊28at.com

對數據庫的 count 進行累加操作zgD28資訊網——每日最新資訊28at.com

  1. Action2 首先加載數據 count: 1;
  2. Action1 其次也加載數據 count: 1;
  3. Action2 對count:1進行累加,獲得新值 2,并成功保存 count:2;
  4. Action1 對count:1進行累加,獲得新值 2,并成功保存 count:2;

操作完成后,最終結果為2。實際期望結果為3,Action2 的修改被 Action1 覆蓋,導致一次累加操作被覆蓋。zgD28資訊網——每日最新資訊28at.com

當然,這僅僅是同一流程下的并發問題,多流程間也存在并發問題:zgD28資訊網——每日最新資訊28at.com

圖片圖片zgD28資訊網——每日最新資訊28at.com

對于同一記錄,自增流程和設置流程并發執行,同樣發生了寫覆蓋。zgD28資訊網——每日最新資訊28at.com

2. 局部串行

并發問題,只有在并發執行的情況下才會發生,對于同一數據如果不存在并發就不會出問題。zgD28資訊網——每日最新資訊28at.com

2.1. 線程方案

如下圖所示:zgD28資訊網——每日最新資訊28at.com

圖片圖片zgD28資訊網——每日最新資訊28at.com

訂單流程中的核心操作:zgD28資訊網——每日最新資訊28at.com

  1. 扣庫存
  2. 下單
  3. 支付成功

由于多個訂單間不存在關系,可以并發執行;但同一訂單,必須保障業務執行順序。zgD28資訊網——每日最新資訊28at.com

什么是“局部串行”:zgD28資訊網——每日最新資訊28at.com

  1. 對于同一訂單,需要保障順序性;
  2. 對于不同訂單可以并行執行;

其中分發器是核心,它連接訂單事件和后臺線程:zgD28資訊網——每日最新資訊28at.com

  1. 收到訂單事件后,從消息體中獲取訂單號;
  2. 通過 訂單號 % 線程數量,計算出事件運行的線程;
  3. 將事件提交到對應線程的處理隊列進行處理;
  4. 這樣統一訂單只會由同一線程進行處理;

這樣,相同訂單號的訂單事件均由同一個線程處理,從而保證局部串行化。不同訂單之間,不存在相互影響,可以在多個線程中并行執行。zgD28資訊網——每日最新資訊28at.com

2.2. MQ 方案

當然,內存操作存在數據安全問題(重啟任務會丟失),不少MQ也提供了相關功能,以 RocketMQ 的順序消息為例,如下圖所示:zgD28資訊網——每日最新資訊28at.com

圖片圖片zgD28資訊網——每日最新資訊28at.com

  1. RocketMQ 將相同 shardingKey 的消息發送至固定的 partition;
  2. 后臺處理線程從 partition 中獲取消息并執行處理邏輯;
  3. 從而保證相同 shardingKey 的消息均由同一線程處理;

局部串行對性能存在一定影響,系統最大的并發量為 partition 數量。如果出現增加 Worker 節點無法提升系統吞吐時,需要擴展 partition 數量。zgD28資訊網——每日最新資訊28at.com

【備注】在系統做 rebalance 時,可能會出現短暫的消息混亂,通常情況下,業務是可接受的。如果必須保障強順序,如 binlog 場景,只能使用一個 partition,但會極大的影響性能。zgD28資訊網——每日最新資訊28at.com

3. 最后寫勝出

有些時候,寫更新不依賴于之前的數據狀態,只需使用最新數據進行覆蓋即可,此時,并發管理也就變的非常簡單。zgD28資訊網——每日最新資訊28at.com

如下圖所示:zgD28資訊網——每日最新資訊28at.com

圖片圖片zgD28資訊網——每日最新資訊28at.com

  1. Action1 將 name 更新為 “精英英語”;
  2. Action2 將 status 更新為 Enable;
  3. 兩者對不同字段進行更新,并且相互間沒有交集;

此時,不會出現并發問題。但由于時序問題,數據的最終狀態以“最后更新”為準。zgD28資訊網——每日最新資訊28at.com

4. 原子指令

許多存儲引擎對單條記錄提供了原子操作,對于簡單的場景,可以將并發控制委托給存儲引擎進行管理。zgD28資訊網——每日最新資訊28at.com

比如在庫存扣減的場景,可以使用 Redis 或 DB 的原子指令進行操作。zgD28資訊網——每日最新資訊28at.com

4.1. Redis

使用 Redis 的 incr 指令:zgD28資訊網——每日最新資訊28at.com

圖片圖片zgD28資訊網——每日最新資訊28at.com

由于 redis 指令是單線程處理不存在并發問題,直接使用 incr key -1 質量對數量進行扣減。當然,這樣可能會出現數量為負值情況,此時可以引入 LUA 腳本進行保障:zgD28資訊網——每日最新資訊28at.com

-- KEYS[1]: 庫存鍵的名稱,例如 stock:1001-- ARGV[1]: 要扣減的數量local stock = tonumber(redis.call('GET', KEYS[1]))-- 判斷扣減的數量是否大于庫存數量if stock < tonumber(ARGV[1]) then    return -1end-- 扣減庫存,并返回剩余的庫存數量stock = stock - tonumber(ARGV[1])redis.call('SET', KEYS[1], stock)-- 返回剩余的庫存數量return stock

4.2. MySQL

同樣的操作也可以在 MySQL 中操作,如下圖所示:zgD28資訊網——每日最新資訊28at.com

圖片圖片zgD28資訊網——每日最新資訊28at.com

也可避免扣減為 負值的情況,如下圖所示:zgD28資訊網——每日最新資訊28at.com

圖片圖片zgD28資訊網——每日最新資訊28at.com

新增對 count 的條件判斷,通過操作結果控制不同的流程:zgD28資訊網——每日最新資訊28at.com

  1. 影響行數為1,代表操作成功;
  2. 影響函數為0,代表操作失敗;

5. 樂觀鎖

當一個事務(線程)修改一個數據時,先記錄下該數據的版本號,其他事務(線程)修改該數據時必須先檢查版本號,只有版本號相同的事務(線程)才能修改數據。樂觀鎖通常使用CAS(Compare and Swap)操作實現,對并發性能影響較小,但是需要開發人員在代碼中增加版本號檢查的代碼。zgD28資訊網——每日最新資訊28at.com

業務中使用最多的場景仍舊是 讀-改-寫,此時最佳處理方案便是樂觀鎖。zgD28資訊網——每日最新資訊28at.com

圖片圖片zgD28資訊網——每日最新資訊28at.com

相對于數據更新,樂觀鎖方案只是增加了 version 判斷,并未引入其他復雜性,對性能影響非常小。zgD28資訊網——每日最新資訊28at.com

  1. 在加載數據時獲取當前的數據版本 vsn1;
  2. 操作完成后,將數據更新到DB時,指定更新的數據版本為 vsn1,并將最新的 vsn 更新為 vsn1+1;
  3. 根據操作結果進行判斷:
  1. 更新成功,數據庫數據未發生變化,不存在并發問題;
  2. 更新失敗,數據庫數據已經發生變化,此時可以告知用戶對數據進行重新加載,并進行修改;

對于聚合根來說,這是數據更新最常見的并發保障機制。zgD28資訊網——每日最新資訊28at.com

6. 悲觀鎖

當一個事務(線程)正在使用某個數據時,其他事務(線程)就不能訪問該數據,必須等待鎖釋放后才能訪問。悲觀鎖能夠保證數據的一致性,但是對并發性能影響比較大。zgD28資訊網——每日最新資訊28at.com

悲觀鎖是最后的辦法,由于其對性能沖擊較大,不到萬不得已不要隨便使用。zgD28資訊網——每日最新資訊28at.com

6.1. 數據庫悲觀鎖

MySQL 提供 for update 指令,可以在查詢數據時獲取寫鎖,從而保證數據不會被破壞。zgD28資訊網——每日最新資訊28at.com

使用 for update 加載數據,操作如下:zgD28資訊網——每日最新資訊28at.com

圖片圖片zgD28資訊網——每日最新資訊28at.com

for update 語句將對數據進行強制加鎖,只有在事務提交后,鎖才會釋放。如圖所示,for update 會對操作進行強制排序,最終使單條操作變成串行化,從而影響并發度最終影響系統性能。zgD28資訊網——每日最新資訊28at.com

6.2. 分布式鎖

通常情況下分布式鎖是一種特殊的悲觀鎖,在一些數據添加場景非常重要。zgD28資訊網——每日最新資訊28at.com

比如,在訂單系統中,對于特價商品一個用戶只能購買一次,如下圖所示:zgD28資訊網——每日最新資訊28at.com

圖片圖片zgD28資訊網——每日最新資訊28at.com

該流程存在并發問題,可能導致一個用戶下單多次:zgD28資訊網——每日最新資訊28at.com

  1. 兩個線程都成功加載用戶的歷史訂單;
  2. 進行重復性校驗,發現都沒有購買該商品,從而進入生單流程;
  3. 兩個線程完成訂單對象構建,將數據保存到數據庫;
  4. 最終,同一用戶生成了兩個訂單,與業務預期不符;

由于是新增場景,沒有什么資源可鎖定,所以樂觀鎖方案無法落地,此時就需要引入分布式鎖,如下圖所示:zgD28資訊網——每日最新資訊28at.com

圖片圖片zgD28資訊網——每日最新資訊28at.com

以 user 為單位申請分布式鎖,保證同一用戶只有一個線程能進行被保護流程,從而保證同一用戶不會購買多次。zgD28資訊網——每日最新資訊28at.com

4. 小結

并發管理是一個高級話題,也是設計中的難點,一不小心就會出問題。讓每個開發人員都成為并發高手又是一件不太現實的事,但,好在存在很多并發管理的成熟方案,業務開發者按照場景進行落地即可:zgD28資訊網——每日最新資訊28at.com

  1. 局部串行:適用于同一數據的修改需要串行處理;不同數據間可并行處理的場景;
  2. 最后寫勝出:適用于不依賴于前值狀態的更新操作,對數據進行全量覆蓋的場景;
  3. 原子指令:適用于通過原子指令能完成業務場景,并且存儲引擎也提供了對應支持;
  4. 樂觀鎖:適用于聚合根的更新場景,對性能影響極小,可以作為框架默認配置;
  5. 悲觀鎖:適用于最為嚴格的場景,需要強制串行,對性能影響極大,需謹慎選擇;


zgD28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-14597-0.htmlDDD實戰:應對并發挑戰,五個技巧讓你輕松應對

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 當年很流行,現在已經淘汰的前端技術,請不要再繼續學了!

下一篇: 一文掌握在PyCharm中正確設置Python項目

標簽:
  • 熱門焦點
  • Find N3入網:最高支持16+1TB

    OPPO將于近期登場的Find N3折疊屏目前已經正式入網,型號為PHN110。本次Find N3在外觀方面相比前兩代有很大的變化,不再是小號的橫向折疊屏,而是跟別的廠商一樣采用了較為常見的
  • K60至尊版剛預熱 一加Ace2 Pro正面硬剛

    Redmi這邊剛如火如荼的宣傳了K60 Ultra的各種技術和硬件配置,作為競品的一加也坐不住了。一加中國區總裁李杰發布了兩條微博,表示在自家的一加Ace2上早就已經采用了和PixelWo
  • 把LangChain跑起來的三個方法

    使用LangChain開發LLM應用時,需要機器進行GLM部署,好多同學第一步就被勸退了,那么如何繞過這個步驟先學習LLM模型的應用,對Langchain進行快速上手?本片講解3個把LangChain跑起來
  • 從零到英雄:高并發與性能優化的神奇之旅

    作者 | 波哥審校 | 重樓作為公司的架構師或者程序員,你是否曾經為公司的系統在面對高并發和性能瓶頸時感到手足無措或者焦頭爛額呢?筆者在出道那會為此是吃盡了苦頭的,不過也得
  • 大廠卷向扁平化

    來源:新熵作者丨南枝 編輯丨月見大廠職級不香了。俗話說,兵無常勢,水無常形,互聯網企業調整職級體系并不稀奇。7月13日,淘寶天貓集團啟動了近年來最大的人力制度改革,目前已形成一
  • 疑似小米14外觀設計圖曝光:后置相機模組變化不大

    下半年的大幕已經開啟,而誰將成為下半年手機圈的主角就成為了大家關注的焦點,其中被傳有望拿下新一代驍龍8 Gen3旗艦芯片的小米14系列更是備受大家矚
  • 機構稱Q2國內智能手機銷量同比下滑4% vivo份額重回第1

    7月29日消息,根據市場調查機構Counterpoint Research公布的最新報告,2023年第2季度中國智能手機銷量同比下降4%,創新自2014年以來第2季度銷量新低。報
  • 3699元!iQOO Neo8 Pro頂配版今日首銷:1TB UFS 4.0同價位唯一

    5月23日,iQOO推出了全新的iQOO Neo8系列,包含iQOO Neo8和iQOO Neo8 Pro兩個版本,其中標準版搭載高通驍龍8+,而Pro版更是首發搭載了聯發科天璣9200+旗艦
  • 華為舉行春季智慧辦公新品發布會 首次推出電子墨水屏平板

    北京時間2月27日晚,華為在巴塞羅那舉行春季智慧辦公新品發布會,在海外市場推出之前已經在中國市場上市的筆記本、平板、激光打印機等辦公產品,并首次推出搭載
Top 主站蜘蛛池模板: 北宁市| 宁阳县| 茌平县| 孝昌县| 南郑县| 通许县| 德清县| 新安县| 吕梁市| 涪陵区| 拜泉县| 兴业县| 大宁县| 惠安县| 彭山县| 改则县| 临猗县| 讷河市| 泗阳县| 惠安县| 漳浦县| 东丰县| 南召县| 威海市| 苍南县| 闽侯县| 莱芜市| 乐亭县| 灵台县| 普宁市| 屏南县| 西畴县| 荆门市| 延庆县| 亚东县| 会昌县| 垫江县| 长治县| 芜湖县| 康定县| 基隆市|