自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

B站基于緩存優(yōu)化 PRESTO 集群查詢性能

大數(shù)據(jù)
本次分享主題為 B 站 Presto 集群查詢性能的優(yōu)化,首先會(huì)簡單介紹 Presto以及 B 站內(nèi)部 Presto 集群的架構(gòu)。接下來講解針對(duì) Presto 做的改造,主要是 Presto 搭配 Alluxio 和 Presto 搭配 Alluxio local cache 的使用。最后會(huì)對(duì)后續(xù)計(jì)劃開展的工作做簡要說明。

一、集群架構(gòu)

1、B 站 SQL On Hadoop

下圖為 B 站 Presto 集群的架構(gòu)圖,最上層是內(nèi)部的一些數(shù)據(jù)服務(wù),所有服務(wù)統(tǒng)一接入 Dispatcher。Dispatcher 是一套內(nèi)部自研的服務(wù),根據(jù)查詢 HDFS 的數(shù)據(jù)量、目前引擎的負(fù)載情況等將用戶提交的 query 路由到相應(yīng)的引擎進(jìn)行執(zhí)行。對(duì)于 presto 的查詢語法和 hive/spark 語法可能出現(xiàn)的不兼容問題,我們引進(jìn)了 Linkedin 的開源軟件 Coral,將 hive 和 spark 的語法轉(zhuǎn)換為 presto 的語法進(jìn)行執(zhí)行。

計(jì)算引擎的路由邏輯:對(duì)于查詢量比較小的 sql,會(huì)優(yōu)先路由到 presto 進(jìn)行執(zhí)行,如果失敗則降級(jí)到 spark 進(jìn)行執(zhí)行,再失敗則降級(jí)到 hive 進(jìn)行執(zhí)行。

調(diào)度平臺(tái)(ETL):用戶可以通過調(diào)度平臺(tái)編寫調(diào)度作業(yè)來執(zhí)行調(diào)度任務(wù),具體是由 yarn 來調(diào)度。

Ranger:目前 HDFS 和 hive/presto/spark 都已經(jīng)接入到 Ranger 進(jìn)行統(tǒng)一的權(quán)限控制。權(quán)限控制包括表字段級(jí)別的控制以及 column masking 和 row filter 的控制。

圖片

2、Presto 集群現(xiàn)狀

目前 Presto 包括了四套集群,分為兩個(gè)機(jī)房(IDC1 和 IDC2)。除了Cluster3 之外的集群都實(shí)現(xiàn)了跨機(jī)房功能,目前集群數(shù)最多的為 IDC2 的 Cluster1(441 為集群數(shù)量,2 為 coordinator 數(shù)量)。Presto 集群平均每月作業(yè)數(shù)量 500w,每日作業(yè)數(shù)約 16w~17w。平均每月讀 HDFS 數(shù)據(jù)量約 300PB,每日 10PB。

圖片

3、Presto 集群架構(gòu)

Presto 集群的架構(gòu)大致如下,用戶作業(yè)提交后,會(huì)先通過一個(gè)開源組件Presto-Gateway,將 sql 作業(yè)路由到對(duì)應(yīng)的 IDC 機(jī)房中相對(duì)應(yīng)的 presto 集群中的 coordinator 節(jié)點(diǎn)進(jìn)行執(zhí)行。

圖片

二、Presto 簡介

1、Presto 歷史

Presto 是 2013 年 11 月份由 Facebook 開源的一個(gè)分布式 sql 查詢引擎,設(shè)計(jì)之初是為了進(jìn)行 OLAP 數(shù)據(jù)查詢,支持標(biāo)準(zhǔn)的 ANSI SQL,也支持多數(shù)據(jù)源。在 2019 年 1 月時(shí) Presto 內(nèi)部分裂出了兩個(gè)分支:PrestoSQL(trino)和 PrestoDB。PrestoSQL 相對(duì)于 PrestoDB 來說社區(qū)活躍度較高且更加注重 OLAP 的方向,而后者相對(duì)更注重 ETL 的方向。

圖片

2、Presto 基本原理

Presto 是一個(gè)典型的主從架構(gòu),它由一臺(tái) coordinator 和多個(gè) worker 構(gòu)成,Presto worker 啟動(dòng)時(shí)會(huì)在 coordinator 進(jìn)行注冊(cè)。Presto 集群作業(yè)的執(zhí)行流程是:

1.coordinator 收到作業(yè)后通過 sql 解析器對(duì)作業(yè)進(jìn)行解析生成語法樹, LogicPlanner 再對(duì)語法樹進(jìn)行語義分析,將 AST 轉(zhuǎn)為邏輯執(zhí)行計(jì)劃,同時(shí)使用優(yōu)化器進(jìn)行優(yōu)化。接著通過 DistributedPlanner 將計(jì)劃進(jìn)行切分生成多個(gè) stage,stage 內(nèi)部劃分為多個(gè) task, 通過 scheduler 將多個(gè) task 分發(fā)到不同的 worker 上執(zhí)行。由于Presto 本身不存儲(chǔ)數(shù)據(jù),需要通過多個(gè)connector 來訪問不同數(shù)據(jù)源的數(shù)據(jù)。

