如何應對單日十億計Web請求
就在不久之前,AppLovin移動廣告平臺的單一廣告請求數量突破了200億大關——相當於每一秒鐘處理50萬項事務——其如火如荼的發展態勢幫助眾多品牌在激勵現有客戶的同時、從市場中拉攏到了新的買家。那麼AppLovin是如何打造出這樣一套有能力應對數百億請求、但又無需對硬體及運維人員進行顯著擴張的基礎設施的呢?
在今天的文章中,我們將共同瞭解該公司如何發現並選擇採用各類最佳實踐,從而通過技術堆疊進化實現業務規模擴充。
極具成本效率的擴充套件思路
讓我們首先從規模談起。對於我們這些在AppLovin工作的傢伙來說,極具成本效率的規模擴充套件方案意味著能夠在大幅提升負載處理能力的同時、避免硬體或者人員的線性增長。如果我們只能通過採購雙倍的伺服器裝置或者將人員數量提高一倍來實現請求處理能力倍增,那麼這樣的方案根本沒什麼實際意義。由於我們在構建基礎設施時充分考慮到效率擴充需求,因此才能夠在過去一年中將伺服器的請求處理數量增加到此前的二十倍。
另一項值得注意的重點在於,對於大規模分散式系統而言,市面上並沒有現成的解決方案可供借鑑。這類系統的構建工作必須使用自定義元件。無論歸屬於哪個行業,技術團隊在建立分散式系統時都需要對選定的元件進行認真評估。除此之外,每一次出現工作負載爆炸式增長的時候,這些元件也需要及時作出調整。
針對這些調整制定規劃意味著基礎設施自身必須擁有出色的靈活性。我們從業務建立之初就充分意識到,移動廣告領域可以說瞬息萬變,而我們則需要打造一套能夠與之相匹配且相適應的靈活基礎設施。我們希望自己的這套基礎設施能夠允許員工針對各類市場需求實現對應的創新活動。舉例來說,如果我們需要進行細節調整,那麼只需在現有基礎設施之上直接實施即可、而無需對設施整體進行重新設計。這就是我們工作的核心指導思想。
這套方案也切實帶來了回報。我們最近剛剛將單月資訊流量提升了一倍,而讓這一切變成現實的正是我們這套靈活性出眾的基礎設施。
適應性強且具備可擴充套件能力的實時基礎設施
考慮到上述構建要求,我們所打造的基礎設施堆疊中包含Web伺服器、一套實時快取層、資料庫、分散式訊息服務以及大規模平行計算系統。
作為前端的是成百上千臺Web伺服器。這些伺服器裝置用於應答每天來自海量使用者的數十億請求。當每一條請求傳入時,我們需要立刻作出一系列決定,包括是否對其作出應答、為其支付多少成本以及提供哪條廣告作為宣傳內容——整個決定過程大約耗時50毫秒。
接下來我們要做的是將使用者配置資訊納入快取,整套資料庫包含數十億擁有手機裝置的使用者。這些資訊需要在很段的時間週期內進入可用狀態,從而實現Web伺服器的響應並決定是否為特定廣告請求提供支援。簡而言之,我們需要的是一套分散式快取層,旨在以實時方式為全部傳入請求提供所需資料。這套快取層中使用包括Aerospike、Redis以及Memchached在內的多套系統。
除此之外,另有大量分析、報告、資料倉儲以及資料科學功能集需要接入到不同型別的資料庫當中。從巨集觀規模角度看,這些功能必須具備分散式能力。為了實現這種分散式機制,我們採用分散式訊息或者釋出/訂閱訊息服務。分散式訊息傳送機製為我們帶來了以下幾項關鍵優勢:
·我們能夠從任何位置獲取需要的資訊。
·我們能夠利用日誌檔案作為事務單元,從而處理在一秒鐘內處理數以十萬計請求。
·我們能夠為任何服務訂閱方案提供其需要的資訊。
上述訊息必須被髮布到全球世界內的任何位置。其目標位置可能是一套惠普Vertica資料倉儲、MySQL資料庫、Apache Hadoop系統或者一套Apache Storm實時處理系統。分散式訊息傳送機制可以說是所有實時架構的核心組成部分。
最後,我們需要利用分散式計算體系實現資料處理。擁有分散式計算體系意味著對Hadoop或者Apache Spark等技術方案的運用——這類並行處理系統能夠檢視全部資料並通過擴充套件處理規模龐大的資料負載。
以上列出的所有部件都通過一套分散式日誌架構實現對接。這類基於日誌架構的基本設計思路在於,它能夠接納多種資料來源,利用日誌檔案作為事務單元並獲取來自全部資料來源的資訊。舉例來說,一臺廣告伺服器可能會記錄下“我是否提供了廣告內容?使用者是否點選過廣告內容?我是否感知到事務處理?”這一切都將被寫入日誌當中,而大量日誌資訊則匯聚成訊息系統。這些日誌不斷傳輸、接受處理,最後的彙總資料則被寫入資料庫。全部此類資料都能夠為日誌記錄系統所呼叫,並以訂閱方式交付給任何需要這些資料的服務。
這種架構型別之所以能夠實現創新,是因為我們完全可以將任何元件插入到系統當中。大家可能需要在特定位置插入Aerospike實時資料庫,也可能希望在其它位置使用Vertica。我們必須有能力將全部輸入資訊交付給全部不同型別的處理工具。擁有這樣一套基於日誌的架構能夠幫助我們通過日誌將所有資料來源同集中式日誌記錄系統對接起來,並最終成為實時訂閱系統的實現基礎。
評估技術選項
對我們這套平臺的評估工作能夠充分展示,為什麼擁有具備高度靈活性的基礎設施是如此重要。
我們最初其實選擇了利用PHP語言進行平臺構建。這是一種效率極高的開發方式,而且也很容易找到大量熟悉此類開發任務的程式設計人員。同樣的道理也適用於MySQL,而考慮到MongoDB作為NoSQL資料庫領域重要成員的崇高地位,我們決定將二者並行使用。當然,作為一家初創企業,我們在起步階段在Amazon Web Services上構建起平臺的核心主體。但最後,我們利用RabbitMQ來實現自己的釋出/訂閱訊息機制。
隨著時間的推移,我們已經開始將資料遷移到由Aerospike、Redis、Apache Cassandra、Vertica以及Hadoop系統所共同構成的綜合體系當中。我們完成了由PHP向C++的轉換,而且將訊息釋出任務由RabbiMQ轉換到一套定製化Java系統當中。與此同時,我們還成功削減了其它系統的使用數量,將其規模嚴格控制在我們相對易於理解、而工程技術團隊又明白該如何處理的程度上。
新軟體的引進無疑是個成本昂貴的命題。無論是開源軟體還是專有許可軟體,如果大家作出了嘗試但卻沒能收到預期中的效果,那麼整個工作就又得退回幾個月之前。因此我們認真對每款產品進行了評估,希望能預先了解其是否物有所值。
我們採取的第一項舉措是審視行業中的其它廠商在使用哪些產品,這些產品又能給我們的現有用例帶來哪些改進。舉例來說,當評估Aerospike時,來自另一家廣告技術企業的工作人員就向我們介紹了他的經驗。我們之後又與四、五家其它Aerospike客戶進行了溝通,並提出“你們的用例跟我們的是否存在相似之處?你們喜歡Aerospike的實際表現嗎?你們對Aerospike還有哪些不滿?”等問題。在此之後,我們還非常關心“如果我將其引入自己的業務體系,是否會還出現什麼意想不到的計劃外狀況?”
另一項評估元素則源自開發人員的偏好傾向。這一點在開源專案當中表現得尤為突出,不過在商業產品範疇內也極具指導意義。與此相關的問題包括:“是否已經有開發人員編寫、使用以及為其建立文件?這款產品是否擁有我們想要的發展軌跡?我身邊的朋友中是否有人正在使用這套系統?如果這是一套開源系統,那我是否需要獨力解決自己面臨的問題?”
舉例來說,我們目前正在對Apache Storm與Apache Spark進行全面比較。這兩個專案都能夠作為實時計算處理系統的實用性解決手段,那麼哪一種更受開發人員的青睞呢?在其它因素旗鼓相當的情況下,這一點就顯得非常重要了。
接下來是適應性水平。換句話來說:這套方案能否順暢融入我的系統?舉例而言,如果我們目前所使用的是PHP、Python或者C++,那麼這款新軟體能否以原生方式整合到對應語言當中?我們又是否能夠編寫出切實與該元件內API相對接的工具?
除此之外,我們還要深入考量產品出現故障的可能性。特別是在我們的實際案例當中,企業的多座資料中心分佈在全球各個位置,最重要的就是在故障出現時及時瞭解實際情況。某些產品在遭遇意外時不會發出警報作為提醒,這在我們眼中就顯得非常危險。
最後一個需要考慮的問題在於平臺的潛在風險——投入大量資源構建起的方案有可能在後續使用過程中給企業帶來恐怖的額外成本。舉例來說,如果一家企業並沒有以.Net為核心構建業務體系的經驗,那麼選擇任何一套與.Net相關的技術平臺都將毫無意義。如果這套技術方案基於Java所打造,那麼我們是否擁有對其加以妥善維護的必要資源?如果我們採用的是Amazon Web Services或者Google Compute Engine,那麼是否有信心在未來三年內繼續將全部業務依賴於這些雲平臺的發展趨勢?
一家企業所採用的技術方案在潛在客戶、合作伙伴或者投資者眼中往往會被視為優勢或者劣勢因素。總而言之,平臺的實施目標在於貼合業務的運營目標,這也應該成為指導我們選擇的根本性原則。
相關文章
- 如何根據介面請求型別和請求方法,自動執行對應請求型別
- Go Web如何處理Web請求?GoWeb
- Wireshark的HTTP請求包和響應包如何對應HTTP
- SPA單應用-請求介面URL結構設計
- Go如何響應http請求?GoHTTP
- Web請求過程Web
- WebApi系列~基於單請求封裝多請求的設計WebAPI封裝
- 對請求來源進行白名單限制
- 【知識分享】伺服器如何應對大量使用者請求伺服器
- Apache 記錄請求響應時間日誌Apache
- WebApi系列~基於單請求封裝多請求的設計~請求的安全性設計與實現WebAPI封裝
- Facebook 這類網站如何處理數十億請求並保持高可用性的?網站
- SpringMVC中如何傳送GET請求、POST請求、PUT請求、DELETE請求。SpringMVCdelete
- 如何在 Go 中傳送表單請求Go
- Spring Cloud Gateway 之 請求應答日誌列印SpringCloudGateway
- 如何檢測 Web 服務請求丟失問題Web
- 說說如何使用 Spring Security 保護 web 請求SpringWeb
- python-對requests請求簡單的封裝Python封裝
- PHP 回顧之 Web 請求PHPWeb
- Go Web 程式設計--深入學習解析 HTTP 請求GoWeb程式設計HTTP
- 使用 Laravel 請求類來驗證表單請求Laravel
- Go Web輕量級框架Gin學習系列:HTTP請求日誌GoWeb框架HTTP
- 面對海量請求,快取設計還應該考慮哪些問題?快取
- DRF對Django請求響應做了技術升級Django
- Angular如何對包含了HTTP請求的服務類進行單元測試AngularHTTP
- axios躺坑之路:cookie,簡單請求與非簡單請求。iOSCookie
- Laravel 5.5 簡單的檔案請求以及響應Laravel
- 【面試】Web 頁面請求歷程面試Web
- GOLANG Web請求引數驗證GolangWeb
- web 跨域請求安全問題Web跨域
- python requests get請求 如何獲取所有請求Python
- oracle ebs 根據請求id找到對應trace 檔案Oracle
- ThinkPHP 請求與響應PHP
- HTTP 請求與響應HTTP
- Http請求與響應HTTP
- WebxFrameworkFilter 請求響應流程WebFrameworkFilter
- Django請求響應物件Django物件
- 如何從請求、傳輸、渲染3個方面提升Web前端效能Web前端