无码专区一区人妻|人妻系列一区二区播放|国产免费牲交大片高清|日韩黄色无码一区二区三区|久久精品国产亚洲二区三区|欧美综合在线一区二区三区|精品无码国产自产拍在线观看蜜|999zyz精品视频在线播放

您當前的位置 :寧夏資訊網 > 資訊 >  內容正文
投稿

小米手機越來越容易搶的背后:搶購系統(tǒng)的優(yōu)化!

寧夏資訊網 2021-02-19 15:56:33 來源: 閱讀:-

我和同事們對小米網的搶購系統(tǒng)做了最后的檢查與演練。幾個小時后,小米網今年開年來最重要的一次大型活動“米粉節(jié)”就要開始了。

這次米粉節(jié)活動,是小米電商的成人禮,是一次重要的考試。小米網從網站前端、后臺系統(tǒng)、倉儲物流、售后等各個環(huán)節(jié),都將接受一次全面的壓力測試。

10點整,一波流量高峰即將到來,幾百萬用戶將準點擠入小米網的服務器。而首先迎接壓力沖擊的,就是擋在最前面的搶購系統(tǒng)。

小米手機越來越容易搶的背后:搶購系統(tǒng)的優(yōu)化


而這個搶購系統(tǒng)是重新開發(fā)、剛剛上線不久的,這是它第一次接受這樣嚴峻的考驗。

系統(tǒng)能不能頂住壓力?能不能順暢正確地執(zhí)行業(yè)務邏輯?這些問題不到搶購高峰那一刻,誰都不能百分百確定。

9點50分,流量已經爬升得很高了;10點整,搶購系統(tǒng)自動開啟,購物車中已經順利加入了搶購商品。

一兩分鐘后,熱門的搶購商品已經售罄自動停止搶購。搶購系統(tǒng)抗住了壓力。

我長舒一口氣,之前積累的壓力都消散了。我坐到角落的沙發(fā)里,默默回想搶購系統(tǒng)所經歷的那些驚心動魄的故事。這可真是一場很少人有機會經歷的探險呢。

搶購系統(tǒng)是怎樣誕生的

時間回到2011年底。小米公司在這一年8月16日首次發(fā)布了手機,立刻引起了市場轟動。隨后,在一天多的時間內預約了30萬臺。之后的幾個月,這30萬臺小米手機通過排號的方式依次發(fā)貨,到當年年底全部發(fā)完。

然后便是開放購買。最初的開放購買直接在小米的商城系統(tǒng)上進行,但我們那時候完全低估了“搶購”的威力。瞬間爆發(fā)的平常幾十倍流量迅速淹沒了小米網商城服務器,數(shù)據(jù)庫死鎖、網頁刷新超時,用戶購買體驗非常差。

市場需求不等人,一周后又要進行下一輪開放搶購。一場風暴就等在前方,而我們只有一周的時間了,整個開發(fā)部都承擔著巨大的壓力。

小米網可以采用的常規(guī)優(yōu)化手段并不太多,增加帶寬、服務器、尋找代碼中的瓶頸點優(yōu)化代碼。但是,小米公司只是一家剛剛成立一年多的小公司,沒有那么多的服務器和帶寬。而且,如果代碼中有瓶頸點,即使能增加一兩倍的服務器和帶寬,也一樣會被瞬間爆發(fā)的幾十倍負載所沖垮。而要優(yōu)化商城的代碼,時間上已沒有可能。電商網站很復雜,說不定某個不起眼的次要功能,在高負載情況下就會成為瓶頸點拖垮整個網站。

這時開發(fā)組面臨一個選擇,是繼續(xù)在現(xiàn)有商城上優(yōu)化,還是單獨搞一套搶購系統(tǒng)?我們決定冒險一試,我和幾個同事一起突擊開發(fā)一套獨立的搶購系統(tǒng),希望能夠絕境逢生。

擺在我們面前的是一道似乎無解的難題,它要達到的目標如下:

  • 只有一周時間,一周內完成設計、開發(fā)、測試、上線;
  • 失敗的代價無法承受,系統(tǒng)必須順暢運行;
  • 搶購結果必須可靠;
  • 面對海量用戶的并發(fā)搶購,商品不能賣超;
  • 一個用戶只能搶一臺手機;
  • 用戶體驗盡量好些。


