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

支持每秒上萬單的秒殺扣庫存事務

開發 架構
本文介紹一種全新的秒殺架構,解決了秒殺架構中的高并發扣庫存問題。

該架構能夠支持每秒超萬單精準扣庫存,并且在應用crash等情況下,也能保證創建訂單和扣減庫存的數據最終嚴格一致。

現有秒殺系統的問題

現有的秒殺架構,為了支持高并發,通常把庫存放在Redis中,收到訂單請求時,在Redis中進行庫存扣減。這種的設計,導致創建訂單和庫存扣減不是原子操作,如果兩個操作中間,遇到進程crash等問題,就會導致數據不一致。

即使庫存扣減不放在Redis中,而是放在數據庫,不一致問題也通常是存在的。業務系統為了模塊化,減少耦合,會將庫存服務與訂單服務分開。只要是分開的服務,那么數據不一致的情況就是無法避免的。

進程crash等問題,雖然發生的概率不高,但即使占比百分之一,甚至千分之一,都會產生數據不一致,例如扣減的庫存量和創建成功的訂單不一致。

庫存與訂單數據不一致是必須解決的難題,常見做法是,開發人員通過訂單數據,去校準庫存數據,這部分的工作非常繁瑣復雜,耗費大量的開發工作,而且很多時候需要人工介入,對數據進行人工校驗和修復。

下面我們來看看新架構如何優雅解決這個問題

整體架構

我們明確業務場景,我們把秒殺系統的核心要點提取出來,為以下幾點:

  • 用戶進行秒殺,會在某個時間點發送大量的請求到后端,請求量會大大高于庫存數量
  • 后端需要保證庫存扣減和訂單創建是最終嚴格一致的,即使中間發生進程crash,最終數據不會受到影響

本架構基于 https://github.com/dtm-labs/dtm,這是一個分布式事務框架,提供跨服務,跨庫的數據一致性解決方案。

上述的場景下,絕大部分扣減庫的描述請求,都會失敗,時序圖如下:

在這個架構中,使用了分布式事務框架dtm。上述的時序圖中,扣減庫存是在Redis中進行的,與dtm相關的注冊全局事務和取消全局事務也是在Redis中處理的,全程依賴Redis,與數據庫無關,因此能夠支持極高的并發,從后面的測試數據中可以看到,該架構可以輕易處理每秒上萬單的秒殺請求。

雖然大部分請求因為扣減庫存失敗而結束,但是會有一定數量的請求,扣減庫存成功,這種情況的時序圖如下:

在這個時序圖中,扣減庫存成功后,會進入到訂單服務,進行訂單相關的創建,以及后續的支付。在這個新架構中,訂單服務僅需要處理有效訂單,此時并發量已經大幅下降,只需要通過常規的方法,例如訂單分庫分表、消息隊列削峰處理,就可以輕松解決問題了。

原子操作

在上述的架構中,如果在Redis中扣減庫存后,在提交全局事務前,發生進程crash,就會導致兩個操作沒有同時完成,那么這種情況后續會怎么樣?新架構如何保證數據最終嚴格一致?這種情況的整個的時序圖如下:

一旦發生這類進程crash,導致兩個操作過程中斷,那么dtm服務器會輪詢超時未完成的事務,如果出現已Prepare、未Submit的全局任務,那么他會調用反查接口,詢問應用,庫存扣減是否成功扣減。如果已扣減,則將全局事務提交,并進行后續的調用;如果未扣減,則將全局事務標記為失敗,不再處理。

保證原子操作的原理,以及發生各種情況dtm的處理策略,可以參考二階段消息,這里不做詳細的描述。

核心代碼#

秒殺接口的核心代碼如下:

gid := "{a}flash-sale-" + activityID + "-" + uid
msg := dtmcli.NewMsg(DtmServer, gid).

Add(busi.Busi+"/createOrder", gin.H{activity_id: activityID, UID: uid})err := msg.DoAndSubmit(busi.Busi+"/QueryPreparedRedis", func(bb *BranchBarrier) error {

return bb.RedisCheckAdjustAmount(rds, "{a}stock-"+stockID, -1, 86400)})

}
  • 行1: 一般的秒殺活動,一個用戶僅能購買一次,因此按照活動id+用戶id作為全局事務ID,能夠保證用戶最多生成一個全局事務,最多創建一個訂單
  • 行2: 創建一個二階段消息的對象,填入dtm服務器地址,以及全局事務id
  • 行3: 給二階段消息添加一個分支事務,該事務分支為創建訂單服務
  • 行4: 調用二階段消息的DoAndSubmit,該函數第一個參數為反查的URL(見上圖中的反查);第二個參數為一個回調函數,里面會包含業務邏輯。該函數會執行業務,并在成功后提交全局事務,保證執行業務和全局事務的提交是“原子的”
  • 行5: 調用RedisCheckAdjustAmount,該函數會進行庫存扣減,這個函數進行庫存扣減時,如果庫存不夠,則會返回錯誤;如果庫存足夠,則會扣減庫存,并記錄庫存已扣減成功,這樣可以保證這個操作冪等,并且保證后續的反查能夠獲得正確的結果

反查的核心代碼如下:

app.GET(BusiAPI+"/QueryPreparedRedis", dtmutil.WrapHandler2(func(c *gin.Context) interface{} {
return MustBarrierFromGin(c).RedisQueryPrepared(rds)
}))

開發人員編寫反查的邏輯很簡單,對于Redis里面的數據,只需要復制粘貼這上面的代碼就行。反查的詳細原理參考二階段消息,二階段消息的文檔里介紹的是數據庫中如何做,而這里則是用Redis來完成類似的反查邏輯,就不詳細說明了。

性能#

