自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

14張圖深度解密大廠秒殺系統(tǒng)庫存設(shè)計(jì),不是所有的庫存都能支持高并發(fā)!

數(shù)據(jù)庫 其他數(shù)據(jù)庫
本章,主要對商品的庫存進(jìn)行了分庫分表和分桶設(shè)計(jì)。首先,簡單描述了本章的需求。隨后,對庫存優(yōu)化的目標(biāo)進(jìn)行了闡述。緊接著對庫存的分庫分表和分桶進(jìn)行了設(shè)計(jì)和說明。

大家好,我是冰河~~

相信很多小伙伴都在大廠的秒殺大促中搶購過商品,那大家有沒有想過這樣一個(gè)問題:在秒殺這種高并發(fā)大流量的場景下,商品的庫存是如何設(shè)計(jì)呢?怎么才能抗住瞬時(shí)高并發(fā)的流量呢?

也有不少小伙伴出去面試時(shí),簡歷上寫了秒殺系統(tǒng),此時(shí)面試官通常也會(huì)問這樣一個(gè)問題:你們的秒殺系統(tǒng)庫存是怎么設(shè)計(jì)的呢?要知道,秒殺系統(tǒng)的庫存如果只是簡單的按照普通商品的庫存進(jìn)行設(shè)計(jì),是根本撐不住瞬時(shí)的高并發(fā)流量的。

一、前言

對秒殺系統(tǒng)數(shù)據(jù)庫的讀寫操作進(jìn)行優(yōu)化,并不是簡單的進(jìn)行主從復(fù)制和分庫分表。而是需要從秒殺特有的瞬時(shí)高并發(fā)、大流量的業(yè)務(wù)場景出發(fā),針對場景進(jìn)行數(shù)據(jù)庫優(yōu)化。

對于秒殺這種場景來說,關(guān)鍵是要支撐瞬時(shí)的高并發(fā)、大流量,大量用戶搶購商品下單時(shí),會(huì)頻繁調(diào)用查詢和更新商品庫存的接口,所以,對于商品庫存來說,我們需要增強(qiáng)數(shù)據(jù)庫的讀寫性能。

在具體設(shè)計(jì)上,就是要對商品的庫存進(jìn)行分庫分表和分桶設(shè)計(jì),使得商品的庫存不再由單數(shù)據(jù)庫進(jìn)行存儲(chǔ),擴(kuò)展成多臺(tái)數(shù)據(jù)庫,并且在每個(gè)數(shù)據(jù)庫中,又對商品的庫存進(jìn)行分桶設(shè)計(jì)。同時(shí),在緩存層面,也需要對商品的庫存進(jìn)行分桶設(shè)計(jì)

二、庫存優(yōu)化目標(biāo)

在正式對商品庫存進(jìn)行分庫分表和分桶設(shè)計(jì)之前,我們先來確定下庫存優(yōu)化的目標(biāo),也就是分庫分表和分桶設(shè)計(jì)的目標(biāo),這樣在后續(xù)的實(shí)現(xiàn)中更有針對性。這里,我主要把庫存優(yōu)化的目標(biāo)分成了六點(diǎn):分庫設(shè)計(jì)、分表設(shè)計(jì)、分桶設(shè)計(jì)、緩存設(shè)計(jì)、一致性設(shè)計(jì)和兼容性設(shè)計(jì),如下圖所示。

圖片圖片

  • 根據(jù)秒殺商品對庫存進(jìn)行分庫設(shè)計(jì):使得相同秒殺商品的庫存能夠路由到同一數(shù)據(jù)庫進(jìn)行處理。
  • 根據(jù)秒殺商品對庫存進(jìn)行分表設(shè)計(jì):使得相同秒殺商品的庫存能夠路由到同一數(shù)據(jù)庫中,然后再進(jìn)一步根據(jù)商品id進(jìn)行分表。
  • 根據(jù)秒殺商品對庫存進(jìn)行分桶設(shè)計(jì):對于秒殺系統(tǒng)來說,分庫分表主要提升的是多場秒殺活動(dòng)的并發(fā)處理能力,而分桶設(shè)計(jì)主要解決的是單場秒殺活動(dòng)的并發(fā)處理能力。
  • 根據(jù)庫存的分庫分表和分桶方案,設(shè)計(jì)對應(yīng)的庫存緩存方案:根據(jù)庫存的分庫分表和分桶方案,為商品的分桶庫存設(shè)計(jì)分桶緩存方案:真正扣減商品分桶庫存之前會(huì)預(yù)扣緩存中的分桶庫存數(shù)據(jù),以提高系統(tǒng)的并發(fā)處理能力。
  • 數(shù)據(jù)一致性設(shè)計(jì):在緩存與數(shù)據(jù)庫的數(shù)據(jù)一致性層面,基于分庫分表和分桶設(shè)計(jì),在緩存層面實(shí)現(xiàn)弱一致性,數(shù)據(jù)庫層面實(shí)現(xiàn)強(qiáng)一致性。
  • 兼容性設(shè)計(jì):對于新增的商品庫存分庫分表和分桶設(shè)計(jì),要兼容之前的商品庫存設(shè)計(jì),能夠根據(jù)簡單的配置進(jìn)行自由切換。