設計方案就是多個限制條件下求得的解。時間、可靠性、成本,這是我們面臨的限制條件。要在那么短的時間內解決難題,必須選擇最簡單可靠的技術,必須是經過足夠驗證的技術,解決方案必須是最簡單的。

在高并發(fā)情況下,影響系統(tǒng)性能的一個關鍵因素是:數(shù)據(jù)的一致性要求。在前面所列的目標中,有兩項是關于數(shù)據(jù)一致性的:商品剩余數(shù)量、用戶是否已經搶購成功。如果要保證嚴格的數(shù)據(jù)一致性,那么在集群中需要一個中心服務器來存儲和操作這個值。這會造成性能的單點瓶頸。

在分布式系統(tǒng)設計中,有一個CAP原理?!耙恢滦?、可用性、分區(qū)容忍性”三個要素最多只能同時實現(xiàn)兩點,不可能三者兼顧。我們要面對極端的爆發(fā)流量負載,分區(qū)容忍性和可用性會非常重要,因此決定犧牲數(shù)據(jù)的強一致性要求。

做出這個重要的決定后,剩下的設計決定就自然而然地產生了:

  1. 技術上要選擇最可靠的,因為團隊用PHP的居多,所以系統(tǒng)使用PHP開發(fā);
  2. 搶資格過程要最簡化,用戶只需點一個搶購按鈕,返回結果表示搶購成功或者已經售罄;
  3. 對搶購請求的處理盡量簡化,將I/O操作控制到最少,減少每個請求的時間;
  4. 盡量去除性能單點,將壓力分散,整體性能可以線性擴展;
  5. 放棄數(shù)據(jù)強一致性要求,通過異步的方式處理數(shù)據(jù)。


最后的系統(tǒng)原理見后面的第一版搶購系統(tǒng)原理圖(圖1)。


小米手機越來越容易搶的背后:搶購系統(tǒng)的優(yōu)化



圖1 第一版搶購系統(tǒng)原理圖


系統(tǒng)基本原理:在PHP服務器上,通過一個文件來表示商品是否售罄。如果文件存在即表示已經售罄。PHP程序接收用戶搶購請求后,查看用戶是否預約以及是否搶購過,然后檢查售罄標志文件是否存在。對預約用戶,如果未售罄并且用戶未搶購成功過,即返回搶購成功的結果,并記錄一條日志。日志通過異步的方式傳輸?shù)街行目刂乒?jié)點,完成記數(shù)等操作。

最后,搶購成功用戶的列表異步導入商場系統(tǒng),搶購成功的用戶在接下來的幾個小時內下單即可。這樣,流量高峰完全被搶購系統(tǒng)擋住,商城系統(tǒng)不需要面對高流量。

在這個分布式系統(tǒng)的設計中,對持久化數(shù)據(jù)的處理是影響性能的重要因素。我們沒有選擇傳統(tǒng)關系型數(shù)據(jù)庫,而是選用了Redis服務器。選用Redis基于下面幾個理由。

  1. 首先需要保存的數(shù)據(jù)是典型的Key/Value對形式,每個UID對應一個字符串數(shù)據(jù)。傳統(tǒng)數(shù)據(jù)庫的復雜功能用不上,用KV庫正合適。
  2. Redis的數(shù)據(jù)是in-memory的,可以極大提高查詢效率。
  3. Redis具有足夠用的主從復制機制,以及靈活設定的持久化操作配置。這兩點正好是我們需要的。


在整個系統(tǒng)中,最頻繁的I/O操作,就是PHP對Redis的讀寫操作。如果處理不好,Redis服務器將成為系統(tǒng)的性能瓶頸。

系統(tǒng)中對Redis的操作包含三種類型的操作:查詢是否有預約、是否搶購成功、寫入搶購成功狀態(tài)。為了提升整體的處理能力,可采用讀寫分離方式。

所有的讀操作通過從庫完成,所有的寫操作只通過控制端一個進程寫入主庫。

在PHP對Redis服務器的讀操作中,需要注意的是連接數(shù)的影響。如果PHP是通過短連接訪問Redis服務器的,則在高峰時有可能堵塞Redis服務器,造成雪崩效應。這一問題可以通過增加Redis從庫的數(shù)量來解決。

而對于Redis的寫操作,在我們的系統(tǒng)中并沒有壓力。因為系統(tǒng)是通過異步方式,收集PHP產生的日志,由一個管理端的進程來順序寫入Redis主庫。