圖片

三、Presto 改造

我們對(duì) Presto 做的改造主要從可用性、穩(wěn)定性和性能提升三個(gè)角度出發(fā)。

圖片

Presto在B站的實(shí)踐:https://mp.weixin.qq.com/s/9_lSIFSw5o8sFC8foEtA7w 

1、可用性改進(jìn)

① Presto 和 hive 語法之間兼容性的操作。

② Hive Ranger Plugin 的兼容。

在 Ranger 社區(qū)中,不同的引擎有不同的 policy 進(jìn)行管理,我們使用了hive 的 policy 來統(tǒng)一進(jìn)行管理。

2、穩(wěn)定性改進(jìn)

① Coordinator 的多活改造。

Presto 的主從架構(gòu)存在單點(diǎn)故障的問題,也就是當(dāng) Coordinator 發(fā)生故障的時(shí)候會(huì)影響到整個(gè)集群的查詢。多活改造保證了當(dāng)某一個(gè) Coordinator 發(fā)生故障的時(shí)候,另一個(gè) Coordinator 會(huì)繼續(xù)對(duì)外進(jìn)行服務(wù)。此外,多活也可以減輕單臺(tái) Coordinator 的作業(yè)壓力。

② label 改造。

由于多個(gè)部門同時(shí)使用 Presto 集群進(jìn)行查詢,其中有一些部門對(duì)于作業(yè)的實(shí)時(shí)性要求比較高,有些部門會(huì)提交查詢數(shù)據(jù)量較大的 query 語句,這就會(huì)導(dǎo)致大 query 擠壓 Presto 的查詢性能,使實(shí)時(shí)性要求高的查詢無法完成。因此我們對(duì) worker 進(jìn)行了標(biāo)簽的改造,同時(shí)在用戶提交任務(wù)時(shí)也給任務(wù)打上標(biāo)簽,這樣 scheduler 在分發(fā)任務(wù)的時(shí)候就會(huì)根據(jù)任務(wù)標(biāo)簽和 worker 標(biāo)簽將任務(wù)分配到相應(yīng)的 worker 上去執(zhí)行。

③ 實(shí)時(shí)懲罰。

label 改造實(shí)現(xiàn)了不同部門之間 worker 資源的隔離,但對(duì)于同一個(gè)部門不同的業(yè)務(wù)還是會(huì)存在大 query 擠壓資源的現(xiàn)象。因此我們引進(jìn)實(shí)時(shí)懲罰策略,對(duì)于提交的大語句判斷對(duì)應(yīng)的 resource group 并分配 CPU 的閾值。如果超過閾值,Presto worker 會(huì)進(jìn)行 split 并下發(fā)懲罰信息暫停執(zhí)行,等整體 resource group 資源占用量低于閾值后再恢復(fù)調(diào)度。

④ 查詢限制。

在 presto Gateway 對(duì) bad sql 進(jìn)行攔截。包括短時(shí)間內(nèi)重復(fù)提交、查詢HDFS 數(shù)據(jù)量較大(超過 30TB)的查詢語句。

3、性能提升

性能提升主要圍繞 Presto 緩存來進(jìn)行,緩存有三部分,分別為數(shù)據(jù)源/元數(shù)據(jù)/結(jié)果集的緩存。

四、Presto on Alluxio

前面幾章主要講解了我們內(nèi)部對(duì) presto 的改造,接下來介紹 presto 對(duì)數(shù)據(jù)源和元數(shù)據(jù)的緩存。首先是對(duì)于 Alluxio 做緩存的介紹。

1、背景介紹 — Presto 痛點(diǎn)

① 計(jì)算存儲(chǔ)分離架構(gòu)帶來網(wǎng)絡(luò)開銷。

和傳統(tǒng)的 MySQL(存算一體)的數(shù)據(jù)庫不同,Presto 是一個(gè)存算分離的數(shù)據(jù)庫。Presto 本身只做計(jì)算不做存儲(chǔ),它通過多個(gè) connector 實(shí)現(xiàn)遠(yuǎn)端獲取數(shù)據(jù),也可以實(shí)現(xiàn)聯(lián)邦查詢。但從遠(yuǎn)端獲取數(shù)據(jù)必然會(huì)帶來網(wǎng)絡(luò)上的性能開銷。

② 容易受慢 rpc (Remote Procedure Call) 或熱 dn 影響,查詢性能不穩(wěn)定。

我們 Presto 主要的場景是查詢 hive 表為主,需要去底層查詢 HDFS 的數(shù)據(jù)。由下圖可見,Presto 查詢 HDFS 時(shí)每隔一段時(shí)間就會(huì)有較長時(shí)間的慢 rpc 請(qǐng)求,進(jìn)而導(dǎo)致 Presto 查詢性能的不穩(wěn)定。

