Lyft的Presto基礎架構

總覽

在2017年初,我們開始針對OLAP用例探索Presto,我們意識到了這種驚人的查詢引擎的潛力。 與Apache Hive相比,它起初是一種即席查詢工具,供數據工程師和分析人員以更快的方式運行SQL以建立其查詢原型。 當時,AWS-Redshift支持許多內部儀表板,並且數據存儲和計算已耦合在一起。 我們的數據呈指數增長(每隔幾天翻一番),這也需要頻繁地擴展存儲。 將存儲與計算相結合,進行任何維護,升級所需的停機時間以及擴展節點使查詢變得極其緩慢(隨著大量數據在節點之間移動),我們需要一個將數據和計算分離的系統,這就是Presto很好地適合我們的用例的地方 。 已經設置了以Parquet格式存儲事件數據的管道,並且正在通過Hive訪問數據。 將Presto添加到此堆棧中可謂錦上添花。

Lyft的Presto基礎架構

> Presto infra stack

現在,數以千計的儀表板由Presto提供支持,每週約有1.5K的活躍用戶每月在此平臺上運行數百萬個查詢。 到今天為止,我們已經在基於S3的數據湖中存儲了60 PB的可查詢事件數據,並且每天使用Presto掃描大約10 PB的原始數據。 以下圖表顯示了presto使用量增長的時間表。

Lyft的Presto基礎架構

> Monthly query volume growth

Lyft的Presto基礎架構

> Daily input data processed

在上面的圖表中,我們正在查看每天的原始數據掃描量。 在過去的4個月中,我們看到每日原始數據掃描量增長了4倍。

Presto客戶

Lyft用戶使用諸如Apache Superset,Mode,Looker,Tableau,Jupyter筆記本之類的查詢工具以及一些內部ML工具來消費數據,這些內部ML工具可構建和改善特定於應用程序的機器學習模型。 所有這些工具都通過Presto網關連接到presto,這些客戶端發送的查詢在多個Presto群集之間均勻地負載均衡。 使用網關,我們執行零停機時間升級,這對於通過這些客戶端進行查詢的用戶/應用程序是透明的。

設置:構建,發佈和部署

我們在lyft / presto下創建了prestosql / presto分支,並創建了lyft-stable穩定分支(如果需要,添加其他Cherry Picks)。 我們有一個專用存儲庫,在其中使用saltstack和aws-orca腳本將部署部署到我們的環境中。 在這個私有分支中,我們添加了特定於我們環境的其他依賴項,並添加了針對每個更新或請求請求運行的集成測試。 我們已經對該存儲庫進行了docker化,並將Docker容器用作開發環境。 在每次新提交時,我們都會通過Jenkins觸發針對開發環境的集成測試。

這是在將Presto投入生產時我們使用的各種組件。

· Lyft的presto查詢日誌插件:我們添加了一個基於Presto-Event偵聽器框架的查詢日誌記錄和阻止插件。 我們使用EventListener攔截新查詢的到達時間,並阻止一些我們認為對系統有害的查詢(例如,某些工具會主動緩存列名和查詢system.jdbc.columns或catalog.information_schema.columns並導致額外的重載 系統)。 我們在queryCreated和queryCompleted事件中記錄查詢統計信息,這有助於我們分析成功率,等待時間,各種類型的失敗及其根本原因等。

· Presto UDF:如果Presto中沒有解決用例的功能,我們可以讓用戶根據需要添加自定義UDF。 一些用戶已根據其用例添加了自定義地理功能。

· 基於Python的統計信息收集:我們正在使用datadog-agent lib,並添加了多項檢查以收集系統/ jvm /進程統計信息度量標準並推送至statsd。 我們有statsd收集器,用於收集指標並將其進一步推送到Wavefront。 我們設置了各種警報,並在發生閾值突破時通過pagerduty進行尋呼。

· 測試服:在將新的presto版本投入生產之前,我們運行多種測試以確保候選發佈版本的質量。

以下是我們為確保每個版本的質量而運行的測試類型。

