4. 秒殺系統--處理系統的“熱點數據”

       假設你的系統中存儲有幾十億上百億的商品,而每天有千萬級的商品被上億的用戶訪問,那麼肯定有一部分被大量用戶訪問的熱賣商品,這就是我們常說的“熱點商品”。這些熱點商品中最極端的例子就是秒殺商品,它們在很短時間內被大量用戶執行訪問、添加購物車、下單等操作,這些操作我們就稱爲“熱點操作”。

爲什麼要關注熱點?

因爲熱點會對系統產生一系列的影響。

  1. 首先,熱點請求會大量佔用服務器處理資源,雖然這個熱點可能只佔請求總量的億分之一,然而卻可能搶佔 90% 的服務器資源,如果這個熱點請求還是沒有價值的無效請求,那麼對系統資源來說完全是浪費。
  2. 其次,即使這些熱點是有效的請求,我們也要識別出來做針對性的優化,從而用更低的代價來支撐這些熱點請求。

什麼是“熱點”?

       熱點分爲 熱點操作和 熱點數據。所謂“熱點操作”,例如大量的刷新頁面、大量的添加購物車、雙十一零點大量的下單等都屬於此類操作。對系統來說,這些操作可以抽象爲“讀請求”和“寫請求”,這兩種熱點請求的處理方式大相徑庭,讀請求的優化空間要大一些,而寫請求的瓶頸一般都在存儲層,優化的思路就是根據 CAP 理論做平衡。 “熱點數據” 就是用戶的熱點請求對應的數據。而熱點數據又分爲“靜態熱點數據”和“動態熱點數據”。

  • ”靜態熱點數據”,就是能夠提前預測的熱點數據。例如,我們可以通過賣家報名的方式提前篩選出來,通過報名系統對這些熱點商品進行打標。另外,我們還可以通過大數據分析來提前發現熱點商品,比如我們分析歷史成交記錄、用戶的購物車記錄,來發現哪些商品可能更熱門、更好賣,這些都是可以提前分析出來的熱點。
  • 動態熱點數據”,就是不能被提前預測到的,系統在運行過程中臨時產生的熱點。例如,賣家在抖音上做了廣告,然後商品一下就火了,導致它在短時間內被大量購買。

     由於熱點操作是用戶的行爲,我們不好改變,但能做一些限制和保護,本文主要針對熱點數據來介紹如何進行優化。

發現熱點數據

發現靜態熱點數據

       靜態熱點數據可以通過商業手段,例如強制讓賣家通過報名參加的方式提前把熱點商品篩選出來,實現方式是通過一個運營系統,把參加活動的商品數據進行打標,然後通過一個後臺系統對這些熱點商品進行預處理,如提前進行緩存。但是這種通過報名提前篩選的方式也會帶來新的問題,即增加賣家的使用成本,而且實時性較差,也不太靈活。

       不過,除了提前報名篩選這種方式,你還可以通過技術手段提前預測,例如對買家每天訪問的商品進行大數據計算,然後統計出 TOP N 的商品,我們可以認爲這些 TOP N 的商品就是熱點商品。

發現動態熱點數據

       通過賣家報名或者大數據預測這些手段來提前預測靜態熱點數據,但這其中有一個痛點,就是實時性較差,如果我們的系統能在秒級內自動發現熱點商品那就完美了。能夠動態地實時發現熱點不僅對秒殺商品,對其他熱賣商品也同樣有價值,所以我們需要想辦法實現熱點的動態發現功能。下面是一個動態熱點發現系統的具體實現。

  1. 構建一個異步的系統,它可以收集交易鏈路上各個環節中的中間件產品的熱點 Key,如 Nginx、緩存、RPC 服務框架等這些中間件(一些中間件產品本身已經有熱點統計模塊)。
  2. 建立一個熱點上報和可以按照需求訂閱的熱點服務的下發規範,主要目的是通過交易鏈路上各個系統(包括詳情、購物車、交易、優惠、庫存、物流等)訪問的時間差,把上游已經發現的熱點透傳給下游系統,提前做好保護。比如,對於大促高峯期,詳情繫統是最早知道的,在統一接入層上 Nginx 模塊統計的熱點 URL。
  3. 將上游系統收集的熱點數據發送到熱點服務檯,然後下游系統(如交易系統)就會知道哪些商品會被頻繁調用,然後做熱點保護。                                       
一個動態熱點發現系統

 

       我們通過部署在每臺機器上的 Agent 把日誌彙總到聚合和分析集羣中,然後把符合一定規則的熱點數據,通過訂閱分發系統再推送到相應的系統中。你可以是把熱點數據填充到 Cache 中,或者直接推送到應用服務器的內存中,還可以對這些數據進行攔截,總之下游系統可以訂閱這些數據,然後根據自己的需求決定如何處理這些數據。

在打造熱點發現系統時,需要注意幾點注意事項:

  1. 這個熱點服務後臺抓取熱點數據日誌最好採用異步方式,因爲“異步”一方面便於保證通用性,另一方面又不影響業務系統和中間件產品的主流程。
  2. 熱點服務發現和中間件自身的熱點保護模塊並存,每個中間件和應用還需要保護自己。熱點服務檯提供熱點數據的收集和訂閱服務,便於把各個系統的熱點數據透明出來。
  3. 熱點發現要做到接近實時(3s 內完成熱點數據的發現),因爲只有做到接近實時,動態發現纔有意義,才能實時地對下游系統提供保護。

處理熱點數據

處理熱點數據通常有幾種思路:一是優化,二是限制,三是隔離

  • 優化。優化熱點數據最有效的辦法就是緩存熱點數據,如果熱點數據做了動靜分離,那麼可以長期緩存靜態數據。但是,緩存熱點數據更多的是“臨時”緩存,即不管是靜態數據還是動態數據,都用一個隊列短暫地緩存數秒鐘,由於隊列長度有限,可以採用 LRU 淘汰算法替換。
  • 限制。限制更多的是一種保護機制,限制的辦法也有很多,例如對被訪問商品的 ID 做一致性 Hash,然後根據 Hash 做分桶,每個分桶設置一個處理隊列,這樣可以把熱點商品限制在一個請求隊列裏,防止因某些熱點商品佔用太多的服務器資源,而使其他請求始終得不到服務器的處理資源。
  • 隔離。秒殺系統設計的第一個原則就是將這種熱點數據隔離出來,不要讓 1% 的請求影響到另外的 99%,隔離出來後也更方便對這 1% 的請求做針對性的優化。

具體到“秒殺”業務,我們可以在以下幾個層次實現隔離:

  1. 業務隔離。把秒殺做成一種營銷活動,賣家要參加秒殺這種營銷活動需要單獨報名,從技術上來說,賣家報名後對我們來說就有了已知熱點,因此可以提前做好預熱。
  2. 系統隔離。系統隔離更多的是運行時的隔離,可以通過分組部署的方式和另外 99% 分開。秒殺可以申請單獨的域名,目的也是讓請求落到不同的集羣中。
  3. 數據隔離。秒殺所調用的數據大部分都是熱點數據,比如會啓用單獨的 Cache 集羣或者 MySQL 數據庫來放熱點數據,目的也是不想 0.01% 的數據有機會影響 99.99% 數據。

       當然,實現隔離有很多種辦法。比如,你可以按照用戶來區分,給不同的用戶分配不同的 Cookie,在接入層,路由到不同的服務接口中;再比如,你還可以在接入層針對 URL 中的不同 Path 來設置限流策略。服務層調用不同的服務接口,以及數據層通過給數據打標來區分等等這些措施,其目的都是把已經識別出來的熱點請求和普通的請求區分開。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章