圖片

③ 缺少 data locality,性能方面有待提升。

2、背景介紹 — 熱數(shù)據(jù)

上部分從引擎的角度介紹了 Presto 的一些痛點(diǎn),此部分從業(yè)務(wù)數(shù)據(jù)的角度介紹為什么需要 Alluxio 做存儲(chǔ)。

下圖為對(duì) Presto query 血源信息做的 UI 展示,我們發(fā)現(xiàn)有些表/分區(qū)存在重復(fù)訪問的情況,比如圖中第一張表的訪問熱度(tableheat)達(dá)到了 866。我們可以對(duì)經(jīng)常被訪問的表進(jìn)行緩存,從而提升 presto 引擎的查詢性能。 

圖片

3、Alluxio 的引入

① 架構(gòu)變化。

架構(gòu)上的變化主要有兩個(gè),一是對(duì)于血緣變化的處理,二是添加了 Alluxio worker。

  • Alluxio worker

原先 Presto worker 直接從 HDFS 訪問數(shù)據(jù), 現(xiàn)在則是先通過 Alluxio worker 獲取數(shù)據(jù),如果 Alluxio 中沒有對(duì)應(yīng)數(shù)據(jù)再去最訪問 HDFS 獲取數(shù)據(jù)。

  • 增加 Presto 血緣信息解析用于獲取熱數(shù)據(jù)

Presto Coordinator 對(duì) sql 進(jìn)行解析時(shí),會(huì)將血緣信息吐到 Kafka 中,再通過消費(fèi)程序?qū)⑾鄳?yīng)的血緣信息落到數(shù)據(jù)庫中,最后通過自研的血緣分析服務(wù)對(duì)熱數(shù)據(jù)打上標(biāo)識(shí)。下一次 Coordinator 從 Hive Metastore 訪問分區(qū)時(shí)會(huì)判斷分區(qū)的參數(shù)是否有熱數(shù)據(jù)標(biāo)識(shí),如果有標(biāo)識(shí),接下來就會(huì)走 Alluxio 的邏輯。

圖片

4、Presto on Alluxio 的實(shí)現(xiàn)細(xì)節(jié)

① Alluxio 與 HDFS 的 scheme 不同。

當(dāng) Presto 去 Hive Metastore 查詢的時(shí)候,如果想要訪問 Alluxio 的數(shù)據(jù)時(shí),比較簡單的做法是將 Hive Metastore 里相應(yīng)的 scheme 轉(zhuǎn)換為 Alluxio 的 scheme,但這會(huì)帶來的問題是對(duì)于其他的引擎(比如 spark),因?yàn)槠浔緛砭蜎]有接入 Alluxio,會(huì)導(dǎo)致查詢不可用。對(duì)于這個(gè)問題,社區(qū)的解決方案是在高版本 Presto 中支持 Alluxio 連接器。原先 Presto 需要通過訪問 Hive Metastore 去獲取表信息,現(xiàn)在只需要訪問 Alluxio 就可以獲取信息。Alluxio 內(nèi)的 SDS 模塊有和 Hive Metastore 的通信功能,SDS 模塊會(huì)在 Alluxio 中將相應(yīng)的邏輯進(jìn)行封裝,再返還給 Presto 進(jìn)行處理。

其他互聯(lián)網(wǎng)公司方案:維護(hù)一套新的 Hive Metastore 來用于 adhoc 的場景,并定期將新 HMS 和原先的 HMS 保持同步。同時(shí)依靠自己開發(fā)的白名單來確定哪些表是需要 Alluxio 緩存的。

由于:

  • 維護(hù)一套新的 HMS 運(yùn)維成本太高。
  • 我們希望通過自己的方式來掌管需要把哪些表存到 Alluxio 中。

所以我們團(tuán)隊(duì)沒有使用上述兩種方案,而是通過打 Tag 的方式來控制哪些表走 Alluxio。我們的解決方案:改造 hive connector。因?yàn)槲覀冃枰ㄟ^ hive connector 來獲取 HMS 中的 parameter 信息,再通過識(shí)別分區(qū)參數(shù)里面 Alluxio 的 tag 來判斷是否走 Alluxio 的邏輯并且通過代碼將 scheme 替換成 Alluxio 的 scheme。

圖片

② Alluxio 緩存數(shù)據(jù)的確定。

  • 熱數(shù)據(jù) tag 設(shè)置

由于 Alluxio 緩存空間的有限性,沒有必要將所有數(shù)據(jù)進(jìn)行緩存,因此我們會(huì)對(duì)熱數(shù)據(jù)打上標(biāo)識(shí),只把熱數(shù)據(jù)存儲(chǔ)到 Alluxio 上。首先,在 Presto 端把 Presto query 血緣信息吐到 Kafka上,再通過 Kafka 消費(fèi)程序分析血緣信息并落到 Tidb 上。血緣信息主要包括 query 語句,涉及到的 queryid 以及查詢表和分區(qū)。接下來通過緩存策略服務(wù)判斷數(shù)據(jù)熱度,并對(duì)熱度高的數(shù)據(jù)打上 tag。

  • 緩存策略