一個。 集成測試套件-針對每個構建運行Table-CRUD和UDF測試,在Jenkins構建任務中啟動devbox docker容器。

b。 重新播放器測試套件-將發佈候選版本轉換為預生產版本後,我們將使用較早的有價值的查詢啟動為期一天的測試,以與過去執行查詢相同的方式進行重放。 我們使用事件記錄管道來提供查詢日誌,並將性能與先前記錄的數據進行比較。

C。 驗證程序測試套件—與replayer相似,我們使用presto-verifier來運行靜態查詢集並針對新舊版本運行。 如果性能結果未降低,我們將移至該版本。

1. PrestoInfra:收集配置和腳本,以構建和發佈可部署的工件,併發布saltstack腳本以部署特定於環境的部署。

1. PrestoProxy:具有lyft特定路由規則和替代的自定義presto網關。

Presto生產環境和配置

我們正在運行多個presto群集,每個群集通過presto-gateway共享負載,每個100多個工作節點。 節點規格如下

Lyft的Presto基礎架構

> Presto cluster configuration

Presto配置

在每個群集上,我們設置了25個最大查詢併發性和200個最大查詢隊列,每個隊列最多運行4個查詢,每個用戶運行20個查詢隊列。 每個查詢的最大運行時間限制為30分鐘,最大執行時間限制為10分鐘。 我們每天旋轉整個群集一次,以免生成較長的傳統GC。 我們讓每個查詢最多掃描1 TB的最大數據,而每個工作節點最多裝載10 GB的數據。 以下是實現這些設置的確切配置。

Lyft的Presto基礎架構

> Presto server properties

在Presto網關協調器中,每個路由協調器都可以分配一個路由組,設置X-Presto-Routing-Group標頭會將該請求路由到該路由組下的一個集群。 我們有一個集群,該集群在擴展內存限制下分配了nolimit路由組。 用戶必須在查詢中添加註釋" -highlimit"作為提示,以指示資源密集型查詢以及查詢到具有更高資源限制的集群的網關網關路由。

JVM配置

我們正在presto節點上運行Java 11。 Java 11具有用於舊時代的並行GC,大大減少了收集時間。

以下是我們用來運行presto進程的JVM配置。 通過Java 11升級,我們能夠將舊的GC暫停時間降低了幾秒鐘,而在Java 8中,它的峰值達到了400秒的時間,每隔一段時間就會破壞服務。

Lyft的Presto基礎架構

> Presto JVM config salt template

max_heap_size_mb的值為(0.6 * node_memory_mb),在工作程序節點上為114 GB。

Presto節點回收

儘管進行了所有優化,但是presto會隨著時間的推移而消耗主機資源,並且根據我們的經驗,我們瞭解到,服務運行的時間越長,它變得越慢。 隨著越來越多的查詢在群集上執行,舊式GC的暫停時間隨時間而增加,我們也注意到,與舊群集相比,較新的群集可產生更好的查詢性能。 牢記這一點,我們設計了基礎結構,每24小時回收一次每個群集中的所有節點。

我們使用PrestoGateway的停用API在計劃關閉時間之前30分鐘禁用集群,並在計劃啟動時間之後30分鐘通過cron激活集群,以提供無停機維護。 由於我們為每個查詢設置了30分鐘的最大運行時間,從而確保在這些操作期間不會丟失查詢。 我們正在使用aws-orca腳本來觸發AWS的ScheduledAction,以按照給定的時間表啟動或關閉整個presto集群。

這是用於在下午5:20關閉集群並在太平洋時間晚上7點重新啟動的鹽腳本。

Lyft的Presto基礎架構

> ASG scheduled action based presto scaling

Presto網關

