成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

14張圖深度解密大廠秒殺系統庫存設計,不是所有的庫存都能支持高并發!

數據庫 其他數據庫
本章,主要對商品的庫存進行了分庫分表和分桶設計。首先,簡單描述了本章的需求。隨后,對庫存優化的目標進行了闡述。緊接著對庫存的分庫分表和分桶進行了設計和說明。

大家好,我是冰河~~

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

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

一、前言

對秒殺系統數據庫的讀寫操作進行優化,并不是簡單的進行主從復制和分庫分表。而是需要從秒殺特有的瞬時高并發、大流量的業務場景出發,針對場景進行數據庫優化。

對于秒殺這種場景來說,關鍵是要支撐瞬時的高并發、大流量,大量用戶搶購商品下單時,會頻繁調用查詢和更新商品庫存的接口,所以,對于商品庫存來說,我們需要增強數據庫的讀寫性能。

在具體設計上,就是要對商品的庫存進行分庫分表和分桶設計,使得商品的庫存不再由單數據庫進行存儲,擴展成多臺數據庫,并且在每個數據庫中,又對商品的庫存進行分桶設計。同時,在緩存層面,也需要對商品的庫存進行分桶設計

二、庫存優化目標

在正式對商品庫存進行分庫分表和分桶設計之前,我們先來確定下庫存優化的目標,也就是分庫分表和分桶設計的目標,這樣在后續的實現中更有針對性。這里,我主要把庫存優化的目標分成了六點:分庫設計、分表設計、分桶設計、緩存設計、一致性設計和兼容性設計,如下圖所示。

圖片圖片

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

三、分庫分表設計

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

  • 商品庫:在秒殺下單的過程中,主要以讀操作為主,比如獲取秒殺商品詳情信息等。
  • 庫存庫:在秒殺下單的過程中,主要以寫操作為主,主要是在下單過程中扣減商品的庫存,分攤數據庫的寫壓力。

這里需要注意的是:在我們實現的秒殺系統中,使用了一個商品庫和兩個庫存庫來實現商品庫存的分庫分表和分桶設計,在實際場景下,大家可以根據實際的業務需要,靈活配置分庫、分表和分桶的數量。

對商品庫存進行分庫分表設計時,一個很重要的設計就是對分片鍵的設計。所謂的分片鍵就是指定一個字段,通過這個字段將數據路由到對應的數據庫和數據表中。在秒殺系統分片鍵的設計上,盡量將同一個用戶的同一次事務中的相關操作路由到同一個數據庫中,降低跨庫操作的事務成本。

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

圖片圖片

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

庫存庫中則存放的是庫存分桶數據,每個庫存庫中存放了三個分桶后的庫存信息。這些分庫分表的數據,大家可以根據實際需要靈活調整。

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

四、庫存分桶設計

在分庫分表的基礎上,為了進一步提升數據庫的并發寫性能,可以對商品的庫存進行分桶存儲。當運營人員在配置庫存信息時,可以設置庫存的總量和分桶數量,比如,要將1500個商品分配到5個分桶中,則每個分桶中會分得300個商品庫存,如下圖所示。

圖片圖片

這樣,每個分桶就能夠承擔一部分寫壓力,從而將商品的庫存寫壓力分擔出去,使得秒殺系統的庫存數據庫能夠具備更高的并發寫能力。

當用戶搶購下單時,會根據分桶的數量對用戶的id進行取模來定位對應的庫存分桶,比如用戶的id為10001,目前庫存的分桶數量設置為5,則用戶搶購下單時,會將當前用戶搶購下單時,扣減商品庫存的請求路由到分桶1,如下圖所示。

圖片圖片

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

圖片圖片

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

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

  • 第一個方案就是在商品數據表中存儲商品的總庫存和分桶數量,每個分桶中存儲當前分桶的庫存信息即可。
  • 第二個方案就是在多個分桶中選擇一個主分桶用來存儲商品的總庫存。
  • 第三個方案就是在商品數據表中存儲商品的總庫存和分桶數量,每個分桶中存儲當前分桶的商品總庫存和當前可用庫存。

考慮到對商品庫存的并發寫操作,以及后續運營人員可能要調整商品的庫存信息,這里我們采用的是方案三,也就是在商品數據表中存儲商品總庫存和分桶數量,每個分桶中存儲當前分桶的商品總庫存和當前可用庫存。如下圖所示。

圖片圖片

運營人員在設置商品庫存時,將商品的總庫存和分桶數量存儲到商品庫,每個分桶中存儲當前分桶的總庫存和可用庫存。

五、分桶庫存扣減策略

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

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

方案1: 設計庫存分桶的“爭搶”機制,類似Java中的Fork/Join框架,如果當前分桶中的庫存不足,則按照一定的規則“爭搶”其他分桶中的庫存。

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

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

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

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

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

方案1和方案2在實現上比較復雜,要充分考慮在高并發、大流量場景下如何實現庫存的爭搶機制,并要考慮不能出現庫存超賣和少賣的問題,無疑是在系統的架構設計和實現層面增加了復雜度。

在這種秒殺場景下,大可不必非要實現方案1和方案3,換個角度思考,對于平臺和商戶來說,保證所有商品都能售罄,并保證數據一致。對于用戶來說,完全必要保證庫存數據的強一致性,只要保證用戶能看到對應分桶中的庫存就可以了,完全沒必要保證用戶看到庫存數據的強一致性。