訪問熱度判斷:計(jì)算表一周平均訪問次數(shù),再根據(jù)全量表一周內(nèi)的被訪問頻率確定劃分閾值,高于閾值的為熱表。

計(jì)算 TTL(離當(dāng)前最遠(yuǎn)的熱分區(qū)的時(shí)間跨度)數(shù)據(jù):使用滑動(dòng)窗口的方式實(shí)現(xiàn)對(duì)離當(dāng)前時(shí)間點(diǎn)最近的熱分區(qū)的時(shí)間跨度計(jì)算,在 Alluxio 中剔除超過最遠(yuǎn)時(shí)間點(diǎn)熱度分區(qū)并將最近 logdate 的分區(qū)添加進(jìn)緩存中。

圖片

③ 數(shù)據(jù)一致性保證。

當(dāng)?shù)讓?HDFS 數(shù)據(jù)發(fā)生變更的時(shí)候,Alluxio 中便可能出現(xiàn)緩存了舊數(shù)據(jù)和臟數(shù)據(jù)的情況。針對(duì)這一問題,社區(qū)普遍的解決方案是通過配置參數(shù)達(dá)到和 HDFS 的元數(shù)據(jù)同步。但我們實(shí)踐過程中由于存在慢 rpc 的情況,所以無法使用社區(qū)的解決方案。為此我們自己開發(fā)了一套緩存失效服務(wù)來監(jiān)聽 Hive Meta Event,當(dāng)監(jiān)聽到 alter partition  或者 drop partition 的事件時(shí),服務(wù)會(huì)自動(dòng)剔除 Alluxio 中存在的相應(yīng)分區(qū)。同時(shí),我們也會(huì)監(jiān)聽 add partition事件。當(dāng) add partition 事件并且表的熱度較高時(shí),我們也會(huì)將相應(yīng)分區(qū)緩存入 Alluxio。下面是 Presto on Alluxio 和 Presto on HDFS 的性能對(duì)比,查詢 Alluxio 對(duì)比查詢 HDFS 大概可以節(jié)省 20% 的查詢時(shí)間。

圖片

④ Presto on Alluxio 線上效果。

目前大約 30% 的 BI 業(yè)務(wù)已接入到 Alluxio 的緩存中,已緩存 20w 分區(qū)(約45TB)。改造后 Presto 讀 HDFS 的穩(wěn)定性有大幅提升,基本控制在 2.5ms 以內(nèi)。

圖片

⑤ Presto on Alluxio 線上故障。

問題:RocksDB 做元數(shù)據(jù)存儲(chǔ)的時(shí)候,線上 Master 進(jìn)程偶發(fā) crash。

主要背景:Alluxio 原本是放在容器中的,Alluxio 主進(jìn)程突然發(fā)生 crash,拉起 Alluxio 容器后出現(xiàn)了日志丟失的問題。

為了排查 crash 原因,我們將 Alluxio 部署到物理機(jī)上,在物理機(jī)上通過添加一些 JVM 的參數(shù),等待問題的再次發(fā)生。

下圖為 JVM 崩潰時(shí)打印出來的錯(cuò)誤日志,整個(gè)異常棧的調(diào)用過程為 client 端向 Alluxio 發(fā)請(qǐng)求獲取文件狀態(tài)時(shí),會(huì)通過 Rocksdb getlocation,再通過 blockid 獲得其對(duì)應(yīng)的信息。在操作的過程中,rocks object 對(duì)象發(fā)生了 GC 被 JVM 回收了,但 rockesdb 是 c++ 的 jni 里面還有該引用,所以會(huì)產(chǎn)生 segment fault, 內(nèi)存地址越界,最后導(dǎo)致了 JVM 的崩潰。此問題已經(jīng)在社區(qū)中有了相應(yīng)的修復(fù)。具體可見以下鏈接:

https://github.com/Alluxio/alluxio/pull/14856

https://groups.google.com/g/rocksdb/c/PwapmWw 

圖片

五、Presto on Local Cache

1、RaptorX 背景

由于 Presto 在執(zhí)行計(jì)劃階段需要訪問 HMS 獲取表和分區(qū)的信息,而HMS 的響應(yīng)受單點(diǎn) mysql 的吞吐影響,存在慢查詢。

Presto 在構(gòu)建 split 以及讀數(shù)據(jù)的情況下需要訪問 HDFS。HDFS 作為底層存儲(chǔ)對(duì)接了許多計(jì)算引擎,如 Hive、spark 等,在 RPC 請(qǐng)求穩(wěn)定性方面經(jīng)常存在 slow rpc,在讀 datanode 數(shù)據(jù)時(shí),存在 slow dn。因此 RaptorX 應(yīng)運(yùn)而生,它通過對(duì)元數(shù)據(jù)與數(shù)據(jù)源進(jìn)行全方面緩存來解決上述問題。