另一個需要注意的點是Redis的持久化配置。用戶的預約信息全部存儲在Redis的進程內存中,它向磁盤保存一次,就會造成一次等待。嚴重的話會導致?lián)屬徃叻鍟r系統(tǒng)前端無法響應。因此要盡量避免持久化操作。我們的做法是,所有用于讀取的從庫完全關閉持久化,一個用于備份的從庫打開持久化配置。同時使用日志作為應急恢復的保險措施。

整個系統(tǒng)使用了大約30臺服務器,其中包括20臺PHP服務器,以及10臺Redis服務器。在接下來的搶購中,它順利地抗住了壓力?;叵肫甬敃r的場景,真是非常的驚心動魄。

小米手機越來越容易搶的背后:搶購系統(tǒng)的優(yōu)化


第二版搶購系統(tǒng)

經過了兩年多的發(fā)展,小米網已經越來越成熟。公司準備在2014年4月舉辦一次盛大的“米粉節(jié)”活動。這次持續(xù)一整天的購物狂歡節(jié)是小米網電商的一次成人禮。商城前端、庫存、物流、售后等環(huán)節(jié)都將經歷一次考驗。

對于搶購系統(tǒng)來說,最大的不同就是一天要經歷多輪搶購沖擊,而且有多種不同商品參與搶購。我們之前的搶購系統(tǒng),是按照一周一次搶購來設計及優(yōu)化的,根本無法支撐米粉節(jié)復雜的活動。而且經過一年多的修修補補,第一版搶購系統(tǒng)積累了很多的問題,正好趁此機會對它進行徹底重構。

第二版系統(tǒng)主要關注系統(tǒng)的靈活性與可運營性(圖2)。對于高并發(fā)的負載能力,穩(wěn)定性、準確性這些要求,已經是基礎性的最低要求了。我希望將這個系統(tǒng)做得可靈活配置,支持各種商品各種條件組合,并且為將來的擴展打下良好的基礎。


小米手機越來越容易搶的背后:搶購系統(tǒng)的優(yōu)化



圖2 第二版系統(tǒng)總體結構圖


在這一版中,搶購系統(tǒng)與商城系統(tǒng)依然隔離,兩個系統(tǒng)之間通過約定的數(shù)據(jù)結構交互,信息傳遞精簡。通過搶購系統(tǒng)確定一個用戶搶得購買資格后,用戶自動在商城系統(tǒng)中將商品加入購物車。

在之前第一版搶購系統(tǒng)中,我們后來使用Go語言開發(fā)了部分模塊,積累了一定的經驗。因此第二版系統(tǒng)的核心部分,我們決定使用Go語言進行開發(fā)。

我們可以讓Go程序常駐內存運行,各種配置以及狀態(tài)信息都可以保存在內存中,減少I/O操作開銷。對于商品數(shù)量信息,可以在進程內進行操作。不同商品可以分別保存到不同的服務器的Go進程中,以此來分散壓力,提升處理速度。

系統(tǒng)服務端主要分為兩層架構,即HTTP服務層和業(yè)務處理層。HTTP服務層用于維持用戶的訪問請求,業(yè)務處理層則用于進行具體的邏輯判斷。兩層之間的數(shù)據(jù)交互通過消息隊列來實現(xiàn)。

HTTP服務層主要功能如下:

  1. 進行基本的URL正確性校驗;
  2. 對惡意訪問的用戶進行過濾,攔截黃牛;
  3. 提供用戶驗證碼;
  4. 將正常訪問用戶數(shù)據(jù)放入相應商品隊列中;
  5. 等待業(yè)務處理層返回的處理結果。


業(yè)務處理層主要功能如下:

  1. 接收商品隊列中的數(shù)據(jù);
  2. 對用戶請求進行處理;
  3. 將請求結果放入相應的返回隊列中。


用戶的搶購請求通過消息隊列,依次進入業(yè)務處理層的Go進程里,然后順序地處理請求,將搶購結果返回給前面的HTTP服務層。

商品剩余數(shù)量等信息,根據(jù)商品編號分別保存在業(yè)務層特定的服務器進程中。我們選擇保證商品數(shù)據(jù)的一致性,放棄了數(shù)據(jù)的分區(qū)容忍性。

