左手隔離,右手分層 —— 秒殺系統的思考方式與設計思路

你們好,我是崔皓。
很高興有這樣一個機會和你們認識。我在IT行業從事軟件開發工做十餘年了,足跡涵蓋企業服務,互聯網,企業數字化轉型等。工做之餘熱愛閱讀和學習,但願能和你們成爲朋友。前端

今天要給你們分享的是「如何設計秒殺系統」。算法

秒殺場景的特徵
隔離的設計思路
分層設計思路數據庫

講解思路是,提出秒殺場景的特徵,也就是理解什麼是秒殺。而後介紹在秒殺系統設計的底線,有了底線才能保證進可攻退可守。最後介紹使用哪些方法和手段實現秒殺系統的架構設計,以及本專欄的章節脈絡和主要內容。緩存

秒殺場景的特徵

秒殺一般是電商網站按期舉辦的活動,這個活動有明確的開始和結束時間,並且參與互動的商品是事先定義好的,商品的個數也是有限制的。同時會提供一個秒殺的入口,讓用戶經過這個入口進行搶購。服務器

總結一下秒殺場景的特色:

定時開始,秒殺時大量用戶會在同一時間段,搶購同一商品,網站瞬時流量激增。網絡

庫存有限,秒殺下單數量遠遠大於庫存數量,只有少部分用戶可以秒殺成功。多線程

操做可靠,秒殺業務流程比較簡單,通常就是下訂單減庫存。庫存就是用戶爭奪的「資源」,實際被消費的「資源」不能超過計劃要售出的「資源」,也就是不能被「超賣」。所以要保證數據的一致性,也就是操做可靠。架構

併發量高,在同一時刻訪問系統的用戶數急劇增長,主要表如今同時讀和同時寫數據。如何同時處理這些請求,以及如何處理哪些沒法響應的請求是對系統的考驗。併發

若是把上面四個特徵進行總結,那就是在很短的時間內,須要支持對稀缺資源進行海量併發讀寫操做,還要保證這些讀寫操做的可靠性。負載均衡

秒殺場景的特徵就決定了,秒殺系統與平常系統的不同。秒殺系統是大流量請求在短期內集中處理,而平常系統的請求處理更加平滑和平均。秒殺場景不會常常發生,它有實效性,有具體的開始和結束時間。再者秒殺系統是針對具體的商品或者商品分類進行的,資源的範圍相對於平常系統來講也比較小。鑑於這些不一樣點,秒殺系統須要和平常系統須要分開考慮,這就是下面要提到的隔離的設計思路。

隔離的設計思路

因爲秒殺活動是有計劃的,而且在短期內會爆發大量的請求。爲了避免影響平常業務系統的正常運行,咱們須要把它和現有的系統作隔離。這樣即使秒殺系統出現了問題,也不會影響平常系統的正常工做。要不就「偷雞不成反失一把米了」,所以在設計秒殺系統的時候能夠從如下幾個方面來思考隔離的問題。

業務隔離

既然秒殺是一場活動,那它必定和常規的業務不一樣,咱們能夠把它當成一個單獨的項目來看。在活動開始以前,最好設計一個「熱場」。「熱場」的形式多種多樣,例如:分享活動領優惠卷,領秒殺名額等等。「熱場」的形式不重要,重要的是經過它獲取一些準備信息。例如:有可能參與的用戶數,他們的地域分佈,他們感興趣的商品。爲後面的技術架構提供數據支持。別小看這些數據,經過這些數據能夠預估出秒殺當天的流量,併發數等信息。並且能夠做爲壓力測試數據來源的一部分,協助測試系統的可用性。

應用隔離

如今應用的部署多采用分佈式或者微服務的架構,經過容器和服務編排的方式部署方式比較常見。建議分配給秒殺系統專門的系統資源,來應對高併發。咱們能夠將原來平常系統中的服務在秒殺系統中複用,也能夠爲秒殺系統設計專門的服務。衆所周知一個系統中包含服務數量,少則幾十個,多則上百個。若是爲了秒殺系統複製一套,恐怕成本過高。這裏須要區分,核心功能、支撐功能和通用功能。對於須要併發讀寫的功能就是秒殺系統的核心功能,例如:商品詳情,下單等。這些功能的服務能夠專門提供一套,作水平擴展。針對一些支撐功能和通用功能的服務,例如配置信息,用戶評論。建議不作擴展,只須要作好熔斷和降級的準備,使之不影響核心功能就好。

流量隔離

前面的特徵分析中提到了,秒殺系統會在短期內迎來巨大流量。若是秒殺系統和平常系統共用一個接入層,那麼對應的負載均衡器也會接受海量的請求。不管是硬件負載均衡仍是軟件負載均衡,其可以承受的流量都是有限制的。超過了這個流量,系統會進行限流操做,將多餘的流量置之門外。若是此時由於秒殺系統的流量增長,致使平常系統的流量瓶頸是得不償失的。因此這裏須要對流量進行隔離,若是共用負載均衡須要設置秒殺系統使用的流量上限。根據秒殺系統特有的請求頭判斷流入的請求是來自秒殺請求仍是平常系統請求。同時也能夠根據用戶ID,請求IP、請求的地域來作隔離。

數據隔離