Presto-Gateway是用於多個presto群集的有狀態負載均衡器,代理和路由器,它無需更改協議即可透明訪問底層的presto-後端。它從一個代理服務項目開始,以安全的方式將presto協調器公開給外部BI工具,例如Mode和Looker。隨著查詢量的增加,我們面臨著更頻繁的中斷,因為單個群集無法處理負載。我們很快意識到我們需要多集群設置。因此,我們將一個集群專用於每種查詢工具。儘管它減少了停機和事件的發生頻率,但我們仍未實現零停機時間維護,並注意到一個群集相對空閒,而另一個群集則處於較高排隊狀態。到那時,我們決定實現一個真正的代理負載平衡路由器。由於BI工具是外部工具,因此它們正在通過部署在我們網絡中的代理進行訪問,因此這些代理無法遵循HTTP重定向,因此我們需要實現真正的代理路由器和負載均衡器。

我們使用了JettyProxy,它是一個代理服務器,可以綁定自定義過濾器並插入代理處理程序。 我們在代理處理程序中實現了路由規則,該規則使我們可以攔截HTTP請求和響應,從而可以檢查查詢,源,標頭等,並基於此我們可以選擇後端主機來服務查詢請求。 客戶端發送兩種類型的請求:1.新查詢提交請求; 2.先前提交查詢的跟進請求。 PrestoGateway代理處理程序將查詢ID緩存到後端映射,以便它將後續請求粘貼到運行原始查詢的後端。

Presto Gateway具有3個組件:

BaseApp —它提供樣板代碼以通過yaml配置添加/刪除可插入組件,並且具有內置的指標註冊表模塊,可以輕鬆地為基於此的應用發出自定義指標。

Lyft的Presto基礎架構

> BaseApp class diagram

ProxyServer —它是在碼頭代理之上構建的庫,該庫提供具有可插入代理處理程序的代理服務器實現。

Lyft的Presto基礎架構

> ProxyServer class diagram

網關-此組件充當代理服務器的容器,並插入ProxyHanders中以提供代理,路由和負載平衡功能。 它還公開了一些端點和UI,以激活/停用後端以及最近提交的查詢的查詢歷史記錄視圖。

Lyft的Presto基礎架構

> Presto Gateway UI

我們正在使用lombok來減少很多樣板代碼,例如getters / setters / logger / equals等,從而加快了開發過程,並且該應用程序是使用dropwizard框架構建的。

具有成本意識的擴展以滿足查詢需求

我們從一個Presto群集開始,隨著使用量的增長,我們不斷增加更多的工作節點來支持更高的計算需求。 隨著我們添加更多的工作程序節點,為了充分利用群集的潛力,必須提高查詢併發設置,並且要求重新啟動協調器會導致停機。 介紹了presto-gateway之後,我們使用網關作為負載均衡器進入了多集群模式。 整個presto基礎架構使用情況並非一整天都在變化,並且工作負載的性質一直很突發,因此我們過度配置了基礎設施,因此,如果出現大量查詢,基礎設施應能夠優雅地吸收它。

Lyft的Presto基礎架構

> Query volume for a week (granularity — 1 hour)

為了優化成本,我們實施了動態擴展。 我們查看了傳入的查詢量比率,發現在工作時間內使用量通常較高。 在網關上實現後端激活/停用API後,我們已經能夠執行非停機升級,部署和維護。 我們將其提升到了一個新的水平,並在非工作時間將計劃停機時間增加了一半。 在觸發關機前30分鐘,我們使用網關API禁用群集,因為我們為任何查詢設置了30分鐘的最大運行時間,以確保在此過程中不會對查詢造成任何不利影響。 下圖顯示了節點數如何隨時間變化。

Lyft的Presto基礎架構

> Total number of nodes over a week time

在非工作時間減少50%的基礎設施,總體上可節省30%的成本。

Google表格連接器插件

這使Presto可以從Google表格中讀取數據,以便可以將較小尺寸的數據添加到查詢中。

Lyft的Presto基礎架構

> Querying google sheet as table in Presto

我們在Presto Summit 2019中宣佈了此功能,並將其貢獻回開源。

侷限性

當前,gsheets連接器插件具有以下限制。

  • · 如果工作表不是公開的,則所有工作表必須至少與服務帳戶用戶共享,並且必須具有視圖訪問權限。
  • · 工作表的第一行始終被視為具有所有列名稱的標題。
  • · 所有列都使用VARCHAR類型解析。

