<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
相信大家從網上學習專案大部分人第一個專案都是電商,生活中時時刻刻也會用到電商APP,例如淘寶,京東等。做技術的人都知道,電商的業務邏輯簡單,但是大部分電商都會涉及到高並行高可用,對並行和對資料的處理要求是很高的。這裡我今天就講一下高並行情況下是如何扣減庫存的?
我們對扣減庫存所需要關注的技術點如下:
顧名思義,就是扣減業務完全依賴MySQL等資料庫來完成。而不依賴一些其他的中介軟體或者快取。純資料庫實現的好處就是邏輯簡單,開發以及部署成本低。(適用於中小型電商)。
純資料庫的實現之所以能夠滿足扣減業務的各項功能要求,主要依賴兩點:
基於上述方案,它包含一個扣減服務和一個數量資料庫
如果資料量單庫壓力很大,也可以做主從和分庫分表,服務可以做叢集等。
一次完整的流程就是先進行資料校驗,在其中做一些引數格式校驗,這裡做介面開發的時候,要保持一個原則就是不信任原則,一切資料都不要相信,都需要做校驗判斷。其次,還可以進行庫存扣減的前置校驗。比如當前庫存中的庫存只有8個,而使用者要購買10個,此時的資料校驗中即可前置攔截,減少對於資料庫的寫操作。純讀不會加鎖,效能較高,可以採用此種方式提升並行量。
update xxx set leavedAmount=leavedAmount-currentAmount where skuid='xxx' and leavedAmount>=currentAmount
此SQL採用了類似樂觀鎖的方式實現了原子性。在where後面判斷剩餘數量大於等於需要的數量,才能成功,否則失敗。
扣減完成之後,需要記錄流水資料。每一次扣減的時候,都需要外部使用者傳入一個uuid作為流水編號,此編號是全域性唯一的。使用者在扣減時傳入唯一的編號有兩個作用:
當用戶只購買某個商品一個的時候,如果校驗時剩餘庫存有8個,此時校驗通過。但在後續的實際扣減時,因為其他使用者也在並行的扣減,可能會出現幻讀,此時使用者實際去扣減時不足一個,導致失敗。這種場景會導致多一次資料庫查詢,降低整體的扣減效能。這時候可以對MySQL架構進行升級
多一次查詢,就會增加資料庫的壓力,同時對整體效能也有一定的影響。此外,對外提供的查詢庫存數量的介面也會對資料庫產生壓力,同時讀的請求要遠大於寫。
根據業務場景分析,讀庫存的請求一般是顧客瀏覽商品時產生,而呼叫扣減庫存的請求基本上是使用者購買時才觸發。使用者購買請求的業務價值比讀請求會更大,因此對於寫需要重點保障。針對上述的問題,可以對MySQL整體架構進行升級
整體的升級策略採用讀寫分離的方式,另外主從複製直接使用MySQL等資料庫已有的功能,改動上非常小,只要在扣減服務裡設定兩個資料來源。當客戶查詢剩餘庫存,扣減服務中的前置校驗時,讀取從資料庫即可。而真正的資料扣減還是使用主資料庫。
讀寫分離之後,根據二八原則,80% 的均為讀流量,主庫的壓力降低了 80%。但採用了讀寫分離也會導致讀取的資料不準確的問題,不過庫存數量本身就在實時變化,短暫的差異業務上是可以容忍的,最終的實際扣減會保證資料的準確性。
在上面基礎上,還可以升級,增加快取
純資料庫的方案雖然可以避免超賣和少賣的情況,但是並行量實在很低,效能不是很樂觀。所以這裡再進行升級
這和前面的扣減庫存其實是一樣的。但是此時扣減服務依賴的是Redis而不是資料庫了。
這裡針對Redis的hash結構不支援多個key的批次操作問題,我們可以採用Redis+lua指令碼來實現批次扣減單執行緒請求。
升級成純Redis實現扣減也會有問題
雖然使用純Redis方案可以提高並行量,但是因為Redis不具備事務特性,極端情況下會存在Redis的資料無法回滾,導致出現少賣的情況。也可能發生非同步寫庫失敗,導致多扣的資料再也無法找回的情況。
在向磁碟進行資料操作時,向檔案末尾不斷追加寫入的效能要遠大於隨機修改的效能。因為對於傳統的機械硬碟來說,每一次的隨機更新都需要機械鍵盤的磁頭在硬碟的盤面上進行定址,再去更新目標資料,這種方式十分消耗效能。而向檔案末尾追加寫入,每一次的寫入只需要磁頭一次定址,將磁頭定位到檔案末尾即可,後續的順序寫入不斷追加即可。
對於固態硬碟來說,雖然避免了磁頭移動,但依然存在一定的定址過程。此外,對檔案內容的隨機更新和資料庫的表更新比較類似,都存在加鎖帶來的效能消耗。
資料庫同樣是插入要比更新的效能好。對於資料庫的更新,為了保證對同一條資料並行更新的一致性,會在更新時增加鎖,但加鎖是十分消耗效能的。此外,對於沒有索引的更新條件,要想找到需要更新的那條資料,需要遍歷整張表,時間複雜度為 O(N)。而插入只在末尾進行追加,效能非常好。
通過上面的理論就可以得出一個兼具效能和高可靠的扣減架構
上述的架構和純快取的架構區別在於,寫入資料庫不是非同步寫入,而是在扣減的時候同步寫入。同步寫入資料庫使用的是insert操作,就是順序寫,而不是update做資料庫數量的修改,所以,效能會更好。
insert 的資料庫稱為任務庫,它只儲存每次扣減的原始資料,而不做真實扣減(即不進行 update)。它的表結構大致如下:
create table task{ id bigint not null comment "任務順序編號", task_id bigint not null }
任務表裡儲存的內容格式可以為 JSON、XML 等結構化的資料。以 JSON 為例,資料內容大致可以如下:
{ "扣減號":uuid, "skuid1":"數量", "skuid2":"數量", "xxxx":"xxxx" }
這裡我們肯定是還有一個記錄業務資料的庫,這裡儲存的是真正的扣減名企和SKU的彙總資料。對於另一個庫裡面的資料,只需要通過這個表進行非同步同步就好了。
這裡和純快取的區別在於增加了事務開啟與回滾的步驟,以及同步的資料庫寫入流程
任務庫裡儲存的是純文字的 JSON 資料,無法被直接使用。需要將其中的資料轉儲至實際的業務庫裡。業務庫裡會儲存兩類資料,一類是每次扣減的流水資料,它與任務表裡的資料區別在於它是結構化,而不是 JSON 文字的大欄位內容。另外一類是彙總資料,即每一個 SKU 當前總共有多少量,當前還剩餘多少量(即從任務庫同步時需要進行扣減的),表結構大致如下:
create table 流水錶{ id bigint not null, uuid bigint not null comment '扣減編號', sku_id bigint not null comment '商品編號', num int not null comment '當次扣減的數量' }comment '扣減流水錶'
商品的實時資料彙總表,結構如下:
create table 彙總表{ id bitint not null, sku_id unsigned bigint not null comment '商品編號', total_num unsigned int not null comment '總數量', leaved_num unsigned int not null comment '當前剩餘的商品數量' }comment '記錄表'
在整體的流程上,還是複用了上一講純快取的架構流程。當新加入一個商品,或者對已有商品進行補貨時,對應的新增商品數量都會通過 Binlog 同步至快取裡。在扣減時,依然以快取中的數量為準
到此這篇關於Redis高並行情況下並行扣減庫存專案實戰的文章就介紹到這了,更多相關Redis 並行扣減庫存內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45