在工程師的理想世界中,架構總是美麗的。但在高規模系統的現實世界中,你必須做出妥協。一個工程師在一開始就必須思考的基本問題是寫入速度和讀取速度之間的惡性權衡取捨。
通常,你會犧牲其中一個來換取另一個。但在我們的案例中,在 AWS 處理 PB 級數據時,這種妥協並沒有影響我們的速度——而是打擊了我們的錢包。
我們建立了一個完美寫入數據的系統,但每次從存檔中讀取時,它都以最痛苦的方式燒錢。畢竟,從 AWS 讀取 PB 級數據需要支付數據傳輸費、請求計數費和存儲類別檢索費...這可是一大筆錢!
這是我們如何優化它使其更高效且更具成本效益的故事!
真實故事:幾個月前,我們的一位解決方案架構師想從一個罕見的低流量網站提取樣本導出,以向潛在客戶展示產品。由於 API 中的一個錯誤,文件數量的安全限制沒有被應用。
因為這個"罕見"網站的數據與高流量網站一起散布在數百萬個存檔中,系統試圖恢復我們幾乎一半的歷史存儲來找到那幾個頁面。
這個誠實的錯誤最終花費了我們近$100,000 的 AWS 費用!
現在,我立即修復了 API 錯誤(並添加了嚴格限制),但架構上的漏洞仍然存在。這是一個定時炸彈...
讓我告訴你 Bright Data Web Archive 架構的故事:我如何將系統推入"廉價"存儲的陷阱,以及我如何使用重新排列管道爬出來。
當我開始在 Web Archive 上工作時,系統已經在攝取大量數據流:每分鐘數百萬個請求,每天數十 TB。基礎架構的建立有一個主要目標:在不丟失數據的情況下捕獲一切。
它依賴於高吞吐量系統最持久的策略:僅追加日誌。
對於攝取階段,這種設計無懈可擊。在 Deep Archive 中存儲數據只需幾分錢,而寫入吞吐量幾乎是無限的。
這種架構對寫入來說是完美的...直到客戶要求歷史數據。那時我面臨一個基本矛盾:
cnn.com、google.com和shop.xyz的混合。cnn.com的所有頁面。"這就是激發本文的錯誤所在。像許多工程師一樣,我習慣於思考延遲、IOPS 和吞吐量。但我忽略了AWS Glacier 計費模型。
我想:"好吧,檢索幾千個存檔很慢(48 小時),但不會太貴。"
現實:AWS 不僅對 API 調用收費,還對恢復的數據量收費(每 GB 檢索的費用)。
想像一個客戶請求來自單一域名的 1,000 個頁面。由於寫入邏輯是按時間順序的,這些頁面可能分散在 1,000 個不同的 TAR 存檔中。
為了給客戶提供這 50 MB 的有用數據,災難發生了:
我們付費恢復 TB 級的垃圾只為提取金子粒。這是一個經典的數據局部性問題,變成了財務黑洞。
我無法快速更改攝取方法——傳入流太過並行且龐大,無法"即時"排序(雖然我正在研究這個),而且我還需要一個對已存檔數據也有效的解決方案。
因此,我設計了重新排列管道,一個"碎片整理"存檔的後台進程。
這是一個非同步 ETL(提取、轉換、加載)過程,具有幾個關鍵核心組件:
選擇:對客戶沒有要求的數據進行排序是沒有意義的。因此,我將所有新數據引導到管道中,以及客戶特別要求恢復的數據。我們第一次為檢索多付費,但第二次就不會發生了。
\
洗牌(分組):多個工作者並行下載未排序的文件,並按域名組織緩衝區。由於系統是非同步的,我不擔心傳入流會使內存過載。工作者以自己的節奏處理負載。
\
重寫:我將排序後的文件寫回 S3,使用新的前綴(以區分排序文件和原始文件)。
2024/05/05/random_id_ts.tar→[cnn, google, zara, cnn]2024/05/05/cnn/random_id_ts.tar→[cnn, cnn, cnn...] MERGE INTO或UPDATE的成本過高。這一變化徹底改變了產品的經濟性:
cnn.com時,系統只恢復cnn.com所在的數據。Bright Data 正在進一步擴展 Web Archive。如果你喜歡:
那麼我很想與你交談。
我們正在招聘強大的 Node.js 工程師來幫助構建下一代 Web Archive。擁有數據工程和 ETL 經驗是非常有利的。請隨時將您的簡歷發送至vadimr@brightdata.com。
隨著我繼續擴展存檔——以及我不斷尋找新的創造性方式來打破它,更多更新即將到來!
\


