聊聊高并发下库存加减那些事儿——“异步扣减库存”
聊聊高并發(fā)下庫存加減那些事兒
不定期福利發(fā)放哦
聊聊高并發(fā)下庫存加減那些事兒背景? ? ?一般在日常開發(fā)中經(jīng)常會遇到打折促銷,秒殺活動,就如拼多多最近的4999搶券買愛瘋11促銷活動,畢竟誰的錢也不是大風(fēng)刮來的,有秒殺有促銷必定帶來大量用戶,而這類活動往往支撐著公司重要營銷策略,所以保證系統(tǒng)在高并發(fā)下不出異常非常關(guān)鍵,這其中棘手的便是如何在高并發(fā)下高效的處理庫存數(shù)據(jù)。今天就來聊聊高并發(fā)下庫存加減那些事兒。
常規(guī)做法首先我們要明確重要的一點是減庫存是需要順序的,而需要順序就意味著不能有并發(fā)加減庫存的操作,為了實現(xiàn)順序,一般做法都是將多線程強(qiáng)行變?yōu)閱尉€程實現(xiàn)同步操作或者所說的順序,將多線程變?yōu)閱尉€程方案普遍做法便是使用鎖或者借助隊列。另一方面由于大型互聯(lián)網(wǎng)應(yīng)用面向大量用戶所以都是大型分布式加集群作為最基礎(chǔ)的架構(gòu),而由于架構(gòu)原因,往常所使用的lock或者Synchronized進(jìn)程鎖關(guān)鍵字失去了意義(只能鎖住當(dāng)前Web程序代碼塊,但無法鎖住集群中其他Web程序)。此時我們便要借助分布式鎖或者M(jìn)Q組件來達(dá)到跨進(jìn)程跨主機(jī)的單線程效果。
接下來我們以ABC下單減庫為例說明分布式下的減庫存場景
ABC同時發(fā)起庫存減1的請求
服務(wù)器接收到三個減庫存操作,利用分布式鎖鎖住了減庫存的邏輯,每次只限一個請求操作.對A請求進(jìn)行庫存減1操作后,再對B進(jìn)行操作,one by one 以此類推。
目前減庫存操作運行很好,不會發(fā)生超賣情況,老板再也不擔(dān)心程序員敗家了。但是以上減庫存的邏輯有個很大的問題便是由于強(qiáng)行將多線程請求變?yōu)閱尉€程,不可避免的導(dǎo)致排隊的發(fā)生,這樣會發(fā)生什么情況呢?
越后進(jìn)分布式鎖或者隊列的請求他需要的響應(yīng)時間越久因為他的響應(yīng)時間是前面所有請求的響應(yīng)時間之和。當(dāng)然有人會說增加配置或者在redis中減庫存再利用rabbitmq將結(jié)果同步到數(shù)據(jù)庫中,由于操作內(nèi)存中的數(shù)據(jù)讓減庫存操作響應(yīng)加快,這的確對單次的減庫存有效,但是隨著并發(fā)提高,單次減庫存響應(yīng)時間的優(yōu)化必將遇到瓶頸。依然沒有解決高并發(fā)下所有人必須強(qiáng)行排隊導(dǎo)致的問題。那有沒有那種又順序執(zhí)行又能相對的并行加減庫存操作呢?
并行異步減庫存減庫存必定是順序排隊的,這毋庸置疑,但是有沒有辦法可以加快這個排隊呢,答案是有的!
只有將同步減庫存邏輯變?yōu)楫惒讲拍軓母窘鉀Q排隊問題。但是有人會說這與庫存操作的邏輯(同步順序排隊)沖突。
其實這里所說的異步是相對的,什么意思呢?
首先全局庫存是必須順序操作的,但是如果我們把庫存分割成N塊,每一塊內(nèi)部是順序的,但是每一塊彼此之間又是異步的。這樣就很好的解決了庫存順序執(zhí)行的邏輯又減輕了排隊的影響。有人會問這里是如何減輕的呢?首先來給減庫存算一筆響應(yīng)時間的賬:
假設(shè)每個減庫存操作的響應(yīng)時間優(yōu)化到50毫秒,并發(fā)2000,按照常規(guī)做法加全局鎖那第2000個人的響應(yīng)時間便是前面1999個用戶的響應(yīng)時間加他自己的50毫秒之和為100秒。100秒的響應(yīng)可能用戶早就心里默默詛咒你了。而且這已經(jīng)是非常理想化的單次響應(yīng)時間了。如果有人說可以優(yōu)化到2毫秒就不會超時了。。麻煩帶上鍵盤去微博杠吧。。
如果使用第二種方案假設(shè)三個用戶請求減庫存操作,完全可以讓三個請求進(jìn)三個不同的鎖去扣減各自的庫存數(shù),此時三人沒有排隊可以保證他們同時減庫存,而又不影響庫存總數(shù)的準(zhǔn)確性,因為三個請求操作的是各自鎖所維護(hù)的庫存數(shù)。隨著業(yè)務(wù)增長,庫存總數(shù)的分割可以不斷細(xì)分直到縮短響應(yīng)時間到合理范圍,而這個庫存總數(shù)的分割很好的保證了不會遇到瓶頸。但是由于這種業(yè)務(wù)架構(gòu)的設(shè)計,導(dǎo)致業(yè)務(wù)不得不變得復(fù)雜,可以看到我們在進(jìn)入分布式鎖之前有一個稱為庫存總數(shù)協(xié)調(diào)器的模塊,這個模塊是用來做什么的呢?
首先我們把庫存分割成多塊后解決的首要問題便是如何讓請求均勻的依次進(jìn)入每一個分布式鎖中進(jìn)而操作當(dāng)前鎖所負(fù)責(zé)的庫存數(shù)。
庫存協(xié)調(diào)器的邏輯完全看各位自己業(yè)務(wù)模型來決定,你可以用雪花算法均勻分布也可使用ip或者用戶標(biāo)識取余去覆蓋到每一個鎖,總之實現(xiàn)方式看業(yè)務(wù)情況來決定,當(dāng)然了很大幾率會出現(xiàn)有的庫存塊內(nèi)的庫存總數(shù)消耗完了但有的還剩余,所以庫存協(xié)調(diào)器一定要考慮到這類情況及時將庫存較多的庫存塊內(nèi)的庫存數(shù)分散給其他庫存塊,以達(dá)到多線程減庫存的效果。
從示例圖中可以看到引入了rabbitmq,他在當(dāng)前整個業(yè)務(wù)架構(gòu)中的作用主要是每一個分布式鎖處理完當(dāng)前庫存塊的庫存后要將當(dāng)前加減的數(shù)量丟給消息隊列,由消費端慢慢消化這些操作到數(shù)據(jù)庫。
總結(jié)其實解決高并發(fā)業(yè)務(wù)只要你遵循讓一個變成多個的思路,很多都有解決辦法等著你
提前預(yù)祝中華人民共和國成立70周年 國慶快樂。。
總結(jié)
以上是生活随笔為你收集整理的聊聊高并发下库存加减那些事儿——“异步扣减库存”的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 推荐neter常用优秀开源项目系列之一
- 下一篇: 记一次中小公司的研发问题