從上面的介紹中,可以看到,對于大部分扣減庫存失敗的請求,只需要進行三個Redis操作,1. 注冊全局事務;2. 扣減庫存;3. 修改全局事務為以失敗。這個三個操作都是lua腳本實現。一個普通的redis,每秒大約能夠支持6w個lua腳本操作,照此分析,我們的新架構,理論上每秒能夠支持2w個秒殺請求。我做的性能測試報告顯示,當dtm與扣庫存共享一個redis時,每秒可以輕松完成1.2w個秒殺訂單,達到理論極限值的60%,詳情可以參考后面的性能測試報告

更進一步分析,扣減庫存與全局事務可以使用不同的Redis,那么

  • 扣減庫存:若由單獨一個Redis來支持,那么扣庫存的理論上限值為6w/s,預估的實際值為6*0.6=3.6w/s,如果更進一步,采用 Redis6 的多線程IO,可以獲得更高的性能,大約達到6 * 2.5 * 0.6=9w/s。
  • 全局事務操作:而這里面的dtm只需要部署多組,或者未來使用集群版,就可以提供遠超9w/s的支持。
  • 所以采用新架構的情況下,預計可以達到9w/s的秒殺請求流量

上述的分析還僅僅限于普通云廠商虛擬機上的自己安裝Redis,假如通過簡單的硬件升級,或者使用云廠商提供的Redis,那么Redis能提供更強勁的性能,上述的9w/s還能夠再提高一個臺階。

參考一下阿里雙十一的峰值訂單:58.3萬筆/秒,那么上述預估的9w/s,幾乎足以應對所有的秒殺活動

代碼示例#

完整的可運行的代碼示例,可以參考https://github.com/dtm-labs/dtm-cases/flash

秒殺性能測試詳情

測試的環境,兩臺阿里云主機,類型為:ecs.hfc5.3xlarge 12核 CPU 3.1GHz/3.4GHz PPS 130萬

  • 一臺機器運行Redis
  • 另一臺機器運行測試程序

測試過程:

準備Redis#

選擇虛擬機 A 安裝 Redis

apt-get install -y redis# 修改 /etc/redis/redis.conf# bind 127.0.0.1 => 0.0.0.0systemctl redis restart

準備dtm

選擇虛擬機 B 安裝 dtm

apt update
apt install -y git

wget https://golang.org/dl/go1.17.1.linux-amd64.tar.gz

rm -rf /usr/local/go && tar -C /usr/local -xzf go1.17.1.linux-amd64.tar.gz && cp -f /usr/local/go/bin/go /usr/local/bin/go

git clone https://github.com/dtm-labs/dtm.git && cd dtm && git checkout v1.11.0 && cd bench && make

# 修改 dtm/bench/test-flash-sales.sh

# export BUSI_REDIS=localhost:6379 => 虛擬機A 的私網ip

運行測試

sh test-flash-sales.sh

獲取結果

我的結果顯示,每秒大約能夠完成1.2w個秒殺請求:

Requests per second:    11970.21 [#/sec] (mean)

小結

我們提出了一個全新的秒殺架構,可以保證創建訂單和扣減庫存的原子性,并且預估可以支撐9w/s的秒殺請求流量。幫助大家更好更快的解決秒殺的業務需求。

歡迎訪問我們的項目,并star支持我們:

https://github.com/dtm-labs/dtm

責任編輯:張燕妮 來源: 分布式事務
相關推薦

2022-11-22 17:15:55

高并發NameNode

2017-06-15 08:02:02

庫存扣減查詢

2021-03-16 08:21:29

Spark系統并行

2024-09-23 08:03:13

2018-05-28 16:11:04

阿里云GTS分布式

2018-12-05 09:20:02

MySQL數據庫索引

2010-10-27 09:09:21

NoSQL

2020-11-05 14:12:16

Vue開源項目js框架

2016-11-02 13:51:02

大數據工具

2021-08-26 08:24:33

高并發秒殺系統

2023-07-20 21:41:08

2019-05-05 09:28:59

架構數據查詢

2019-07-29 14:40:26

架構存儲檢索

2019-07-16 08:51:03

熱搜新浪微博數據

2015-03-31 10:44:26

IT人員上萬月薪招不到IT人才

2013-03-07 09:30:51

云成本分析工具云服務亞馬遜云服務

2010-02-22 10:21:22

2025-05-12 04:20:00

Linux系統epoll

2021-11-23 09:00:00

數據庫事務API無代碼

2019-09-16 09:34:39

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美日韩在线免费观看 | 亚洲 欧美 精品 | 婷婷二区| 国产一区91精品张津瑜 | 欧美性网| 国产成人免费视频网站视频社区 | 在线免费观看毛片 | 二区视频 | 国产精品爱久久久久久久 | 91性高湖久久久久久久久_久久99 | 日韩av成人 | 久热国产在线 | 亚洲人成一区二区三区性色 | 亚洲成人一区二区 | 免费黄色在线观看 | 91国产在线播放 | 美女视频黄色的 | 国产91在线精品 | 亚洲精品视频在线播放 | 日韩精品在线免费观看视频 | 欧美精品综合在线 | 久久尤物免费一区二区三区 | 国产高清一区 | 国产乱码精品一区二区三区五月婷 | 一区二区三区四区不卡视频 | 久久久精品一区 | 国产福利网站 | 中文字幕伊人 | 在线观看日本高清二区 | 365夜爽爽欧美性午夜免费视频 | 国产激情视频网址 | 日本啊v在线 | 波多野结衣一区二区 | 日韩人体在线 | 欧美日韩最新 | 日韩伦理一区二区 | 欧美性jizz18性欧美 | 毛片网站在线观看视频 | 成人三级网址 | 久久精品高清视频 | 手机av免费在线 |