三、分庫分表設(shè)計(jì)

在分庫分表的設(shè)計(jì)上,這里我們使用了三個(gè)庫實(shí)現(xiàn)(實(shí)際場景可以根據(jù)具體需要靈活配置分庫和分表的數(shù)量),默認(rèn)一個(gè)商品庫和兩個(gè)庫存庫,將商品的庫存信息從商品表中獨(dú)立出來,單獨(dú)進(jìn)行分庫分表和分桶設(shè)計(jì)。

  • 商品庫:在秒殺下單的過程中,主要以讀操作為主,比如獲取秒殺商品詳情信息等。
  • 庫存庫:在秒殺下單的過程中,主要以寫操作為主,主要是在下單過程中扣減商品的庫存,分?jǐn)倲?shù)據(jù)庫的寫壓力。

這里需要注意的是:在我們實(shí)現(xiàn)的秒殺系統(tǒng)中,使用了一個(gè)商品庫和兩個(gè)庫存庫來實(shí)現(xiàn)商品庫存的分庫分表和分桶設(shè)計(jì),在實(shí)際場景下,大家可以根據(jù)實(shí)際的業(yè)務(wù)需要,靈活配置分庫、分表和分桶的數(shù)量。

對商品庫存進(jìn)行分庫分表設(shè)計(jì)時(shí),一個(gè)很重要的設(shè)計(jì)就是對分片鍵的設(shè)計(jì)。所謂的分片鍵就是指定一個(gè)字段,通過這個(gè)字段將數(shù)據(jù)路由到對應(yīng)的數(shù)據(jù)庫和數(shù)據(jù)表中。在秒殺系統(tǒng)分片鍵的設(shè)計(jì)上,盡量將同一個(gè)用戶的同一次事務(wù)中的相關(guān)操作路由到同一個(gè)數(shù)據(jù)庫中,降低跨庫操作的事務(wù)成本。

對于商品庫存進(jìn)行分庫分表之后的示意圖如下圖所示。

圖片圖片

可以看到,對于商品商品庫存來說,分庫分表后,會(huì)分成一個(gè)商品庫和兩個(gè)庫存庫,其中商品庫中存放的是秒殺商品信息,主要在用戶搶購下單的業(yè)務(wù)場景中,以讀操作為主。

庫存庫中則存放的是庫存分桶數(shù)據(jù),每個(gè)庫存庫中存放了三個(gè)分桶后的庫存信息。這些分庫分表的數(shù)據(jù),大家可以根據(jù)實(shí)際需要靈活調(diào)整。

對于商品庫存的分庫分表來說,在實(shí)際場景下,可以根據(jù)商品id進(jìn)行分片。也就是說,這里我們選擇的分片鍵是商品的id,同一個(gè)商品的庫存會(huì)被路由到同一個(gè)數(shù)據(jù)庫中,不會(huì)出現(xiàn)跨數(shù)據(jù)庫的操作。

四、庫存分桶設(shè)計(jì)

在分庫分表的基礎(chǔ)上,為了進(jìn)一步提升數(shù)據(jù)庫的并發(fā)寫性能,可以對商品的庫存進(jìn)行分桶存儲(chǔ)。當(dāng)運(yùn)營人員在配置庫存信息時(shí),可以設(shè)置庫存的總量和分桶數(shù)量,比如,要將1500個(gè)商品分配到5個(gè)分桶中,則每個(gè)分桶中會(huì)分得300個(gè)商品庫存,如下圖所示。

圖片圖片

這樣,每個(gè)分桶就能夠承擔(dān)一部分寫壓力,從而將商品的庫存寫壓力分擔(dān)出去,使得秒殺系統(tǒng)的庫存數(shù)據(jù)庫能夠具備更高的并發(fā)寫能力。

