設計一個秒殺系統,主要的挑戰和問題有哪些?核心的架構方案或者思路有哪些?

{"type":"doc","content":[{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"1、秒殺存在的問題","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  對於一個日常平穩的業務系統,如果直接開通秒殺功能的話,往往會出現很多問題——","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/67/6787c143534fb818100d73e02968b84c.png","alt":"","title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"首先從高維度出發,整體思考問題。秒殺無外乎解決兩個核心問題,一是併發讀,一是併發寫,對應到架構設計,就是高可用、一致性和高性能的要求。關於秒殺系統的設計思考,本文即基於此 3 層依次推進,簡述如下:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"高性能。 秒殺涉及高讀和高寫的支持,如何支撐高併發,如何抵抗高IOPS?核心優化理念其實是類似的:高讀就儘量\"少讀\"或\"讀少\",高寫就數據拆分。本文將從動靜分離、熱點優化以及服務端性能優化 3 個方面展開","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一致性。 秒殺的核心關注是商品庫存,有限的商品在同一時間被多個請求同時扣減,而且要保證準確性,顯而易見是一個難題。如何做到既不多又不少?本文將從業界通用的幾種減庫存方案切入,討論一致性設計的核心邏輯","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"高可用。 大型分佈式系統在實際運行過程中面對的工況是非常複雜的,業務流量的突增、依賴服務的不穩定、應用自身的瓶頸、物理資源的損壞等方方面面都會對系統的運行帶來大大小小的的衝擊。如何保障應用在複雜工況環境下還能高效穩定運行,如何預防和麪對突發問題,系統設計時應該從哪些方面着手?本文將從架構落地的全景視角進行關注思考","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"2、動靜分離","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"大家可能會注意到,秒殺過程中你是不需要刷新整個頁面的,只有時間在不停跳動。這是因爲一般都會對大流量的秒殺系統做系統的靜態化改造,即數據意義上的動靜分離。動靜分離三步走:1、數據拆分;2、靜態緩存;3、數據整合。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"2.1 數據拆分","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"動靜分離的首要目的是將動態頁面改造成適合緩存的靜態頁面。因此第一步就是分離出動態數據,主要從以下 2 個方面進行:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":null,"normalizeStart":1},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"用戶。用戶身份信息包括登錄狀態以及登錄畫像等,相關要素可以單獨拆分出來,通過動態請求進行獲取;與之相關的廣平推薦,如用戶偏好、地域偏好等,同樣可以通過異步方式進行加載","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"時間。秒殺時間是由服務端統一管控的,可以通過動態請求進行獲取","attrs":{}}]}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這裏你可以打開電商平臺的一個秒殺頁面,看看這個頁面裏都有哪些動靜數據。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"2.2 靜態緩存","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"分離出動靜態數據之後,第二步就是將靜態數據進行合理的緩存,由此衍生出兩個問題:1、怎麼緩存;2、哪裏緩存","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"2.2.1 怎麼緩存","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"靜態化改造的一個特點是直接緩存整個 HTTP 連接而不是僅僅緩存靜態數據,如此一來,Web 代理服務器根據請求 URL,可以直接取出對應的響應體然後直接返回,響應過程無需重組 HTTP 協議,也無需解析 HTTP 請求頭。而作爲緩存鍵,URL唯一化是必不可少的,只是對於商品系統,URL 天然是可以基於商品 ID 來進行唯一標識的。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"2.2.2 哪裏緩存","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"靜態數據緩存到哪裏呢?可以有三種方式:1、瀏覽器;2、CDN ;3、服務端。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"瀏覽器當然是第一選擇,但用戶的瀏覽器是不可控的,主要體現在如果用戶不主動刷新,系統很難主動地把消息推送給用戶(注意,當討論靜態數據時,潛臺詞是 “相對不變”,言外之意是 “可能會變”),如此可能會導致用戶端在很長一段時間內看到的信息都是錯誤的。對於秒殺系統,保證緩存可以在秒級時間內失效是不可或缺的。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"服務端主要進行動態邏輯計算及加載,本身並不擅長處理大量連接,每個連接消耗內存較多,同時 Servlet 容器解析 HTTP 較慢,容易侵佔邏輯計算資源;另外,靜態數據下沉至此也會拉長請求路徑。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因此通常將靜態數據緩存在 CDN,其本身更擅長處理大併發的靜態文件請求,既可以做到主動失效,又離用戶儘可能近,同時規避 Java 語言層面的弱點。需要注意的是,上 CDN 有以下幾個問題需要解決:","attrs":{}}]},{"type":"numberedlist","attrs":{"start":null,"normalizeStart":1},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"失效問題。任何一個緩存都應該是有時效的,尤其對於一個秒殺場景。所以,系統需要保證全國各地的 CDN 在秒級時間內失效掉緩存信息,這實際對 CDN 的失效系統要求是很高的","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"命中率問題。高命中是緩存系統最爲核心的性能要求,不然緩存就失去了意義。如果將數據放到全國各地的 CDN ,勢必會導致請求命中同一個緩存的可能性降低,那麼命中率就成爲一個問題","attrs":{}}]}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因此,將數據放到全國所有的 CDN 節點是不太現實的,失效問題、命中率問題都會面臨比較大的挑戰。更爲可行的做法是選擇若干 CDN 節點進行靜態化改造,節點的選取通常需要滿足以下幾個條件:","attrs":{}}]},{"type":"numberedlist","attrs":{"start":null,"normalizeStart":1},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"臨近訪問量集中的地區","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"距離主站較遠的地區","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","text":"節點與主站間網絡質量良好的地區","attrs":{}}]}],"attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"3.設置閥門","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/40/40423d83aee7b2a74265dcc1b35379b4.png","alt":null,"title":"","style":[{"key":"width","value":"100%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/e4/e4bc9953645adc38f456f5ea92bc59da.png","alt":null,"title":"","style":[{"key":"width","value":"100%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章