Presto 是免費的開放原始碼 SQL 查詢引擎。過去十年間,Meta 都使用此工具,邊做邊學到許多寶貴的經驗。大量執行任何內容,無論工具、程序、服務,都需要解決問題的能力,才能克服意料之外的挑戰。如果您有興趣大量執行查詢,以下是我們從 Presto 擴充為 Meta scale 之際獲得的四大心得及一些建議!
圖 1:發佈新版 Presto 的程序工作流程(製圖:Philip S. Bell)
Meta 橫跨全球各地的資料中心執行大量 Presto 叢集。新版 Presto 設計為可直接部署,每個月至少一次,有時兩次。Meta 在推動 Presto 時最先面臨的挑戰之一,是如何在查詢引擎部署到大量叢集同時,確保一致的可用性和可靠性。在 Presto 的互動式使用案例中更是如此,也就是指用戶啟動查詢且主動等待結果的情境。在自動化「批次」使用案例中,查詢失敗比較不需要擔心,因為可藉由自動重試確保查詢最終成功。
此情況能輕鬆解決。所有 Presto 叢集落在稱為「閘道」的負載平衡器後方,閘道(配合 Meta 的其他系統)會負責替 Presto 查詢安排適當的叢集路徑。Presto 叢集需要更新時,會先從閘道將其標示為「已耗盡」,即:閘道會停止將新查詢的路徑安排到該處。然後,自動化程序會根據預先決定的時間,等待目前在叢集上執行的查詢完成。接著更新叢集,一上線之後,閘道就可以看見,並開始將新查詢安排至該路徑。
部署 Presto 新版本的其他面向還包括可用性。我們得確保用戶在叢集更新的同時,仍可使用 Presto。同樣的,自動化程序會確保每個物理地區的每個資料中心,總是有所需的 Presto 叢集數量可用。當然,勢必得在一次撤掉過多叢集(可用性問題)和一次撤掉過少(部署時間過長)之間求取平衡。
圖 2:新增硬體至叢集的自動化工作流程(製圖:Philip S. Bell)
Meta 跨不同地區的資料倉儲分佈不斷更動中。也就是說,必須固定豎立新的 Presto 叢集並解除現有叢集。過去 Presto 叢集為數不多時,我們採用手動程序。隨著 Meta 的規模逐漸擴增,手動追蹤所有變更很快就成為挑戰。為了解決此問題,我們採用自動化程序處理叢集的豎立和解除。
首先,我們得將叢集設定標準化,亦即:必須為 Meta 不同的 Presto 使用案例建立基礎設定。接著在基礎設定之餘,每個叢集還有最低限度的額外或覆寫規格。完成後,即可從基礎範本自動化產生設定,以此方式建起新叢集。建起叢集還需要與自動化勾點整合,以便與各式各樣的全公司基礎架構服務整合,例如:Tupperware 及資料倉儲專屬服務。叢集上線後,會將一些測試查詢傳送至叢集,並由自動化程序驗證叢集已成功執行查詢。接著,查詢就會在閘道註冊,並開始提供查詢處理服務。
解除叢集基本上為相反程序。在閘道取消註冊叢集,並允許任何執行中的查詢完成。Presto 程序會關閉,叢集設定則會刪除。
此自動化程序會與資料倉儲的硬體豎立及解除工作流程整合。最終結果為資料中心出現新硬體、乃至 Presto 叢集上線及提供查詢服務,直到硬體解除時關閉的整個程序全面自動化。落實前述自動化可省下寶貴的工時、縮短硬體閒置時間,並將人為錯誤降到最低。
圖 3:不良主機偵測(製圖:Philip S. Bell)
由於 Meta 大量部署 Presto,因此我們不可避免必須採用工具和自動化程序,讓 oncall(Presto 的接觸點)週期更輕鬆。
多年來,我們已建立多種「分析器」,協助 oncall 有效偵錯與評估發生問題的根本原因。客戶面 SLA 遭到入侵時,監控系統會發出警報。接著會觸發分析器。來自廣大監測系統的原始資訊(Operational Data Store 或 ODS)、發佈至 Scuba 的事件,甚至主機層級記錄。然後,分析器中的自訂邏輯會將這類資訊全數綁定,藉此推論可能的根本原因。根本原因分析對 oncall 特別有用,可讓此函數直接跳入可能的風險降低選項。有些時候,我們會將偵錯和補救兩者完全自動化,oncall 甚至不需要介入。以下提供幾個範例:
在大量機器上大量執行 Presto 時,我們發現特定的「不良」主機可能導致過量的查詢失敗。根據調查,我們找出幾個導致主機「不良」的根本原因,包括:
為了對抗此問題,我們現在會監控 Presto 叢集中的查詢失敗。具體來說,我們盡量將每一次查詢失敗歸因於導致該錯誤的主機。另外,我們也設定在發生大量可歸因於特定主機的查詢失敗時,發出警報。然後,自動化程序會介入,從 Presto 叢集隊伍中除去該主機,以此方式遏止查詢失敗。
根據使用案例、硬體設定和查詢規模,每個 Presto 叢集都在達到所執行查詢的最高並行性時,支援佇列查詢。Meta 採用成熟的路徑安排機制,可將 Presto 查詢調度至「正確」的叢集,由其執行查詢,同時使資源獲得最佳運用。在 Presto 之外還有多個系統參與路徑安排決策,並且考量多項因素:
由於其複雜性,oncall 要找出生產期間遭遇的任何佇列問題之根本原因,實為一個難題。這一點再次強調分析器的重要性,分析器可從多個來源提取資訊並整理出結論。
圖 4:負載平衡器的穩固性(製圖:Philip S. Bell)
如上所述,我們的 Presto 叢集落在負載平衡器後方。負載平衡器會安排 Meta 每個單一 Presto 查詢的路徑。一開始,在 Presto 尚未擴充至目前的內部使用規模時,閘道非常簡單。不過,隨著 Meta 的 Presto 使用量日漸增加,我們就在許多情境下面臨擴充性問題。其中一個問題是閘道因為沈重的負載而故障,進而導致 Presto 無法提供所有用戶使用。有些導致不穩定問題的根本原因,在於其中一項服務無意中不斷向閘道提出查詢,在短時間內轟炸數百萬次查詢,導致閘道程序損毀且無法安排任何查詢的路徑。
為了避免此情境,我們著手讓閘道更加穩固,並提高面對這類非刻意 DDoS 式流量的容忍力。我們落實節流功能,在負載沈重時拒絕查詢。節流會根據所有查詢各維度的每秒查詢數啟動節流,如每位用戶、每個來源、每個 IP,以及共用層。我們落實的另一項強化功能是自動調整。仰賴 Meta 上下支援調整工作規模的服務,閘道實例的數量現在具有動態性質。也就是說,在負載沈重時,閘道現在可以擴增處理額外流量,在 CPU/記憶體對外流量不會達到最大值,因此得以避免上述的損毀處境。再配合節流功能,即可確保閘道穩固且可耐受不在預期中的不利流量模式。
圖 5:Presto 架構調整(製圖:Philip S. Bell)
擴充 Presto 時,請謹記這幾個重要面向:
本文與 Meta 生產工程師 Neerad Somanchi 及 Meta 開發人員協調人 Philip Bell 合作撰寫。
若要進一步瞭解 Presto,請造訪 prestodb.io、觀賞 Philip Bell 在 YouTube 上的 Presto 快速說明,或在 Twitter、Facebook 和 LinkedIn 上追蹤 Presto。
若要進一步瞭解 Meta 開放原始碼,請造訪我們的開放原始碼網站、訂閱我們的 YouTube 頻道,或追蹤我們的 Twitter、Facebook 和 LinkedIn 帳號。