當(dāng)用戶搶購下單時(shí),會(huì)根據(jù)分桶的數(shù)量對用戶的id進(jìn)行取模來定位對應(yīng)的庫存分桶,比如用戶的id為10001,目前庫存的分桶數(shù)量設(shè)置為5,則用戶搶購下單時(shí),會(huì)將當(dāng)前用戶搶購下單時(shí),扣減商品庫存的請求路由到分桶1,如下圖所示。

圖片圖片

用戶id為10002的用戶搶購下單時(shí),扣減商品庫存的請求會(huì)被路由到分桶2,如下圖所示。

圖片圖片

可以看到,用戶搶購下單時(shí),扣減商品庫存的請求會(huì)被路由到不同的分桶中,這樣就可以大大降低扣減商品庫存的并發(fā)寫沖突問題,提升扣減商品庫存的并發(fā)寫性能。

這里,還有一個(gè)問題就是對商品的庫存進(jìn)行分桶設(shè)計(jì)后,每個(gè)分桶中保存的是當(dāng)前商品的一部分庫存信息,那如何確定商品的總庫存呢?其實(shí)有兩種方案和解決這個(gè)問題。

  • 第一個(gè)方案就是在商品數(shù)據(jù)表中存儲(chǔ)商品的總庫存和分桶數(shù)量,每個(gè)分桶中存儲(chǔ)當(dāng)前分桶的庫存信息即可。
  • 第二個(gè)方案就是在多個(gè)分桶中選擇一個(gè)主分桶用來存儲(chǔ)商品的總庫存。
  • 第三個(gè)方案就是在商品數(shù)據(jù)表中存儲(chǔ)商品的總庫存和分桶數(shù)量,每個(gè)分桶中存儲(chǔ)當(dāng)前分桶的商品總庫存和當(dāng)前可用庫存。

考慮到對商品庫存的并發(fā)寫操作,以及后續(xù)運(yùn)營人員可能要調(diào)整商品的庫存信息,這里我們采用的是方案三,也就是在商品數(shù)據(jù)表中存儲(chǔ)商品總庫存和分桶數(shù)量,每個(gè)分桶中存儲(chǔ)當(dāng)前分桶的商品總庫存和當(dāng)前可用庫存。如下圖所示。

圖片圖片

運(yùn)營人員在設(shè)置商品庫存時(shí),將商品的總庫存和分桶數(shù)量存儲(chǔ)到商品庫,每個(gè)分桶中存儲(chǔ)當(dāng)前分桶的總庫存和可用庫存。

五、分桶庫存扣減策略

我們對庫存進(jìn)行分庫分表和分桶設(shè)計(jì)后,在實(shí)際場景中,大部分情況下都是路由到不同庫存分桶的流量是存在差異的,這就會(huì)導(dǎo)致不同庫存分桶中的庫存剩余量有所不同,比如,id為10001的用戶搶購下單時(shí),會(huì)被路由到分桶1,id為10002的用戶搶購下單時(shí),會(huì)被路由到分桶2。

有可能存在的一種情況是:此時(shí)分桶1中沒有庫存了,分桶2中有庫存,那對于id為10001的用戶來說,該怎么處理呢?此時(shí),我們可以考慮三種方案:

方案1: 設(shè)計(jì)庫存分桶的“爭搶”機(jī)制,類似Java中的Fork/Join框架,如果當(dāng)前分桶中的庫存不足,則按照一定的規(guī)則“爭搶”其他分桶中的庫存。

方案2: 每個(gè)分桶中預(yù)留一些冗余的庫存,某個(gè)分桶庫存不足,向其他分桶借用。

方案3: 路由到不同庫存分桶的用戶看到的剩余庫存量不同,如果某個(gè)分桶的庫存不足,直接向路由到該分桶的用戶提示庫存不足。

這三種方案各有利弊,經(jīng)過對秒殺這種場景的權(quán)衡,我們最終采用的是方案3。要知道,在秒殺絕大部分場景下,都是大量的用戶去搶購有限數(shù)量的商品,大部分情況下,所有分桶的庫存會(huì)被瞬間搶購一空。

那有沒有一些極端情況,某些分桶中的庫存無法售罄呢?這種情況不能說沒有,有可能會(huì)出現(xiàn),但是概率極低。

如果確實(shí)存在某些分桶中的庫存無法售罄的情況,則可以通過人工干預(yù)的方式收縮庫存分桶,將沒有售罄的分桶庫存收縮到一個(gè)分桶中,這樣將相當(dāng)于庫存沒有分桶了,后續(xù)所有的請求都會(huì)被路由到同一個(gè)庫存分桶中,最終庫存都會(huì)被售罄。

方案1和方案2在實(shí)現(xiàn)上比較復(fù)雜,要充分考慮在高并發(fā)、大流量場景下如何實(shí)現(xiàn)庫存的爭搶機(jī)制,并要考慮不能出現(xiàn)庫存超賣和少賣的問題,無疑是在系統(tǒng)的架構(gòu)設(shè)計(jì)和實(shí)現(xiàn)層面增加了復(fù)雜度。

在這種秒殺場景下,大可不必非要實(shí)現(xiàn)方案1和方案3,換個(gè)角度思考,對于平臺(tái)和商戶來說,保證所有商品都能售罄,并保證數(shù)據(jù)一致。對于用戶來說,完全必要保證庫存數(shù)據(jù)的強(qiáng)一致性,只要保證用戶能看到對應(yīng)分桶中的庫存就可以了,完全沒必要保證用戶看到庫存數(shù)據(jù)的強(qiáng)一致性。

六、緩存與一致性設(shè)計(jì)

對于商品的庫存在數(shù)據(jù)庫層面進(jìn)行分桶設(shè)計(jì)是遠(yuǎn)遠(yuǎn)不夠的,要知道MySQL單行并發(fā)寫的TPS大概在300~500之間,即使我們對商品進(jìn)行了分庫分表和分桶設(shè)計(jì),如果將秒殺系統(tǒng)扣減庫存的流量直接打入數(shù)據(jù)庫,哪怕部署了MySQL集群,估計(jì)也很難抗下所有的并發(fā)流量。所以,我們同樣要對商品庫存在緩存中進(jìn)行分桶設(shè)計(jì)。

商品庫存在緩存層面的分桶設(shè)計(jì)與在數(shù)據(jù)庫層面的分桶設(shè)計(jì)規(guī)則保持一致,例如,運(yùn)營人員要將1500個(gè)商品分配到5個(gè)分桶中,則每個(gè)緩存分桶和數(shù)據(jù)庫分桶中都會(huì)分得300個(gè)商品庫存,如下圖所示。

圖片圖片

當(dāng)用戶搶購下單時(shí),同樣會(huì)根據(jù)分桶的數(shù)量對用戶的id進(jìn)行取模來定位對應(yīng)的庫存分桶,先預(yù)扣緩存分桶中的庫存,然后進(jìn)行下單操作,最后扣減數(shù)據(jù)庫分桶中的庫存。

比如用戶的id為10001,目前庫存的分桶數(shù)量設(shè)置為5,則用戶搶購下單時(shí),會(huì)將當(dāng)前用戶搶購下單時(shí),扣減商品庫存的請求路由到分桶1,如下圖所示。

圖片圖片

此時(shí),就會(huì)將id為10001的用戶扣減商品庫存的請求路由到緩存分桶1來預(yù)扣商品庫存,預(yù)扣成功就會(huì)構(gòu)建訂單數(shù)據(jù)并保存,最后扣減數(shù)據(jù)庫分桶1中的庫存數(shù)據(jù)。

如果用戶的id為10002,目前庫存的分桶數(shù)量設(shè)置為5,則用戶搶購下單時(shí),會(huì)將當(dāng)前用戶搶購下單時(shí),扣減商品庫存的請求路由到分桶2,如下圖所示。

圖片圖片

此時(shí),就會(huì)將id為10001的用戶扣減商品庫存的請求路由到緩存分桶2來預(yù)扣商品庫存,預(yù)扣成功就會(huì)構(gòu)建訂單數(shù)據(jù)并保存,最后扣減數(shù)據(jù)庫分桶2中的庫存數(shù)據(jù)。

這里,還有一個(gè)問題就是如何同步緩存中分桶中的庫存數(shù)據(jù)與數(shù)據(jù)庫分桶中的庫存數(shù)據(jù)呢?其實(shí),設(shè)計(jì)起來也比較簡單,就是運(yùn)營人員設(shè)置或者調(diào)整商品庫存和分桶數(shù)量時(shí),會(huì)將計(jì)算出來的商品分桶庫存寫入數(shù)據(jù)庫,寫入成功后,更新緩存中的分桶庫存數(shù)據(jù)即可。