圖片

圖:presto 執(zhí)行階段

2、RaptorX 功能介紹

  • Hive Meta Cache

在 Presto 端的 Coordinator 側(cè)對(duì) hive 端的 meta 信息做了緩存,但是考慮到元數(shù)據(jù)會(huì)出現(xiàn)變更,于是我們添加了版本號(hào)。每次請(qǐng)求元數(shù)據(jù)時(shí),我們會(huì)將版本號(hào)和 HMS 中的版本號(hào)做匹配,判斷緩存的是否是一個(gè)新的 hive meta 數(shù)據(jù)。

  • File List Cache

在 Presto 的 coordinator 側(cè)對(duì) HDFS 的元數(shù)據(jù)做一些緩存,避免長時(shí)間的 list status 操作。

  • Fragment Result Cache

在 Presto worker 節(jié)點(diǎn)對(duì)部分查詢結(jié)果做緩存,避免重復(fù)計(jì)算。

  • Orc/Parquet Footer Cache

對(duì) orc 或者 parquet 格式的文件的 foote r做緩存,提升 presto 查詢的性能。

  • Alluxio Data Cache
  • Soft Affinity scheduling

圖片

Raptorx 相關(guān)文章:??https://prestodb.io/blog/2021/02/04/raptorx、??

3、Presto Local Cache-Alluxio Local 模式

在 local 模式中,我們把 Alluxio 通過架構(gòu)的形式嵌入到 Presto worker的進(jìn)程中,對(duì) Presto 集群進(jìn)行統(tǒng)一的管理。這種模式相對(duì)于 Presto on Alluxio 來說更加輕量以及便于維護(hù)。

圖片

4、Presto Local Cache-Soft Affinity scheduling

搭配 Alluxio Data Cache 使用,它可以使同一個(gè) split 盡可能分發(fā)到同一個(gè) worker 節(jié)點(diǎn),保證緩存的命中率。

實(shí)現(xiàn)方式有兩種,第一種是基于 Hash & Mod,第二種是基于一致性 Hash。

Hash & Mod 是通過 Hash 計(jì)算,把 split 分發(fā)到對(duì)應(yīng)的 worker 節(jié)點(diǎn)。它的缺陷是當(dāng) worker 節(jié)點(diǎn)數(shù)發(fā)生變動(dòng)時(shí)(如故障等),總的 worker 節(jié)點(diǎn)數(shù)就會(huì)發(fā)生變化,會(huì)導(dǎo)致 split 重新分發(fā)到別的 worker 節(jié)點(diǎn)。

一致性 hash 就是為了解決這個(gè)問題而提出的,其基本思路是通過一個(gè)哈希環(huán)(0-max(value)),首先將 Presto worker 給 Hash 到這個(gè)哈希環(huán)上,然后再將 split 哈希到環(huán)上。在選定方向后,在環(huán)上離 split 最近的一個(gè) worker 會(huì)對(duì) split 進(jìn)行處理。這么做的好處是當(dāng)  Presto worker 發(fā)生故障的時(shí)候,只有原先分發(fā)到這個(gè) worker 的 split 才會(huì)重新分發(fā)到別的節(jié)點(diǎn)處進(jìn)行執(zhí)行,此外還有一點(diǎn)優(yōu)化,單臺(tái) worker 可能會(huì)出現(xiàn)負(fù)載較高的情況,因此我們對(duì)一致性 Hash 提出了虛擬節(jié)點(diǎn)的概念。比如將一臺(tái) worker 映射到三臺(tái) worker 分配到哈希環(huán)上,再重新進(jìn)行 split 的分發(fā),這樣可以做到 split 更加均勻的分發(fā)到不同的 worker 節(jié)點(diǎn)上。

圖片

5、Presto Local Cache – Alluxio Cluster

圖片

6、Presto Local Cache – Local vs Cluster

接下來我們看 presto on local cache 和 presto on alluxio cluster 的區(qū)別。

Local 是以 jar 包的形式嵌入到 presto 的進(jìn)程中,cluster 則是需要維護(hù)一套 Alluxio 集群,因此 cluster 的運(yùn)維成本更高。

第二點(diǎn)是緩存的粒度不同,local 緩存粒度更加細(xì),做到了 page 級(jí)別的緩存,cluster 是做文件級(jí)別的緩存。

第三點(diǎn)是 local 離計(jì)算節(jié)點(diǎn)資源更近,而 cluster 需要額外的計(jì)算機(jī)器資源來部署 Alluxio 集群。

圖片

7、Presto Local Cache – 改造點(diǎn)

  • Local cache 與底層數(shù)據(jù)一致性(presto 端改造)