六、緩存與一致性設計

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

商品庫存在緩存層面的分桶設計與在數據庫層面的分桶設計規則保持一致,例如,運營人員要將1500個商品分配到5個分桶中,則每個緩存分桶和數據庫分桶中都會分得300個商品庫存,如下圖所示。

圖片圖片

當用戶搶購下單時,同樣會根據分桶的數量對用戶的id進行取模來定位對應的庫存分桶,先預扣緩存分桶中的庫存,然后進行下單操作,最后扣減數據庫分桶中的庫存。

比如用戶的id為10001,目前庫存的分桶數量設置為5,則用戶搶購下單時,會將當前用戶搶購下單時,扣減商品庫存的請求路由到分桶1,如下圖所示。

圖片圖片

此時,就會將id為10001的用戶扣減商品庫存的請求路由到緩存分桶1來預扣商品庫存,預扣成功就會構建訂單數據并保存,最后扣減數據庫分桶1中的庫存數據。

如果用戶的id為10002,目前庫存的分桶數量設置為5,則用戶搶購下單時,會將當前用戶搶購下單時,扣減商品庫存的請求路由到分桶2,如下圖所示。

圖片圖片

此時,就會將id為10001的用戶扣減商品庫存的請求路由到緩存分桶2來預扣商品庫存,預扣成功就會構建訂單數據并保存,最后扣減數據庫分桶2中的庫存數據。

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

緩存中的商品分桶庫存保持弱一致性,數據庫中的商品分桶庫存保持強一致性。如下圖所示。

圖片圖片

當運營人員設置商品庫存和分桶數量時,會將商品的總庫存和分桶數量存儲到商品數據表,每個分桶中存儲當前分桶的總庫存和可用庫存。

當數據庫分桶中的商品庫存數據設置成功后,將其同步到緩存中,緩存中的商品分桶庫存規則與數據庫中的商品分桶庫存規則相同。

同時,緩存中的分桶庫存數據保持弱一致性,數據庫中的分桶庫存數據保持強一致性。

七、重置和調整分桶設計

運營人員難免會調整秒殺商品的庫存信息,比如原來的商品庫存為1500,后來想調整成1000或者2000,所以,秒殺系統要支持運營人員動態的調整秒殺商品的庫存。

以此對秒殺商品的庫存進行實時調整,運營人員調整庫存時,會涉及到三種情況,分別如下所示。

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

圖片圖片

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

圖片圖片

圖片圖片

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

圖片圖片

其實,這三種情況在秒殺系統的實現中,本質上就是對商品庫存和分桶數量的調整,秒殺系統要支持運營實時調整這些策略。

八、總結

本章,主要對商品的庫存進行了分庫分表和分桶設計。首先,簡單描述了本章的需求。隨后,對庫存優化的目標進行了闡述。緊接著對庫存的分庫分表和分桶進行了設計和說明。

接下來,對商品庫存分庫分表和分桶涉及到的緩存數據進行了設計,并對緩存數據與數據庫數據的一致性進行了設計。最后,對重置和調整商品庫存的分桶數據進行了設計。

責任編輯:武曉燕 來源: 冰河技術
相關推薦

2020-10-14 07:20:53

高并發

2021-08-26 08:24:33

高并發秒殺系統

2025-02-20 00:01:00

2022-06-14 14:18:46

架構秒殺高并發

2018-09-15 04:59:01

2024-09-10 10:42:27

2020-04-22 10:43:49

高并發數據阿里巴巴

2021-06-23 06:58:29

12306系統MySQL高可用預扣庫存

2024-01-31 13:02:00

高并發熱點散列庫存分桶

2025-01-20 00:00:03

高并發秒殺業務

2022-09-19 09:49:17

MCube網絡引擎

2017-12-12 08:40:00

2022-03-18 09:11:56

高并發搶購系統架構

2025-05-28 02:20:00

2024-06-20 07:59:49

2025-01-27 00:40:41

2024-07-12 11:28:44

2024-06-21 08:15:25

2024-07-03 11:01:55

2023-03-09 09:31:58

架構設計vivo
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美一级在线免费 | a在线观看免费 | 亚洲欧美在线一区 | 艹逼网| 99re热这里只有精品视频 | 在线成人av | 美女视频一区二区三区 | 国产乱码精品一区二区三区五月婷 | 日韩欧美亚洲 | 久久99精品国产99久久6男男 | 玖玖精品 | 日韩在线成人 | 一区二区三区欧美在线 | 日韩色视频 | 久草网站 | 欧美11一13sex性hd | 狠狠狠 | 国产精品久久久久久久久久久久冷 | 国产成人福利在线观看 | 国产69久久精品成人看动漫 | 99成人精品 | 国产精品毛片无码 | 久久久精品一区二区三区四季av | 亚洲视频中文字幕 | 一区二区免费在线视频 | 日本精品视频一区二区三区四区 | 久久精品欧美一区二区三区不卡 | 欧美在线综合 | av网站推荐| 黑人一级黄色大片 | 国产精品久久久久无码av | 日本在线小视频 | 久久精品亚洲成在人线av网址 | 91偷拍精品一区二区三区 | 在线免费av观看 | 黄色片在线网站 | 精品久久久久久亚洲精品 | 人人干人人看 | 欧美激情久久久久久 | 欧美日韩在线成人 | 久久99视频精品 |