緩存中的商品分桶庫存保持弱一致性,數(shù)據(jù)庫中的商品分桶庫存保持強(qiáng)一致性。如下圖所示。

圖片圖片

當(dāng)運(yùn)營人員設(shè)置商品庫存和分桶數(shù)量時(shí),會(huì)將商品的總庫存和分桶數(shù)量存儲(chǔ)到商品數(shù)據(jù)表,每個(gè)分桶中存儲(chǔ)當(dāng)前分桶的總庫存和可用庫存。

當(dāng)數(shù)據(jù)庫分桶中的商品庫存數(shù)據(jù)設(shè)置成功后,將其同步到緩存中,緩存中的商品分桶庫存規(guī)則與數(shù)據(jù)庫中的商品分桶庫存規(guī)則相同。

同時(shí),緩存中的分桶庫存數(shù)據(jù)保持弱一致性,數(shù)據(jù)庫中的分桶庫存數(shù)據(jù)保持強(qiáng)一致性。

七、重置和調(diào)整分桶設(shè)計(jì)

運(yùn)營人員難免會(huì)調(diào)整秒殺商品的庫存信息,比如原來的商品庫存為1500,后來想調(diào)整成1000或者2000,所以,秒殺系統(tǒng)要支持運(yùn)營人員動(dòng)態(tài)的調(diào)整秒殺商品的庫存。

以此對秒殺商品的庫存進(jìn)行實(shí)時(shí)調(diào)整,運(yùn)營人員調(diào)整庫存時(shí),會(huì)涉及到三種情況,分別如下所示。

(1)第一種情況是調(diào)整商品庫存,但是分桶數(shù)量不變,如下圖所示。

圖片圖片

(2)第二種情況是商品庫存不變,調(diào)大或者調(diào)下分桶數(shù)量,如下圖所示。

圖片圖片

圖片圖片

(3)第三種情況是既調(diào)整了商品庫存,又調(diào)整了分桶數(shù)量,如下圖所示。

圖片圖片

其實(shí),這三種情況在秒殺系統(tǒng)的實(shí)現(xiàn)中,本質(zhì)上就是對商品庫存和分桶數(shù)量的調(diào)整,秒殺系統(tǒng)要支持運(yùn)營實(shí)時(shí)調(diào)整這些策略。

八、總結(jié)

本章,主要對商品的庫存進(jìn)行了分庫分表和分桶設(shè)計(jì)。首先,簡單描述了本章的需求。隨后,對庫存優(yōu)化的目標(biāo)進(jìn)行了闡述。緊接著對庫存的分庫分表和分桶進(jìn)行了設(shè)計(jì)和說明。

接下來,對商品庫存分庫分表和分桶涉及到的緩存數(shù)據(jù)進(jìn)行了設(shè)計(jì),并對緩存數(shù)據(jù)與數(shù)據(jù)庫數(shù)據(jù)的一致性進(jìn)行了設(shè)計(jì)。最后,對重置和調(diào)整商品庫存的分桶數(shù)據(jù)進(jìn)行了設(shè)計(jì)。

責(zé)任編輯:武曉燕 來源: 冰河技術(shù)
相關(guān)推薦

2020-10-14 07:20:53

高并發(fā)

2021-08-26 08:24:33

高并發(fā)秒殺系統(tǒng)

2025-02-20 00:01:00

2022-06-14 14:18:46

架構(gòu)秒殺高并發(fā)

2018-09-15 04:59:01

2020-04-22 10:43:49

高并發(fā)數(shù)據(jù)阿里巴巴

2024-09-10 10:42:27

2021-06-23 06:58:29

12306系統(tǒng)MySQL高可用預(yù)扣庫存

2024-01-31 13:02:00

高并發(fā)熱點(diǎn)散列庫存分桶

2022-09-19 09:49:17

MCube網(wǎng)絡(luò)引擎

2025-01-20 00:00:03

高并發(fā)秒殺業(yè)務(wù)

2017-12-12 08:40:00

2022-03-18 09:11:56

高并發(fā)搶購系統(tǒng)架構(gòu)

2025-01-27 00:40:41

2024-06-20 07:59:49

2024-07-12 11:28:44

2024-07-03 11:01:55

2024-06-21 08:15:25

2023-03-09 09:31:58

架構(gòu)設(shè)計(jì)vivo

2025-03-11 08:36:52

高并發(fā)場景性能
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)