當(dāng)?shù)讓?hdfs 文件發(fā)生變動(dòng)時(shí),Alluxio 中緩存的可能是舊的數(shù)據(jù)。這時(shí)候Presto 引擎查詢時(shí),返回的可能是不準(zhǔn)確的臟數(shù)據(jù)。改造的思路是基于文件的 LastModifiedTime(最后更改時(shí)間)來判斷,對(duì) Presto 來說最初是獲取 HDFS 的元數(shù)據(jù)文件時(shí)同時(shí)獲取,然后將相應(yīng)的信息封裝到 split 中,Presto 通過 scheduler 將相應(yīng)的 split 調(diào)度到 Presto worker 節(jié)點(diǎn),在節(jié)點(diǎn)處將相關(guān)的信息封裝到HiveFileContext 中。在具體構(gòu)建 pagesource 時(shí),將 HiveFileContext 傳到本地文件系統(tǒng)中。核心方法是openFile,它不同于傳統(tǒng)方法直接傳一個(gè) path 路徑,openFile 方法是傳一個(gè) HiveFileContext,因此它不是一個(gè)標(biāo)準(zhǔn)的 hadoop api。openFile 會(huì)通過 HiveFileContext 來判斷是否走 Alluxio。

HiveFileContext 的核心參數(shù)有:

(1)cacheable:搭配前文提到的 soft affinixity scheduling 使用,當(dāng)一臺(tái)worker 的負(fù)載達(dá)到上限,不得不調(diào)度到其他 worker 進(jìn)行執(zhí)行時(shí),由于這臺(tái) worker 只是臨時(shí)支援的,我們會(huì)將 cacheable 置 false。

(2)ModificationTime:用于在 Alluxio 中判斷緩存的是否是新的數(shù)據(jù)。

圖片

  • Local cache 與底層數(shù)據(jù)一致性(Alluxio 端改造)

Alluxio 端改造:

(1)當(dāng) presto 去底層讀取數(shù)據(jù)時(shí),通過 localcache.manage.get 得到對(duì)應(yīng)的 page,這時(shí)我們需要通過比較文件的 LastModifiedTime 和 Alluxio 內(nèi)存文件中的 LastModifiedTime 來判斷文件是否一致。

(2)構(gòu)建內(nèi)存數(shù)據(jù)結(jié)構(gòu)來保存文件以及時(shí)間信息

(3)持久化信息(可用于在 restore 中恢復(fù))

(4)修改 disk 的存儲(chǔ)路徑以及結(jié)構(gòu)

8、Presto Local Cache – Local Cache 啟動(dòng)問題

(1)Local Cache restore 時(shí)間點(diǎn)

Local cache 會(huì)去指定的 path 路徑加載 page,當(dāng) page 較多時(shí)就會(huì)出現(xiàn)加載耗時(shí)高的情況。如下圖所示,get file system 時(shí),我們會(huì)在 AlluxioCachingFileSystem 創(chuàng)建 local cache,再對(duì) localcache 進(jìn)行異步加載。但對(duì)于 Presto worker 來說,它第一次 get file system 是在 get split 的時(shí)候。這種時(shí)候可能 local cache 還沒有異步加載完畢,此時(shí)便會(huì)導(dǎo)致緩存命中率的下降。對(duì)此進(jìn)行的改造是:在 Presto worker 啟動(dòng)時(shí),構(gòu)建一個(gè)空路徑,通過空路徑構(gòu)建一個(gè) getfilesystem,同步對(duì) local file 進(jìn)行加載,然后再對(duì)外提供服務(wù)。

(2)Local Cache  加載失敗

local cache 主要是寫在 SSD 盤上,可能會(huì)遇到磁盤損壞,或者我們先添加一個(gè)新 path 路徑用于存儲(chǔ) page。但我們新添加的 path 路徑對(duì)應(yīng)的 SSD 可能存在磁盤容量身偏高的場景,于是我們?cè)O(shè)置了一個(gè) local cache 的開關(guān),在以上情況發(fā)生時(shí)會(huì)將 local cache 的開關(guān)關(guān)閉。

圖片

9、Presto Local Cache – Local Cache 支持 HDFS 文件系統(tǒng)

社區(qū)對(duì) local cache 實(shí)現(xiàn)的 scheme 要求為 Alluxio 和 ws 的 scheme,但我們的線上生產(chǎn)環(huán)境主要數(shù)據(jù)還是以 HDFS 為主,以 Alluxio 為輔。因此我們對(duì) Alluxio 代碼做了一些改造,使其能夠支持 hdfs 和 viewfs 的scheme。

10、Presto Local Cache — Local Cache 支持多磁盤

背景:單磁盤空間不足且 io 存在限制。

社區(qū)解決方法:通過 Hash&Mod 寫入多磁盤,這種方法的缺陷是沒有考慮到每個(gè)磁盤本身容量的情況。

我們的改造:借鑒 HDFS,基于 AvailableSpace 來做磁盤選擇?;舅悸肥菍?duì)多塊磁盤給到一個(gè)閾值,超過這個(gè)閾值的就認(rèn)為是容量比較高的,將其放到一個(gè)高容量的 list 中,反之亦然。然后給一個(gè)概率值,比如 0.75 的概率寫到高容量磁盤,0.25 的概率寫到低容量磁盤。為什么不直接把數(shù)據(jù)優(yōu)先寫入高容量磁盤呢,原因有二:

(1)磁盤容量只是其中一個(gè)考量因素,不能單純根據(jù)容量高就優(yōu)先寫;

(2)假設(shè)線上把所有 page 都寫入磁盤容量比較高的盤里面,會(huì)造成這個(gè)盤的 io 壓力過大的情況。

11、Presto Local Cache – Local Cache 測試效果

單并發(fā)場景下開啟 local cache 緩存可以減少 20% 左右的查詢時(shí)間,大大提升了查詢效率。四并發(fā)場景下測試查詢時(shí)間有一定提升,但相比單并發(fā)場景下,性能有一定的損失。

圖片

12、Presto Local Cache — Local Cache 線上效果

目前上線了 3 個(gè) presto 集群,緩存命中率約 40%。

13、Presto Local Cache — 社區(qū) PR 

  • Get raw filesystem should consider CachingFileSystem

(https://github.com/prestodb/presto/pull/17390, Merged) 

  • Wrapper the input and output stream of HadoopExtendedFileSystem

(https://github.com/prestodb/presto/pull/17365, Merged) 

  • Adapt disable filesystem cache

(https://github.com/prestodb/presto/pull/17367, Open) 

  • Support hdfs and viewfs as the external filesystem

(https://github.com/Alluxio/alluxio/pull/15131, Closed) 

  • Support timely invalidation of parquet metadata cache

(https://github.com/prestodb/presto/pull/17500, Merged) 

六、后續(xù)工作

1、推廣 local 模式上線多個(gè)集群

相對(duì)于 Presto on Alluxio, local cache 更加穩(wěn)定也更加輕量。于是我們后續(xù)將繼續(xù)推廣 Local 模式。

2、開發(fā)支持 textFile 格式的緩存

社區(qū)實(shí)現(xiàn)只支持 orc、parquet、rcFile,但線上有很多表用的是 textFile 的格式,所以我們需要開發(fā) textFile 的緩存。

3、開發(fā)磁盤檢測 

線上的一些 Presto 節(jié)點(diǎn)會(huì)存在慢節(jié)點(diǎn)的情況,需要對(duì)有問題的節(jié)點(diǎn)進(jìn)行隔離。

4、改進(jìn) Soft-Affinity 

原先 soft affinity 會(huì)將同一個(gè)文件的 split 分發(fā)到同一個(gè)節(jié)點(diǎn),會(huì)造成單臺(tái)worker 節(jié)點(diǎn)壓力比較大的情況,后續(xù)計(jì)劃使用 path+start 作為 key 來哈希,分散大文件分到單個(gè) worker split 的壓力。

5、改進(jìn) soft-affinity 排除不開啟 cache 的節(jié)點(diǎn) 

對(duì)于沒有 local cache 的 presto worker 進(jìn)行排除。

七、問答環(huán)節(jié)

Q1:presto 跨機(jī)房是如何實(shí)現(xiàn)的?

A1:由于業(yè)務(wù)發(fā)展,原本在一個(gè) idc 機(jī)房的機(jī)位已經(jīng)達(dá)到上限,需要開辟新的機(jī)房來存儲(chǔ)數(shù)據(jù)。在新機(jī)房部署 Hadoop 和 Presto 集群,大家比較容易想到的跨機(jī)房難點(diǎn)是資源緊張,因此我們?cè)O(shè)計(jì)了一套 Presto 跨機(jī)房的功能。內(nèi)部是通過用戶作業(yè)提交到 Presto Getaway,再由 Presto Getaway 分發(fā)到不同集群,對(duì) Presto Getaway 進(jìn)行改造:

1. 分析 sql 語句,看是查詢了哪些表和分區(qū),然后對(duì) nnproxy 做了改造,看這些表和分區(qū)在哪個(gè)機(jī)房下,數(shù)據(jù)量有多少,然后 Presto Getaway 會(huì)根據(jù)以上信息判斷這條 sql 語句會(huì)路由到哪個(gè)集群執(zhí)行。比如如果用戶提交來的 query 涉及到很多個(gè)表,首先對(duì)涉及到的表進(jìn)行分析,最后調(diào)度到占數(shù)據(jù)量最大的機(jī)房執(zhí)行。

2. 此外還有一些優(yōu)化工作。我們知道有個(gè)概念叫做移動(dòng)數(shù)據(jù)不如移動(dòng)計(jì)算,原先通過 hive connector 去訪問數(shù)據(jù)的話會(huì)出現(xiàn)帶寬資源比較緊張的現(xiàn)象,因此我們做了一個(gè)計(jì)算的下推。主要是實(shí)現(xiàn)了一個(gè)叫 IDC connector 的連接器。我們可以將第二個(gè)機(jī)房看作是一個(gè) connector,將跨機(jī)房的相應(yīng)邏輯拋到第二個(gè)機(jī)房的 presto coordinator 進(jìn)行處理。IDC2 的 Presto coordinator 獲取底層 HDFS 的數(shù)據(jù)并處理完成后會(huì)將結(jié)果返還給第一個(gè)機(jī)房做一個(gè)結(jié)果合并。此外我們還使用了 Alluxio 來緩存跨機(jī)房的數(shù)據(jù),比如我們的 query 語句被推到 IDC1 機(jī)房進(jìn)行執(zhí)行,但很多數(shù)據(jù)需要通過 IDC2 獲取,這時(shí) Alluxio 可以將熱度較高的數(shù)據(jù)跨機(jī)房進(jìn)行緩存,下次就只需要通過 Alluxio 來進(jìn)行跨機(jī)房數(shù)據(jù)的獲取。這兩個(gè)方法的好處都是可以減少跨機(jī)房的流量壓力。

Q2:Local Cache 需要部署集群服務(wù)嗎?

A2:不需要。對(duì)于 Alluxio 集群模式需要單獨(dú)部署 Alluxio 集群,然后 presto 訪問 Alluxio 集群。但如果使用 presto local cache 則不需要部署 alluxio 集群,Alluxio 是通過 jar 包的形式嵌入 presto 的進(jìn)程中,它跟原先的 presto cluster 是共用同一套 presto 集群的,因此相對(duì)于 presto on alluxio 來說它會(huì)更加的輕量級(jí)。

Q3:怎么統(tǒng)計(jì)緩存命中率?

A3:社區(qū)實(shí)現(xiàn)主要是對(duì) worker 端的 metrics進(jìn)行統(tǒng)計(jì),單臺(tái) worker 在生產(chǎn)環(huán)境中的命中率達(dá)到了 90% 以上。我們自己更加關(guān)注 coordinator 端的命中率。前面有提到 hive connector 讀取 HMS 中 split 的信息時(shí)會(huì)帶上參數(shù)來判斷是否走 Alluxio,我們會(huì)統(tǒng)計(jì) query 走 Alluxio 的次數(shù),除以整個(gè) presto 集群 query 的次數(shù)來得到緩存命中率。目前線上的緩存命中率基本可以達(dá)到 40% 左右。

Q4:怎么解決 local cache 的高并發(fā)性能問題?

A4:在我們的實(shí)驗(yàn)環(huán)境中。四并發(fā)查詢的響應(yīng)時(shí)間明顯不如單并發(fā),原因可能是因?yàn)閿?shù)據(jù)存在 SSD 盤上,在多次讀數(shù)據(jù)的時(shí)候存在磁盤 io 的限制。

Q5:local cache 的內(nèi)存占用大概是多少?

A5:我們發(fā)現(xiàn)存相同大小的文件,local cache 的內(nèi)存占用相對(duì)較低。這是因?yàn)?cluster 是基于文件級(jí)別存儲(chǔ)的,并且當(dāng)別的 Alluxio worker 參加執(zhí)行時(shí),別的 worker 也會(huì)緩存對(duì)應(yīng)文件。對(duì) local cache 來說,首先是緩存粒度更細(xì)(基于 page),只會(huì)精準(zhǔn)緩存某些 page。另外是 soft affinity scheduling 的策略,它會(huì)盡可能將文件對(duì)應(yīng)的 split 分發(fā)到 worker 執(zhí)行。就算遇到單 worker 負(fù)載高,分發(fā)到其他的 worker 上進(jìn)行執(zhí)行的情況時(shí),我們也會(huì)通過把 cacheable 參數(shù)置 false,讓臨時(shí) worker 不緩存文件。

責(zé)任編輯:姜華 來源: DataFunTalk
相關(guān)推薦

2023-12-29 12:12:04

廣告性能優(yōu)化

2024-08-13 12:54:20

2018-06-07 08:54:01

MySQL性能優(yōu)化索引

2013-06-26 16:12:21

MySQL集群性能優(yōu)化

2010-05-24 14:59:29

Hadoop集群

2025-02-04 10:58:16

2019-03-14 15:38:19

ReactJavascript前端

2011-10-19 09:41:15

ASP.NET性能優(yōu)化

2019-03-22 09:50:52

WebJavaScript前端

2020-06-11 13:03:04

性能優(yōu)化緩存

2023-07-12 08:55:16

PawSQL數(shù)據(jù)庫

2024-04-26 12:13:45

NameNodeHDFS核心

2021-01-31 17:50:41

數(shù)據(jù)庫查詢程序員

2024-09-19 08:09:37

MySQL索引數(shù)據(jù)庫

2011-10-17 09:54:18

ASP.NET性能

2021-06-10 10:02:19

優(yōu)化緩存性能

2022-04-22 14:41:12

美團(tuán)慢查詢數(shù)據(jù)庫

2023-04-04 12:38:50

GPT機(jī)器人LLM

2021-03-01 21:32:49

HTTP2 QUIC

2010-10-21 10:42:30

SQL Server查
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)