秒殺活動持續時間短,瞬時數據量大。爲了避免影響現有數據庫的正常業務,能夠創建新的庫或者表來處理。在秒殺結束之後,須要把這部分數據同步到主業務系統中,或者查詢表中。若是數據量特別巨大,到千萬級別甚至上億,建議使用分表或者分庫。

隔離的工做是爲了保證平常系統的可用性,是秒殺系統設計的底線,由於誰也不知道海量請求到達的時候會發生什麼。即便再有經驗的團隊都須要了明白系統老是會出問題的,咱們要作的就是將問題產生的機率降到最低,讓問題的影響範圍降到最小。有了隔離作保證,再才能談如何設計一個秒殺系統。

左手隔離,右手分層 —— 秒殺系統的思考方式與設計思路

業務隔離、應用隔離、流量隔離和數據隔離*

分層設計思路

說了完了隔離的思路,再來聊聊如何設計秒殺系統。因爲秒殺的場景不一樣,面向的用戶數量不一樣,參與秒殺的資源數量不一樣,每一個公司的現有系統架構千差萬別,而且硬件配置和網絡環境也各有不一樣。沒法提出一個統一的架構,只能針對秒殺系統中出現的問題進行解決。回到秒殺場景的特徵,實際上咱們要解決的就是短期對稀缺資源,高併發讀寫和結果可靠性的問題。解決這些問題的方法,在平時的系統架構中也會用到,只是在秒殺系統中會更有表明性、更極端。總結下來主要是緩存、限流、熔斷、分佈式服務、分佈式存儲、數據一致性、分佈式可靠性、系統的監控。可是這些問題涉及到系統架構的方方面面,單獨來說你們都能理解,如何經過系統的方式給你們介紹,可以從架構的角度去看秒殺系統須要考慮哪些問題。這裏咱們經過架構分層的方式,逐層講解如何解決秒殺系統的問題。專題總共分來7個部分共15個章節來說述。最後總結爲四橫三縱。

用戶觸點:客戶端設計。客戶端頁面設計須要ESI和CSI方法論做爲支撐。前端秒殺頁面使用專門的頁面,這些頁面包括靜態的HTML和動態的JS,以及如何使用HTTP和CDN緩存減小對應用服務器的訪問。

流量入口:代理層設計。即便咱們擴展再多的應用,使用再多的應用服務器,部署再多的負載均衡器,都會遇到支撐不住海量請求的時候。因此,在這一層咱們要考慮的是如何作好流量擴展和流量限制,當超過系統承受範圍的時候,須要果斷阻止請求的涌入。同時在業務層面能夠根據IP,用戶名,商品ID對流入秒殺系統的請求進行篩選和控制。而且可以對惡意請求大膽說「不」。而且包括負載均衡算法,限流算法,Nginx實現限流的最佳實踐以及OpenResty實現代理層緩存的最佳實踐。

核心服務:應用層設計。瞬時的海量請求比如請求的「高峯」,咱們架構系統的目的就是「削峯」。須要使用服務集羣和水平擴展,讓「高峯」請求分流到不一樣的服務器進行處理。同時,還會利用緩存和隊列技術減輕應用處理的壓力,經過異步請求的方式作到最終一致性。因爲是多線程操做,並且商品的額度有限,爲了解決超賣的問題,須要考慮進程鎖的問題。 同時也會可使用進程內的緩存保存一些熱點數據,針對分佈式緩存提供算法和最佳實踐。在遇到服務掛掉的狀況,須要有檢測和熔斷機制。

數據存儲:數據層設計。秒殺活動持續時間短,瞬時數據量大。爲了避免影響現有數據庫的正常業務,能夠創建新的庫或者表來處理。在秒殺結束之後,須要把這部分數據同步到主業務系統中,或者查詢表中。若是數據量特別巨大,到千萬級別甚至上億,建議使用分表或者分庫。同時作到讀寫分離,利用分佈式的選舉機制保證服務器的高可用。

壓力測試:當系統上線以前咱們須要未雨綢繆,針對即將出現的高併發場景進行演練。根據QPS、TPS、BPS對系統設定運行指標,經過壓力測試的方式論和測試工具,探查系統的承載底線。

監控系統:系統上線運行之後,須要時刻監控系統的狀況而且做出響應的反映。咱們會針對監控系統的功能、分類、分層進行詳細介紹。並且會針對Zabbix和ELK的最佳實踐,讓理論結合實踐。

服務降級:若是說服務必定會遇到問題,那麼服務降級就是讓問題形成的影響最小化。針對服務不可用的狀況設置開關,而且經過ZooKeeper實現開關功能。

把上面7個方面的描述總結爲四橫三縱。按照用戶請求從外到內,從上到下的方向分別是:客戶端、代理層、應用層、數據層。壓力測試、監控系統、服務降級做爲高可用的保障貫穿四層之中造成三縱。

左手隔離,右手分層 —— 秒殺系統的思考方式與設計思路
四橫三縱架構設計圖

左手隔離,右手分層 —— 秒殺系統的思考方式與設計思路

聽研發大牛,白話【秒殺高併發】實戰
私信小助手「秒殺」,進興趣羣↓↓↓↓
左手隔離,右手分層 —— 秒殺系統的思考方式與設計思路

相關文章
相關標籤/搜索