· Gsheets API的速率限制-如果Google Project帳戶未啟用結算功能,則每100秒100次調用(當天無限制)。 為了避免這種情況,用戶可以為高速緩存配置屬性選擇更高的值— presto-gsheets配置中的sheets-data-expire-after-write。

設定說明

以下是設置Presto Google表格插件的步驟:

第1步。

要使用此功能,用戶必須在創建項目並授予對Google Sheets API的讀取權限後,在Gsuite-console中生成服務帳戶JSON憑證。 該憑證文件應存儲在sheets.properties中,並作為憑證路徑。 服務帳戶用戶ID將在憑據文件中,用戶應與此服務帳戶用戶共享所有google工作表,以預先閱讀工作表。

第2步。

現在創建一個元數據表,並將表添加到表ID映射。 與服務帳戶用戶共享此工作表,並記下工作表ID。 在sheets.properties中將此工作表ID添加為metadata-sheet-id配置屬性。

第3步

現在,在元數據表單中添加表名稱和相應的表單ID(與服務帳戶用戶共享表單後),您應該能夠從表中以presto進行查詢。

Lyft的Presto基礎架構

> Metadata sheet

Lyft的Presto基礎架構

> Sample table

第4步。

查詢愉快!

Lyft的Presto基礎架構

> Show tables

Lyft的Presto基礎架構

> Desc table

Lyft的Presto基礎架構

> Selecting from table

該功能目前在lyft處於Beta測試階段,自從我們推出該功能以來,它已經變得非常流行,並且大約有數百名用戶每天已經在50多個Google表格上運行了數千個查詢。

Lyft的Presto基礎架構

> Google sheets as table usage — each color band is query volume per user

Superset Presto集成改進

在開發基於SQL的工作流或管道時,用戶面臨許多挑戰。 查詢瀏覽器提供錯誤和建議,以在執行查詢後修復語法錯誤(錯誤的SQL或錯誤的UDF使用)。 用戶需要花費一些時間才能通過多次迭代找出並解決此類錯誤,從而降低用戶體驗。 我們在Presto中實現瞭解釋類型(驗證)查詢,並在實際執行查詢之前在Superset中的sqlLab中以用戶類型的形式將這些解釋查詢作為用戶類型發送,並且返回的解釋計劃捕獲了語法錯誤以及列,表和udf簽名的有效性。 這樣可以執行深度查詢驗證,而無需實際執行整個查詢,從而消除了編寫複雜sql查詢所涉及的調試時間,從而改善了整體查詢體驗。

Lyft的Presto基礎架構

> Table name validation while writing presto query

Lyft的Presto基礎架構

> Column validation while writing the query

Lyft的Presto基礎架構

> UDF validation while writing the query

Apache Superset —預執行深度查詢驗證。 我們已經將這些功能貢獻回了開源。

摘要

對於Lyft的所有團隊來說,制定以數據為依據的決策非常重要,而Data Platform團隊的使命是使數據成為Lyft所做的所有決策的核心。 Presto是我們實現這一使命的關鍵組成部分。 在過去的兩年中,我們主要專注於擴展基礎架構,減少數據到達延遲,改善用戶查詢體驗,同時又具有成本效益。

非常感謝Data Platform Infra團隊的其他成員,他們幫助改善,擴展和支持Lyft的Presto基礎架構。

另外,還要感謝PrestoSQL開源社區的其餘成員在整個開發過程中為我們提供的幫助和支持。 請檢查此頁以瞭解如何參與該項目。

數據平臺團隊正在積極尋找才華橫溢的工程師,數據工程師,科學家,產品經理和市場營銷人員加入我們的團隊。 瞭解Lyft的生活,並訪問"職業"部分以獲取最新的職位空缺。

(本文翻譯自Puneet Jaiswal的文章《Presto Infrastructure at Lyft》,參考:https://eng.lyft.com/presto-infrastructure-at-lyft-b10adb9db01)


分享到:


相關文章: