Presto 是一款免費的開放原始碼 SQL 查詢引擎。過去十年來,Meta 一直都在使用 Presto,從中學到許多經驗。不論是要大規模運行工具、程序、服務還是其他任何東西,我們都需要解決各種問題,應對意想不到的挑戰。以下與大家分享我們在將 Presto 的使用擴大到 Meta 的規模時所學到的 4 件事,為有意大規模運行自家查詢系統的各位提供一些建議!
圖 1:推送新版本 Presto 的程序工作流程(圖表製作者:Philip S. Bell)
Meta 在世界各地的資料中心運行大量的 Presto 叢集。新版 Presto 大約每月至少建構並可供部署一次,有時會是每月兩次。我們在 Meta 內迅速擴展 Presto 的部署範圍時最早期面臨的挑戰之一,便是要在將查詢引擎部署到大量叢集當中的同時,確保引擎持續可用且穩定可靠。這一點在 Presto 互動式使用案例中一直尤為重要,也就是由用戶發起查詢並積極等待結果的情況。而在自動的「批量」使用案例下,查詢失敗則相對不會構成太大的問題,因為系統會在當中自動重試,確保最終能成功查詢所需資料。
要解決這一個挑戰,方法非常簡單。守在所有 Presto 叢集前方的是一個名為「閘道」的負載平衡器,其會與 Meta 的其他系統一同負責將 Presto 查詢路由至適當的叢集。當有 Presto 叢集需要更新時,系統會首先將其標記為從閘道排除,即下令閘道停止向此叢集路由任何新查詢。然後,自動化系統會等待一段預定的時間,以便目前正在此叢集上運行的查詢完成。接下來,系統將會更新有關叢集,而待叢集恢復使用後,系統便會向閘道開放此叢集,以便閘道開始向其路由新的查詢。
部署新版 Presto 時需要考慮的另外一個方面是可用性。我們需要確保用戶在叢集更新期間仍能使用 Presto。同樣地,自動化系統會確保每個地理區域內的每個資料中心始終都有所需數量的 Presto 叢集可供使用。當然,我們不能一次關閉過多叢集,以免影響用戶的使用,也不能一次關閉太少叢集,否則部署時間就會變得太長。因此,我們必須在兩者之間找到平衡點。
圖 2:向叢集加入硬件的自動化工作流程(圖表製作者:Philip S. Bell)
Meta 的資料倉儲在不同區域的分佈情況不斷在變化。換言之,Meta 會定期啟用新的 Presto 叢集和停用現有的叢集。我們以前的 Presto 叢集數量不多,因此當時可手動完成此流程。但隨著 Meta 開始逐步擴大 Presto 的使用規模,很快就變得難以手動追蹤所有變更。為了解決這個問題,我們實施了自動化系統來處理叢集的啟用與停用流程。
首先,我們需要將叢集的配置標準化,也就是說,我們要為 Meta 內的不同 Presto 使用案例訂立基礎配置。然後,每個叢集在基礎配置之上可以設定最低限度的附加或凌駕規格。將叢集的配置標準化後,我們便可根據基礎範本自動產生配置,從而啟用任何新叢集。為了啟用叢集,我們還需要與自動化系統的勾點整合,以便與多項全公司通用的基礎架構服務(如 Tupperware)和資料倉儲專用服務整合。當有叢集推出可供使用後,我們會向其傳送幾項測試查詢,由自動化系統驗證此叢集能否成功執行查詢。接著,此叢集會在閘道上完成註冊,並且開始提供查詢服務。
停用叢集的流程基本上就是反過來。系統會從閘道取消註冊有關叢集,並且容讓任何進行中的查詢先行完成。然後,Presto 程序便會關閉,相應的叢集配置也會刪除。
我們將此自動化系統整合到資料倉儲的硬件啟用與停用工作流程中。最終成果便是整個流程到得以全面自動化:從新硬件出現在資料中心,到 Presto 叢集推出並提供查詢服務,再到硬件停用後關閉叢集的安排,全部都由系統自動處理。實施此流程後,我們得以節省寶貴的人力,縮短了硬件閒置時間,同時將人為錯誤降至最少。
圖 3:偵測到主機狀況欠佳(圖表製作者:Philip S. Bell)
在 Meta 大規模部署 Presto 後,我們必須準備好適當的工具和自動化系統,以便候命人員(亦即 Presto 的聯絡人)工作起來更加輕鬆。
多年來,我們開發了多款「分析程式」,幫助候命人員有效率地偵錯和評估導致問題出現的根本原因。當發現違反顧客端服務級別協定之行為時,監察系統會發出警示,然後觸發分析程式。分析程式會從各個監察系統(操作型資料存放區,簡稱 ODS)、發佈到 Scuba 的事件,甚至主機級別的記錄中獲取資訊。隨後,分析程式中的自訂邏輯會將所有這類資訊串連在一起,從中推斷可能的根本原因。這對於候命人員來說極之實用,因為系統可以提供根本原因分析,方便他們直接跳到思考可行的緩解方案。在某些情況下,我們已將偵錯和補救程序都全面自動化,甚至無需牽涉到候命人員。以下會介紹幾個例子:
當在多部裝置上大規模運行 Presto 時,我們發現某些「狀況欠佳」的主機會導致過量的查詢失敗情況。根據我們的調查,我們找出了導致主機「狀況欠佳」的幾個根本原因,其中包括:
為了解決這一問題,我們如今會監察 Presto 叢集中的查詢失敗情況。具體來說,我們會儘可能將每次查詢失敗歸因,找出導致失敗的主機。此外,我們還設定了警示系統,以在特定主機導致的查詢失敗次數異常地多時發出警示。自動化系統隨之便會開始從 Presto 隊伍中排除相應主機,以此遏制失敗情況。
當 Presto 叢集正在運行的查詢達到自身的並行處理量上限,每個叢集都可以按照使用案例、硬件配置和查詢大小來將查詢佇列。Meta 設有一種十分精密的路由機制,以便將 Presto 查詢分派到可以執行此查詢的「適當」叢集,充分善用資源。除了 Presto 之外,路由的決定過程中也涉及到多個系統和考慮到多個因素:
如此複雜的流程,使候命人員很難在正式環境中遇到的任何佇列問題上,確定其根本原因為何。此時,分析程式便可再次發揮作用,從多個來源提取資訊並得出結論。
圖 4:負載平衡器的穩健度(圖表製作者:Philip S. Bell)
如上所述,在所有 Presto 叢集前方有一個負載平衡器把關,負責將 Meta 的每一個 Presto 查詢路由。最初,Presto 的應用並未擴大至如今的內部使用程度,因此那時的閘道非常簡單。然而,隨著 Presto 在 Meta 的使用率大幅增加,我們在擴展性上多次遇到問題。這方面的其中一個問題,便是閘道因負載過大而出現故障,這可能導致所有用戶都無法使用 Presto。部分穩定性問題的根本原因在於服務短時間內無意間以數百萬條查詢轟炸閘道,導致閘道程序死機,無法將任何查詢路由。
為了防止這種情況,我們著手提高閘道的穩健度,使其更能承受這種無意的 DDoS 式流量。為此我們加入了限速功能,以在負載量過大時拒絕查詢。我們可以針對不同方面的每秒查詢次數啟用限速功能,例如限制每位用戶、每個來源或每個 IP 位址的每秒查詢次數,也可以全域地針對所有查詢限速。我們採用的另外一項增強功能是自動調整規模。有了這個能在全 Meta 支援增加或減少工作數量規模的服務,現在的閘道實例數量便可靈活調整。這意味著當負載較大時,閘道可以擴大以處理額外流量,但又不會超出 CPU/記憶體的上限,這樣便可防止出現上述的死機情況。在此功能與限速功能的相輔相成下,我們可以確保閘道可靠穩定,得以承受無法預測的惡劣流量狀況。
圖 5:Presto 架構擴展(圖表製作者:Philip S. Bell)
在擴大 Presto 規模時,請牢記以下幾個重點:
本文由 Meta 生產工程師 Neerad Somanchi 與 Meta 開發人員大使 Philip Bell 合作撰寫。
如需深入了解 Presto,歡迎瀏覽 prestodb.io、在 YouTube 上觀看 Philip Bell 的 Presto 簡介,或在 Twitter、Facebook 和 LinkedIn 上追蹤 Presto。
如需進一步了解 Meta Open Source,歡迎瀏覽我們的開放原始碼網站、訂閱我們的 YouTube 頻道,或在 Twitter、Facebook 和 LinkedIn 上追蹤我們。