小米抢购限流峰值系统「大秒」架构解密2
上文介紹了【年度案例】小米搶購(gòu)限流峰值系統(tǒng)架構(gòu)歷年演進(jìn)歷程?,本文主要介紹最新版「大秒」系統(tǒng)架構(gòu)。
整合的搶購(gòu)限流峰值系統(tǒng)——「大秒」
2014年初,公司決定舉辦一場(chǎng)“米粉節(jié)”活動(dòng),全天6輪活動(dòng),多個(gè)國(guó)家、多款爆品同時(shí)參與搶購(gòu)。業(yè)務(wù)場(chǎng)景將變得更加復(fù)雜,當(dāng)天的并發(fā)壓力也會(huì)有一個(gè)量級(jí)的提升,原有的搶購(gòu)系統(tǒng)已經(jīng)不能適應(yīng)如此復(fù)雜的業(yè)務(wù)場(chǎng)景了。
為此,小米網(wǎng)技術(shù)團(tuán)隊(duì)基于對(duì) golang 應(yīng)對(duì)高并發(fā)、大規(guī)模分布式系統(tǒng)能力的肯定,完全基于 golang,重新設(shè)計(jì)了搶購(gòu)系統(tǒng),也就是我們目前使用的搶購(gòu)限流峰值系統(tǒng)——“大秒”。
在整個(gè)系統(tǒng)設(shè)計(jì)的之初,我們充分考慮了
靈活性及可運(yùn)營(yíng)性;
可運(yùn)維性及可伸縮性;
限流與搶購(gòu)放號(hào)的精準(zhǔn)性;
從大秒第一天誕生到演化至今有很多次重構(gòu)與優(yōu)化,但一直沿用了設(shè)計(jì)之初的結(jié)構(gòu),接下來(lái)我們一起了解下小米網(wǎng)搶購(gòu)限流峰值系統(tǒng)當(dāng)前的架構(gòu)以及填過(guò)的一些坑。
大秒系統(tǒng)的架構(gòu)設(shè)計(jì)
大秒系統(tǒng)主要由如下幾個(gè)模塊構(gòu)成
限流集群 HTTP 服務(wù)
放號(hào)策略集群 Middle 服務(wù)
監(jiān)控?cái)?shù)據(jù)中心 Dcacenter
監(jiān)控管理體系 Master
準(zhǔn)實(shí)時(shí)防刷模塊 antiblack
基礎(chǔ)存儲(chǔ)與日志隊(duì)列服務(wù): Redis 集群、Kafka 集群等
整個(gè)大秒體系中大秒前端模塊 (HTTP/middle/antiblack) 和監(jiān)控?cái)?shù)據(jù)中心使用 golang 開發(fā),大秒監(jiān)控管理體系使用 Python + golang 開發(fā)。
大秒的前端架構(gòu)設(shè)計(jì)
大秒前端的架構(gòu)設(shè)計(jì)從三個(gè)系統(tǒng)展開
限流集群 HTTP 服務(wù)
策略集群 Middle 服務(wù)
準(zhǔn)實(shí)時(shí)反作弊 antiblack 服務(wù)
1、限流集群 HTTP 服務(wù)
搶購(gòu)高峰時(shí),通常會(huì)有幾百萬(wàn)的用戶同時(shí)請(qǐng)求,瞬時(shí)流量非常大,HTTP 集群頂在最前線,接受用戶的請(qǐng)求,將合法的請(qǐng)求發(fā)送的處理隊(duì)列,處理隊(duì)列設(shè)置一定的長(zhǎng)度限制,通常情況下,搶購(gòu)用戶數(shù)與銷售商品的比例在100:1,甚至更高,為了避免系統(tǒng)不被沖垮,保障絕大多數(shù)用戶的體驗(yàn),我們認(rèn)為流量是部分可丟失的,當(dāng)處理隊(duì)列滿時(shí),丟棄入隊(duì)請(qǐng)求;
雖然設(shè)計(jì)上過(guò)載流量是部分可丟棄的,但是策略層處理能力是非常 power 的,即便是需要丟棄流量,也是按流量的惡意程度,逐級(jí)丟棄的,正常用戶購(gòu)買請(qǐng)求不受影響。
我們使用基于規(guī)則的識(shí)別、離線畫像信息、機(jī)器學(xué)習(xí)邏輯回歸等方法,識(shí)別惡意用戶,在系統(tǒng)高負(fù)載的情況下,這部分請(qǐng)求可以優(yōu)先阻擊其發(fā)送到策略層,優(yōu)先處理正常用戶的請(qǐng)求,保障用戶體驗(yàn)過(guò)。
HTTP集群中不同節(jié)點(diǎn)之間的所持用的狀態(tài)數(shù)據(jù)是一致的,處理邏輯也是一致的,所以整個(gè)集群中的任何一個(gè)節(jié)點(diǎn)掛掉,在前端負(fù)載均衡能力下,服務(wù)的準(zhǔn)確性與一致性不受任何影響。
2、策略集群 Middle 服務(wù)
HTTP 模塊將滿足條件用戶的請(qǐng)求按照 uid 哈希的規(guī)則,轉(zhuǎn)發(fā)到 Middle 集群中相應(yīng)的節(jié)點(diǎn),Middle 集群根據(jù)商品放號(hào)策略判斷 (uid:sku:time) 組合是否可以分配購(gòu)買資格,并返回給相應(yīng)的 HTTP 服務(wù);
使用 Middle 服務(wù)本地內(nèi)存維護(hù)用戶的購(gòu)買記錄信息,支持各種購(gòu)買規(guī)則,比如:單次活動(dòng)不限購(gòu)買數(shù)量,單次活動(dòng)僅限購(gòu)買一款商品,單次活動(dòng)每款商品僅限購(gòu)買一次。
我們將 Middle 的放號(hào)邏輯抽象成一個(gè)有限狀態(tài)機(jī),由商品的放號(hào)策略配置閾值來(lái)觸發(fā)放號(hào)狀態(tài)轉(zhuǎn)換,整個(gè)配置由 Master 節(jié)點(diǎn)統(tǒng)一管理與調(diào)度。
為了提升整個(gè)系統(tǒng)的處理能力,我們將用戶狀態(tài)數(shù)據(jù)局部化,單用戶(uid)的所有相關(guān)信息全部路由到一臺(tái) Middle 節(jié)點(diǎn)上處理。
但是有一點(diǎn)風(fēng)險(xiǎn)是,Middle 集群中服務(wù)可能會(huì)出現(xiàn)活動(dòng)過(guò)程中掛掉的風(fēng)險(xiǎn),在搶購(gòu)場(chǎng)景下,商品基本上是瞬時(shí)賣完,為了保障系統(tǒng)的處理能力,我們主要從代碼層面做優(yōu)化,review 代碼邏輯,保證服務(wù)應(yīng)對(duì)異常的處理能力。
雖然理論上存在風(fēng)險(xiǎn),但是在實(shí)際工程中,經(jīng)歷過(guò)幾百次活動(dòng),還沒(méi)出現(xiàn) Middle 節(jié)點(diǎn)掛掉的情況。
3、準(zhǔn)實(shí)時(shí)防刷 antiblack 服務(wù)
基于日志流的防刷架構(gòu),在每臺(tái) HTTP 節(jié)點(diǎn)上部署日志收集 Agent,使用高吞吐量的 Kafka 做日志轉(zhuǎn)儲(chǔ)隊(duì)列,antiblack 模塊實(shí)時(shí)分析用戶請(qǐng)求日志,基于 IP 粒度、Uid 粒度等做防刷。
雖然此處將 antiblack 模塊定義為準(zhǔn)實(shí)時(shí)防刷模塊,但是作弊信息識(shí)別的延遲時(shí)長(zhǎng)在 1 分鐘之內(nèi),其中主要的時(shí)延發(fā)生在日志的轉(zhuǎn)儲(chǔ)過(guò)程中。
大秒的監(jiān)控管理體系
1、監(jiān)控?cái)?shù)據(jù)中心 dcacenter
監(jiān)控?cái)?shù)據(jù)中心數(shù)據(jù)種類
(1) 業(yè)務(wù)級(jí)數(shù)據(jù):過(guò)大秒的商品配置數(shù)據(jù)與實(shí)時(shí)狀態(tài)數(shù)據(jù),當(dāng)前活動(dòng)的配置與狀態(tài)數(shù)據(jù)等;
(2) 系統(tǒng)級(jí)數(shù)據(jù): 大秒前端服務(wù)集群通信地址配置,限流隊(duì)列初始長(zhǎng)度配置,系統(tǒng)服務(wù)資源占用情況,包括:CPU、MEM、連接數(shù)等;
數(shù)據(jù)采集方式
同時(shí)使用push和pull模式采集業(yè)務(wù)級(jí)監(jiān)控?cái)?shù)據(jù)和系統(tǒng)級(jí)監(jiān)控?cái)?shù)據(jù),業(yè)務(wù)級(jí)數(shù)據(jù)越實(shí)時(shí)越好,做到1秒采集處理,3秒可視化;
對(duì)于 HTTP 節(jié)點(diǎn)和 Middle 節(jié)點(diǎn)采用pull的模式拉去系統(tǒng)監(jiān)控?cái)?shù)據(jù)和業(yè)務(wù)監(jiān)控?cái)?shù)據(jù),優(yōu)點(diǎn)如下
(1) 靈活性高
由數(shù)據(jù)中心控制監(jiān)控?cái)?shù)據(jù)采集的粒度,在數(shù)據(jù)中心處理能力既定的情況下,可以根據(jù)前端集群的伸縮規(guī)模,靈活的調(diào)整數(shù)據(jù)采集的粒度,比如米粉節(jié)時(shí),大秒前端集群擴(kuò)容至過(guò)百臺(tái),管理的過(guò)大秒商品的數(shù)量在400個(gè)左右,業(yè)務(wù)級(jí)監(jiān)控?cái)?shù)據(jù)量很大,此時(shí)監(jiān)控?cái)?shù)據(jù)采集時(shí)間間隔很容易降配至 2s。
對(duì)于除Http服務(wù)和Middle服務(wù)之外的服務(wù)集群,如:redis,管理平臺(tái)各個(gè)模塊等可以使用監(jiān)控?cái)?shù)據(jù)采集agent,將采集到的數(shù)據(jù)周期性的push到redis隊(duì)列,dcacenter采集協(xié)程實(shí)時(shí)的從redis隊(duì)列中拉去消息,對(duì)于基礎(chǔ)服務(wù)以及python實(shí)現(xiàn)的服務(wù),增加了監(jiān)控?cái)?shù)據(jù)采集靈活性。
(2) 增強(qiáng)服務(wù)的可靠性與伸縮性
大秒在設(shè)計(jì)之初采用push的方式,在每臺(tái)前端機(jī)器上部署一個(gè)數(shù)據(jù)采集agent,agent和大秒前端服務(wù)同時(shí)alive,才代表?yè)屬?gòu)系統(tǒng)健康運(yùn)行。這樣即增加了系統(tǒng)的不穩(wěn)定因素,由不利于系統(tǒng)的伸縮,將監(jiān)控?cái)?shù)據(jù)采集邏輯內(nèi)置到前端golang程序中,提供tcp管理端口,在數(shù)據(jù)中心使用pull方式采集數(shù)據(jù),很好的解決了這個(gè)問(wèn)題。減少了服務(wù)的數(shù)量,增強(qiáng)了整個(gè)系統(tǒng)的可靠性與伸縮性。
數(shù)據(jù)ETL與數(shù)據(jù)緩存
dcacenter同時(shí)負(fù)責(zé)將采集到的業(yè)務(wù)級(jí)數(shù)據(jù)及系統(tǒng)級(jí)監(jiān)控?cái)?shù)據(jù),實(shí)時(shí)清洗,提取,轉(zhuǎn)換,結(jié)構(gòu)化,并將結(jié)構(gòu)化的數(shù)據(jù)存儲(chǔ)在自身內(nèi)存中,定制通信協(xié)議(golang實(shí)現(xiàn)類redis通信協(xié)議),作為一個(gè)數(shù)據(jù)中心,對(duì)整個(gè)管理體系Master及其他系統(tǒng)提供實(shí)時(shí)數(shù)據(jù)支持。
將dcacenter直接作為數(shù)據(jù)中心,主要是出于數(shù)據(jù)的實(shí)時(shí)性考慮,省去中間轉(zhuǎn)儲(chǔ)環(huán)節(jié),上層可視化系統(tǒng)、自動(dòng)化活動(dòng)控制系統(tǒng)、規(guī)則引擎系統(tǒng)等可以第一時(shí)間獲得前端實(shí)時(shí)的銷售狀態(tài)數(shù)據(jù)及服務(wù)的狀態(tài)數(shù)據(jù)。
2、監(jiān)控管理中心 Master
監(jiān)控管理中心的主要模塊如下。
a.倉(cāng)儲(chǔ)庫(kù)存同步服務(wù)StockKeeper
同步商品的倉(cāng)儲(chǔ)系統(tǒng)中的實(shí)時(shí)庫(kù)存到秒殺系統(tǒng),大秒系統(tǒng)擁有雙庫(kù)存保障,一個(gè)是實(shí)時(shí)倉(cāng)儲(chǔ)庫(kù)存,一個(gè)是虛擬庫(kù)存也就是資格號(hào),在搶購(gòu)場(chǎng)景下只有當(dāng)兩個(gè)庫(kù)存都有貨時(shí),才能正常銷售。
b.商品策略控制器PolicyKeeper
基于相應(yīng)的策略觸發(fā)器(時(shí)間區(qū)間與庫(kù)存區(qū)間),當(dāng)策略觸發(fā)時(shí),比如12點(diǎn)整,搶購(gòu)開始,為相應(yīng)的商品配置策略,并向大秒前端廣播商品配置變更命令,在通信基礎(chǔ)模塊的保障下,整個(gè)過(guò)程秒級(jí)內(nèi)完成。
c.活動(dòng)自動(dòng)化控制ActKeeper
基于監(jiān)控?cái)?shù)據(jù)中心獲取大秒前端的實(shí)時(shí)銷售數(shù)據(jù),自動(dòng)化的控制活動(dòng)中的各個(gè)狀態(tài),活動(dòng)開始前逐層打開開關(guān),活動(dòng)開始時(shí)打開最后開關(guān),活動(dòng)過(guò)程中維護(hù)活動(dòng)的售罄狀態(tài),活動(dòng)結(jié)束后初始化,整個(gè)搶購(gòu)活動(dòng)的過(guò)程無(wú)需人工介入;
d.數(shù)據(jù)可視化
從監(jiān)控?cái)?shù)據(jù)中心提取實(shí)時(shí)的結(jié)構(gòu)化系統(tǒng)級(jí)監(jiān)控?cái)?shù)據(jù)和業(yè)務(wù)級(jí)監(jiān)控?cái)?shù)據(jù),將活動(dòng)過(guò)程中的詳細(xì)數(shù)據(jù)實(shí)時(shí)可視化到管理頁(yè)面上,讓運(yùn)營(yíng)與銷售以及大秒管理員能夠及時(shí)了解當(dāng)前活動(dòng)狀態(tài),并人工干預(yù)活動(dòng);
e.監(jiān)控規(guī)則引擎
監(jiān)控規(guī)則引擎建立在監(jiān)控?cái)?shù)據(jù)中心之上,根據(jù)結(jié)構(gòu)化監(jiān)控?cái)?shù)據(jù)判斷當(dāng)前整個(gè)搶購(gòu)系統(tǒng)的狀態(tài),及時(shí)報(bào)警,以及半自動(dòng)化控制。
f.其他
大秒管理端管理大秒前端所有的數(shù)據(jù)、配置以及狀態(tài),Master體系提供了詳細(xì)的管理工具與自動(dòng)化服務(wù)。如果清理大秒前端Middle服務(wù)中的用戶購(gòu)買信息等。
3、大秒配置管理數(shù)據(jù)流
整個(gè)搶購(gòu)系統(tǒng)由 Master 體系中各個(gè)服務(wù)做統(tǒng)一的控制的,Master 控制商品狀態(tài)及配置數(shù)據(jù)的變更,控制當(dāng)前活動(dòng)的狀態(tài),控制商品放號(hào)的策略等。
為了保證時(shí)效性,商品、活動(dòng)、系統(tǒng)等配置狀態(tài)的變更都需要將變更命令廣播前端集群,這期間發(fā)生了大量的分布式系統(tǒng)間通信,為了保障命令及時(shí)下行,我們提取出了命令轉(zhuǎn)發(fā)服務(wù):MdwRouter,用于廣播控制命令到大秒前端集群。該服務(wù)模塊維護(hù)了到大秒前端長(zhǎng)連接,接收 Master 下發(fā)的控制命令,并瞬時(shí)廣播,保障了整個(gè)控制流的處理能力。
舉個(gè)例子,2015 年米粉節(jié),我們單機(jī)房大秒集群的規(guī)模在過(guò)百臺(tái)級(jí)別,假設(shè)為 100 臺(tái),管理的獨(dú)立的商品id的數(shù)量在 400 個(gè)左右,在這種量級(jí)的活動(dòng)下,商品的放行策略是批量管理的,比如我們根據(jù)后端交易系統(tǒng)的壓力反饋,調(diào)整所有商品的放行速度,這時(shí)候需要廣播的命令條數(shù)在: 100*400=40000 級(jí)別,Mdwrouter 很好的保障了系統(tǒng)命令下行的速度,秒級(jí)完成命令下行。
小米搶購(gòu)技術(shù)架構(gòu)
1、小米搶購(gòu)服務(wù)閉環(huán)設(shè)計(jì)
小米網(wǎng)搶購(gòu)系統(tǒng)服務(wù)見(jiàn)上圖
bigtap體系中大秒前端服務(wù)負(fù)責(zé)搶購(gòu)時(shí)限流放號(hào),并控制放號(hào)策略以及維護(hù)用戶在本地緩存中的購(gòu)買記錄。
cart服務(wù)驗(yàn)證token的有效性,并向counter服務(wù)發(fā)起銷量驗(yàn)證請(qǐng)求;
counter服務(wù)是整個(gè)搶購(gòu)系統(tǒng)最終的計(jì)數(shù)器, 海量的請(qǐng)求在bigtap服務(wù)的作用下已經(jīng)被限制在可以承受的壓力范圍內(nèi),并且復(fù)雜的放號(hào)策略已經(jīng)在大秒Middle服務(wù)中實(shí)現(xiàn),counter只負(fù)責(zé)最終的計(jì)數(shù)即可。counter服務(wù)采用redis記錄相應(yīng)商品的放號(hào)情況,根據(jù)預(yù)設(shè)的銷量,判斷當(dāng)前請(qǐng)求加購(gòu)物車商品是否有庫(kù)存余量,并維護(hù)商品銷量;
bigtap體系中的dcacenter服務(wù)實(shí)時(shí)采集商品銷量,Master中活動(dòng)自動(dòng)化控制服務(wù)依據(jù)商品銷量判斷當(dāng)前商品是否售罄,售罄則通過(guò)設(shè)置商品的售罄狀態(tài),并通知大秒前端;
2、2015年米粉節(jié)介紹
從上述整個(gè)服務(wù)閉環(huán)設(shè)計(jì)可以看出,大秒的功能完全可以抽象成限流系統(tǒng),只有在處理?yè)屬?gòu)活動(dòng)時(shí),數(shù)據(jù)的管理與一致性要求才使整個(gè)系統(tǒng)變得復(fù)雜。
2015年米粉節(jié),我們完全使用大秒的限流功能,不限用戶的購(gòu)買數(shù)量,很便捷的將系統(tǒng)部署在兩個(gè)機(jī)房,一個(gè)物理機(jī)房,一個(gè)公有云集群,兩者同時(shí)服務(wù),大秒系統(tǒng)作為整個(gè)商城的最前端,能夠根據(jù)后端服務(wù)的壓力狀態(tài),瞬時(shí)調(diào)整整個(gè)集群放行流量大小,非常好的保障了整個(gè)米粉節(jié)的正常舉行。
在上述文章中,已經(jīng)介紹了一些服務(wù)設(shè)計(jì)的出發(fā)點(diǎn),每一次優(yōu)化的背后,都至少有一次慘痛的經(jīng)歷。
大秒系統(tǒng)架構(gòu)的幾點(diǎn)經(jīng)驗(yàn)總結(jié)
1、Golang GC 優(yōu)化方法
我們從 golang 1.2 版本開始在線上搶購(gòu)系統(tǒng)中大規(guī)模使用,最初上線的 TC 限流集群在搶購(gòu)的過(guò)程中通過(guò)過(guò)載重啟的方式瘸腿前行。
在當(dāng)前的大秒系統(tǒng)中,對(duì)于限流集群主要是 goroutine 資源、HTTP 協(xié)議數(shù)據(jù)結(jié)構(gòu)、TCP 連接讀寫緩沖區(qū)等頻繁動(dòng)態(tài)開銷,造成內(nèi)存 GC 壓力大,在現(xiàn)有 GC 能力下,我們對(duì) GC 優(yōu)化從以下幾個(gè)方面考慮
減少垃圾產(chǎn)生:降低數(shù)據(jù)結(jié)構(gòu)或者緩沖區(qū)的開銷;
手動(dòng)管理內(nèi)存:使用內(nèi)存池,手動(dòng)管理內(nèi)存;
臟數(shù)據(jù)盡快釋放,增大空閑內(nèi)存比。
我們使用了以下 3 種 golang GC 優(yōu)化方法
1)定制 golang HTTP 包
調(diào)整 HTTP 協(xié)議 conn 數(shù)據(jù)結(jié)構(gòu)默認(rèn)分配讀寫緩沖區(qū)的大小,以及手動(dòng)維護(hù)讀寫緩存池,減少動(dòng)態(tài)開辟內(nèi)存的次數(shù),降低 GC 壓力。
在 Go 語(yǔ)言原生的 HTTP 包中會(huì)為每個(gè)請(qǐng)求默認(rèn)分配 8KB 的緩沖區(qū),讀、寫緩沖區(qū)各 4K。而在我們的服務(wù)場(chǎng)景中只有 GET 請(qǐng)求,服務(wù)需要的信息都包含在 HTTP header 中,并沒(méi)有 body,實(shí)際上不需要如此大的內(nèi)存進(jìn)行存儲(chǔ),所以我們調(diào)小了讀寫緩沖區(qū),將讀緩沖區(qū)調(diào)小到 1K,寫緩沖區(qū)調(diào)小到 32B,golang 的 bufio 在寫緩沖區(qū)較小時(shí),會(huì)直接寫出。
從 golang 1.3 開始,HTTP 原生的包中已經(jīng)使用了sync.Pool 維護(hù)讀寫緩存池,但是 sync.Pool 中的數(shù)據(jù)會(huì)被自動(dòng)的回收,同樣會(huì)小量的增加 GC 壓力,我們此處自己維護(hù)緩存池來(lái)減少垃圾回收。
2)加快資源釋放
原生的 HTTP 包默認(rèn)使用 keep-alive 的方式,小米搶購(gòu)場(chǎng)景下,惡意流量占用了大量的連接,我們通過(guò)主動(dòng)設(shè)置 response header 的 connection 為 close 來(lái)主動(dòng)關(guān)閉惡意連接,加快 goroutine 資源的釋放。
3)升級(jí)版本
跟進(jìn)使用 golang 最新的版本,golang 后續(xù)的每個(gè)版本都有針對(duì) GC 能力的調(diào)整。
得益于開源技術(shù)力量,以及大秒系統(tǒng)在 GC 優(yōu)化上的努力,以及系統(tǒng)層的調(diào)優(yōu),我們的 HTTP 限流層已經(jīng)可以余量前行。
從上圖可以看出,得益于 GC 的優(yōu)化,2015 年米粉節(jié),每輪搶購(gòu),HTTP 服務(wù)的內(nèi)存不會(huì)有特別大的抖動(dòng)。
2、HTTP 服務(wù)器內(nèi)存調(diào)優(yōu)之操作系統(tǒng)參數(shù)調(diào)整
我們的服務(wù)場(chǎng)景下絕大多數(shù)的請(qǐng)求數(shù)都是惡意請(qǐng)求,惡意請(qǐng)求通常都是短連接請(qǐng)求,大量的短連接會(huì)處于 timewait 狀態(tài),幾分鐘之后才會(huì)釋放,這樣會(huì)占用大量的資源,通過(guò)調(diào)整內(nèi)核參數(shù),盡快釋放或者重用 timewait 狀態(tài)的連接,減少資源的開銷。
具體參數(shù)調(diào)整如下:
<code data-origin=""
高并發(fā)場(chǎng)景下,操作系統(tǒng)層網(wǎng)絡(luò)模塊參數(shù)的調(diào)整,會(huì)起到事半功倍的效果。<code data-origin=""
<code data-origin=""
3、沒(méi)有通信就談不上分布式系統(tǒng)<code data-origin=""
整個(gè)大秒系統(tǒng)模塊之間面臨的通信要求是非常苛刻的,Master 節(jié)點(diǎn)與 HTTP、Middle 節(jié)點(diǎn)要頻繁的廣播控制命令,dcacenter要實(shí)時(shí)的收集 HTTP、Middle 節(jié)點(diǎn)的監(jiān)控管理數(shù)據(jù),HTTP 要將用戶的購(gòu)買請(qǐng)求路由到 Middle 節(jié)點(diǎn)之間,Middle 節(jié)點(diǎn)要返回給相應(yīng)的 HTTP 節(jié)點(diǎn)放號(hào)信息;<code data-origin=""
<code data-origin=""
我們基于 TCP 定制了簡(jiǎn)單、高效的通信協(xié)議,對(duì)于 HTTP 層和 Middle 層通信,通信模塊能夠合并用戶請(qǐng)求,減少通信開銷,保障整個(gè)大秒系統(tǒng)的高效通信,增加服務(wù)的處理能力。<code data-origin=""
<code data-origin=""
4、服務(wù)閉環(huán)設(shè)計(jì)<code data-origin=""
從上述搶購(gòu)的服務(wù)閉環(huán)架構(gòu)中可以看出,整個(gè)搶購(gòu)流程處理bigtap系統(tǒng)之外,還有 cart 服務(wù),中心 counter 服務(wù),這三者與 bigtap 系統(tǒng)構(gòu)成了一個(gè)數(shù)據(jù)流的閉環(huán),但是在大秒最初的設(shè)計(jì)中,是沒(méi)有 counter 服務(wù)的,Middle層策略集群在放號(hào)的同時(shí),又作為計(jì)數(shù)服務(wù)存在,但是整個(gè)搶購(gòu)流程卻是以商品加入購(gòu)物車代表最終的搶購(gòu)成功,這在設(shè)計(jì)上有一個(gè)漏洞,假如 bigtap 計(jì)數(shù)了,但是token 并沒(méi)有請(qǐng)求加購(gòu)物車成功,這是不合理的。為了保證整個(gè)系統(tǒng)的準(zhǔn)確性,我們?cè)黾恿擞?jì)數(shù)器服務(wù),計(jì)數(shù)操作發(fā)生在加購(gòu)物車下游,bigtap 在從計(jì)數(shù)中心取出商品實(shí)時(shí)銷量,由此,構(gòu)成一個(gè)服務(wù)閉環(huán)設(shè)計(jì)。在提升了系統(tǒng)的準(zhǔn)確性,同時(shí)也保證了用戶體驗(yàn)。<code data-origin=""
<code data-origin=""
5、技術(shù)的選擇要可控<code data-origin=""
我們一開始選擇使用 ZooKeeper 存放商品的配置信息,在搶購(gòu)活動(dòng)的過(guò)程伴隨著大量的配置變更操作,ZooKeeper 的 watch 機(jī)制不適合用于頻繁寫的場(chǎng)景,造成消息丟失,大秒前端集群狀態(tài)與配置不一致。<code data-origin=""
<code data-origin=""
后來(lái),我們將所有的配置信息存放在 Redis 中,基于通信模塊,在發(fā)生配置變更時(shí),伴隨著一次配置項(xiàng)變更的廣播通知,大秒前端根據(jù)相應(yīng)的通知命令,拉取 Redis 中相應(yīng)的配置信息,變更內(nèi)存中配置及狀態(tài)。<code data-origin=""
<code data-origin="" 大秒的幾點(diǎn)設(shè)計(jì)原則
<code data-origin=""
分治是解決復(fù)雜問(wèn)題的通則;我們從第一代搶購(gòu)系統(tǒng)演進(jìn)到當(dāng)前的大秒系統(tǒng),衍生出了很多服務(wù),每個(gè)服務(wù)的產(chǎn)生都是為了專門解決一個(gè)問(wèn)題,分離整個(gè)復(fù)雜系統(tǒng),針對(duì)每個(gè)服務(wù)需要解決的問(wèn)題,各個(gè)擊破,重點(diǎn)優(yōu)化。由此,才保障了秒殺體系整體性能、可靠性的提升;<code data-origin=""
<code data-origin=""
服務(wù)化設(shè)計(jì);系統(tǒng)解耦,增強(qiáng)系統(tǒng)的伸縮性與可靠性;<code data-origin=""
<code data-origin=""
無(wú)狀態(tài)設(shè)計(jì),增強(qiáng)系統(tǒng)的伸縮性,提升集群整體處理能力;<code data-origin=""
<code data-origin=""
狀態(tài)數(shù)據(jù)局部化,相對(duì)于數(shù)據(jù)中心化,提升集群整體處理能力。<code data-origin=""
<code data-origin=""
中心化監(jiān)控管理,熱備部署,既保證了服務(wù)的高可用性,又能夠提升開發(fā)和管理效率。隨著集群規(guī)模的增大以及管理數(shù)據(jù)的增多,分離管理信息到不同的數(shù)據(jù)管理節(jié)點(diǎn),實(shí)現(xiàn)管理能力的擴(kuò)容。通常情況下,中小型分布式系統(tǒng),單機(jī)管理能力即可滿足。<code data-origin=""
<code data-origin=""
避免過(guò)度設(shè)計(jì),過(guò)早的優(yōu)化;小步快跑,頻繁迭代。<code data-origin=""
<code data-origin=""
沒(méi)有華麗的技術(shù),把細(xì)小的點(diǎn)做好,不回避問(wèn)題,特別是在高并發(fā)系統(tǒng)中,一個(gè)細(xì)小的問(wèn)題,都可以引發(fā)整個(gè)服務(wù)雪崩。<code data-origin=""
<code data-origin="" ( generated by haroopad )
<code data-origin=""
<code data-origin="" Q&A
<code data-origin=""
1、實(shí)時(shí)倉(cāng)庫(kù)怎么避免超賣?<code data-origin=""
我們的搶購(gòu)系統(tǒng)以加入購(gòu)物車代表購(gòu)買成功,因?yàn)橛脩粢I配件等,庫(kù)存是由計(jì)數(shù)器控制的,先限流,在計(jì)數(shù),在可控的并發(fā)量情況下,不會(huì)出現(xiàn)超賣。<code data-origin=""
<code data-origin=""
2、有了放號(hào)系統(tǒng)計(jì)算放號(hào)規(guī)則,為什么還需要一個(gè)外圍的 counter?<code data-origin=""
主要是 bigtap 到 cart 的環(huán)節(jié) token 有丟失,在 cart 之后再加一個(gè)計(jì)數(shù)器,保障銷量,bigtap 再讀取計(jì)數(shù)器的數(shù)據(jù)控制前端商品銷售狀態(tài),整個(gè)延遲不超 3s。<code data-origin=""
<code data-origin=""
3、HTTP 集群通過(guò) uuid hash 到 Middle,如果目標(biāo) Middle 已經(jīng)死掉怎么應(yīng)對(duì)?<code data-origin=""
這個(gè)問(wèn)題在文章中有強(qiáng)調(diào),在我們的場(chǎng)景下,商品迅速賣完,這塊沒(méi)有做高可用,只是從代碼層面做 review,完善異常處理機(jī)制,并且通常情況下,middle 負(fù)載不是特別高,幾百次活動(dòng)下來(lái),還沒(méi)出現(xiàn)過(guò)掛掉情況。<code data-origin=""
<code data-origin=""
4、防刷系統(tǒng)是離線計(jì)算的嗎,還是有在線識(shí)別的策略?<code data-origin=""
基于日志,準(zhǔn)實(shí)時(shí),因?yàn)檎?qǐng)求量比較大,專門搭了一套 Kafka 服務(wù)轉(zhuǎn)儲(chǔ)日志,基于 golang 開發(fā) logcollect 與 antiblack 模塊,可以達(dá)到很高的處理性能。<code data-origin=""
<code data-origin=""
5、請(qǐng)問(wèn)如何模擬大量請(qǐng)求做測(cè)試?<code data-origin=""
我們遇到的情況是,由于壓測(cè)機(jī)單機(jī)端口限制造成早期不好測(cè)試,我們這邊壓測(cè)團(tuán)隊(duì)基于開源模塊開發(fā)了能夠模擬虛擬IP的模塊,打破了單機(jī)端口的限制。<code data-origin=""
<code data-origin=""
6、即使廣播和 Redis 拉取商品配置信息,仍有可能配置信息不一致如何解決?<code data-origin=""
這個(gè)主要是商品的配置和狀態(tài)信息,不涉及到強(qiáng)一致性要求的場(chǎng)景,我們這樣可以在秒級(jí)達(dá)到最終一致性。<code data-origin=""
<code data-origin=""
想更多了解小米搶購(gòu)的架構(gòu),可閱讀搶購(gòu)系統(tǒng)架構(gòu)演進(jìn)介紹 【年度案例】小米搶購(gòu)限流峰值系統(tǒng)架構(gòu)歷年演進(jìn)歷程<code data-origin=""來(lái)源:https://mp.weixin.qq.com/s/enRMYmss6Y5AUCvAMfpHtA
總結(jié)
以上是生活随笔為你收集整理的小米抢购限流峰值系统「大秒」架构解密2的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 有钱花暂时不能提供借款服务 可能这些原
- 下一篇: 《程序员》2014年11月刊:电商峰值系