這兩個模塊用于搶購過程中的請求處理,系統(tǒng)中還有相應的策略控制模塊,以及防刷和系統(tǒng)管理模塊等(圖3)。


小米手機越來越容易搶的背后:搶購系統(tǒng)的優(yōu)化



圖3 第二版系統(tǒng)詳細結構圖


在第二版搶購系統(tǒng)的開發(fā)過程中,我們遇到了HTTP層Go程序內存消耗過多的問題。

由于HTTP層主要用于維持住用戶的訪問請求,每個請求中的數(shù)據(jù)都會占用一定的內存空間,當大量的用戶進行訪問時就會導致內存使用量不斷上漲。當內存占用量達到一定程度(50%)時,Go中的GC機制會越來越慢,但仍然會有大量的用戶進行訪問,導致出現(xiàn)“雪崩”效應,內存不斷上漲,最終機器內存的使用率會達到90%以上甚至99%,導致服務不可用。

在Go語言原生的HTTP包中會為每個請求分配8KB的內存,用于讀緩存和寫緩存。而在我們的服務場景中只有GET請求,服務需要的信息都包含在HTTP Header中,并沒有Body,實際上不需要如此大的內存進行存儲。

為了避免讀寫緩存的頻繁申請和銷毀,HTTP包建立了一個緩存池,但其長度只有4,因此在大量連接創(chuàng)建時,會大量申請內存,創(chuàng)建新對象。而當大量連接釋放時,又會導致很多對象內存無法回收到緩存池,增加了GC的壓力。

HTTP協(xié)議是構建在TCP協(xié)議之上的,Go的原生HTTP模塊中是沒有提供直接的接口關閉底層TCP連接的,而HTTP 1.1中對連接狀態(tài)默認使用keep-alive方式。這樣,在客戶端多次請求服務端時,可以復用一個TCP連接,避免頻繁建立和斷開連接,導致服務端一直等待讀取下一個請求而不釋放連接。但同樣在我們的服務場景中不存在TCP連接復用的需求。當一個用戶完成一個請求后,希望能夠盡快關閉連接。keep-alive方式導致已完成處理的用戶連接不能盡快關閉,連接無法釋放,導致連接數(shù)不斷增加,對服務端的內存和帶寬都有影響。

通過上面的分析,我們的解決辦法如下。

  1. 在無法優(yōu)化Go語言中GC機制時,要避免“雪崩效應”就要盡量避免服務占用的內存超過限制(50%),在處于這個限制內時,GC可以有效進行??赏ㄟ^增加服務器的方式來分散內存壓力,并盡力優(yōu)化服務占用的內存大小。同時Go 1.3也對其GC做了一定優(yōu)化。
  2. 我們?yōu)閾屬忂@個特定服務場景定制了新的HTTP包,將TCP連接讀緩存大小改為1KB。
  3. 在定制的HTTP包中,將緩存池的大小改為100萬,避免讀寫緩存的頻繁申請和銷毀。
  4. 當每個請求處理完成后,通過設置Response的Header中Connection為close來主動關閉連接。


通過這樣的改進,我們的HTTP前端服務器最大穩(wěn)定連接數(shù)可以超過一百萬。

第二版搶購系統(tǒng)順利完成了米粉節(jié)的考驗。

小米手機越來越容易搶的背后:搶購系統(tǒng)的優(yōu)化


總結

技術方案需要依托具體的問題而存在。脫離了應用場景,無論多么酷炫的技術都失去了價值。搶購系統(tǒng)面臨的現(xiàn)實問題復雜多變,我們也依然在不斷地摸索改進。

簡歷又被刷了,應屆程序員簡歷就該這么寫

了解常用緩存淘汰算法,這就夠了

(正文已結束)

推薦閱讀:財經快訊

免責聲明及提醒:此文內容為本網所轉載企業(yè)宣傳資訊,該相關信息僅為宣傳及傳遞更多信息之目的,不代表本網站觀點,文章真實性請瀏覽者慎重核實!任何投資加盟均有風險,提醒廣大民眾投資需謹慎!

網站簡介 - 聯(lián)系我們 - 營銷服務 - XML地圖 - 版權聲明 - 網站地圖TXT
Copyright.2002-2019 寧夏資訊網 版權所有 本網拒絕一切非法行為 歡迎監(jiān)督舉報 如有錯誤信息 歡迎糾正