presto是什么
是Facebook開源的,完全基于內(nèi)存的并?計(jì)算,分布式SQL交互式查詢引擎
是一種Massively parallel processing (MPP)架構(gòu),多個(gè)節(jié)點(diǎn)管道式執(zhí)?
?持任意數(shù)據(jù)源(通過擴(kuò)展式Connector組件),數(shù)據(jù)規(guī)模GB~PB級(jí)
使用的技術(shù),如向量計(jì)算,動(dòng)態(tài)編譯執(zhí)?計(jì)劃,優(yōu)化的ORC和Parquet Reader等
presto不太支持存儲(chǔ)過程,支持部分標(biāo)準(zhǔn)sql
presto的查詢速度比hive快5-10倍
上面講述了presto是什么,查詢速度,現(xiàn)在來看看presto適合干什么
適合:PB級(jí)海量數(shù)據(jù)復(fù)雜分析,交互式SQL查詢,?持跨數(shù)據(jù)源查詢
不適合:多個(gè)大表的join操作,因?yàn)閜resto是基于內(nèi)存的,多張大表在內(nèi)存里可能放不下
和hive的對(duì)比:
hive是一個(gè)數(shù)據(jù)倉庫,是一個(gè)交互式比較弱一點(diǎn)的查詢引擎,交互式?jīng)]有presto那么強(qiáng),而且只能訪問hdfs的數(shù)據(jù)
presto是一個(gè)交互式查詢引擎,可以在很短的時(shí)間內(nèi)返回查詢結(jié)果,秒級(jí),分鐘級(jí),能訪問很多數(shù)據(jù)源
hive在查詢100Gb級(jí)別的數(shù)據(jù)時(shí),消耗時(shí)間已經(jīng)是分鐘級(jí)了
但是presto是取代不了hive的,因?yàn)閜全部的數(shù)據(jù)都是在內(nèi)存中,限制了在內(nèi)存中的數(shù)據(jù)集大小,比如多個(gè)大表的join,這些大表是不能完全放進(jìn)內(nèi)存的,實(shí)際應(yīng)用中,對(duì)于在presto的查詢是有一定規(guī)定條件的,比比如說一個(gè)查詢?cè)趐resto查詢超過30分鐘,那就kill掉吧,說明不適合在presto上使用,主要原因是,查詢過大的話,會(huì)占用整個(gè)集群的資源,這會(huì)導(dǎo)致你后續(xù)的查詢是沒有資源進(jìn)行查詢的,這跟presto的設(shè)計(jì)理念是沖突的,就像是你進(jìn)行一個(gè)查詢,但是要等個(gè)5分鐘才有資源繼續(xù)查詢,這是很不合理的,交互式就變得弱了很多
presto基本架構(gòu)
在談presto架構(gòu)之前,先回顧下hive的架構(gòu)

hive:client將查詢請(qǐng)求發(fā)送到hive server,它會(huì)和metastor交互,獲取表的元信息,如表的位置結(jié)構(gòu)等,之后hive server會(huì)進(jìn)行語法解析,解析成語法樹,變成查詢計(jì)劃,進(jìn)行優(yōu)化后,將查詢計(jì)劃交給執(zhí)行引擎,默認(rèn)是MR,然后翻譯成MR
presto:presto是在它內(nèi)部做hive類似的邏輯

接下來,深入看下presto的內(nèi)部架構(gòu)

這里面三個(gè)服務(wù):
Coordinator是一個(gè)中心的查詢角色,它主要的一個(gè)作用是接受查詢請(qǐng)求,將他們轉(zhuǎn)換成各種各樣的任務(wù),將任務(wù)拆解后分發(fā)到多個(gè)worker去執(zhí)行各種任務(wù)的節(jié)點(diǎn)
1、解析SQL語句
2、?成執(zhí)?計(jì)劃
3、分發(fā)執(zhí)?任務(wù)給Worker節(jié)點(diǎn)執(zhí)?
Worker,是一個(gè)真正的計(jì)算的節(jié)點(diǎn),執(zhí)行任務(wù)的節(jié)點(diǎn),它接收到task后,就會(huì)到對(duì)應(yīng)的數(shù)據(jù)源里面,去把數(shù)據(jù)提取出來,提取方式是通過各種各樣的connector:
1、負(fù)責(zé)實(shí)際執(zhí)?查詢?nèi)蝿?wù)
Discovery service,是將coordinator和woker結(jié)合到一起的服務(wù):
1、Worker節(jié)點(diǎn)啟動(dòng)后向Discovery Server服務(wù)注冊(cè)
2、Coordinator從Discovery Server獲得Worker節(jié)點(diǎn)
coordinator和woker之間的關(guān)系是怎么維護(hù)的呢?是通過Discovery Server,所有的worker都把自己注冊(cè)到Discovery Server上,Discovery Server是一個(gè)發(fā)現(xiàn)服務(wù)的service,Discovery Server發(fā)現(xiàn)服務(wù)之后,coordinator便知道在我的集群中有多少個(gè)worker能夠給我工作,然后我分配工作到worker時(shí)便有了根據(jù)
最后,presto是通過connector plugin獲取數(shù)據(jù)和元信息的,它不是?個(gè)數(shù)據(jù)存儲(chǔ)引擎,不需要有數(shù)據(jù),presto為其他數(shù)據(jù)存儲(chǔ)系統(tǒng)提供了SQL能?,客戶端協(xié)議是HTTP+JSON
Presto支持的數(shù)據(jù)源和存儲(chǔ)格式
Hadoop/Hive connector與存儲(chǔ)格式:
HDFS,ORC,RCFILE,Parquet,SequenceFile,Text
開源數(shù)據(jù)存儲(chǔ)系統(tǒng):
MySQL & PostgreSQL,Cassandra,Kafka,Redis
其他:
MongoDB,ElasticSearch,HBase
Presto中SQL運(yùn)行過程:整體流程

1、當(dāng)我們執(zhí)行一條sql查詢,coordinator接收到這條sql語句以后,它會(huì)有一個(gè)sql的語法解析器去把sql語法解析變成一個(gè)抽象的語法樹AST,這抽象的語法書它里面只是進(jìn)行一些語法解析,如果你的sql語句里面,比如說關(guān)鍵字你用的是int而不是Integer,就會(huì)在語法解析這里給暴露出來
2、如果語法是符合sql語法規(guī)范,之后會(huì)經(jīng)過一個(gè)邏輯查詢計(jì)劃器的組件,他的主要作用是,比如說你sql里面出現(xiàn)的表,他會(huì)通過connector的方式去meta里面把表的schema,列名,列的類型等,全部給找出來,將這些信息,跟語法樹給對(duì)應(yīng)起來,之后會(huì)生成一個(gè)物理的語法樹節(jié)點(diǎn),這個(gè)語法樹節(jié)點(diǎn)里面,不僅擁有了它的查詢關(guān)系,還擁有類型的關(guān)系,如果在這一步,數(shù)據(jù)庫表里某一列的類型,跟你sql的類型不一致,就會(huì)在這里報(bào)錯(cuò)
3、如果通過,就會(huì)得到一個(gè)邏輯的查詢計(jì)劃,然后這個(gè)邏輯查詢計(jì)劃,會(huì)被送到一個(gè)分布式的邏輯查詢計(jì)劃器里面,進(jìn)行一個(gè)分布式的解析,分布式解析里面,他就會(huì)去把對(duì)應(yīng)的每一個(gè)查詢計(jì)劃轉(zhuǎn)化為task
4、在每一個(gè)task里面,他會(huì)把對(duì)應(yīng)的位置信息全部給提取出來,交給執(zhí)行的plan,由plan把對(duì)應(yīng)的task發(fā)給對(duì)應(yīng)的worker去執(zhí)行,這就是整個(gè)的一個(gè)過程
這是一個(gè)通用的sql解析流程,像hive也是遵循類似這樣的流程,不一樣的地方是distribution planner和executor pan,這里是各個(gè)引擎不一樣的地方,前面基本上都一致的
Presto中SQL運(yùn)行過程:MapReduce vs Presto

task是放在每個(gè)worker上該執(zhí)行的,每個(gè)task執(zhí)行完之后,數(shù)據(jù)是存放在內(nèi)存里了,而不像mr要寫磁盤,然后當(dāng)多個(gè)task之間要進(jìn)行數(shù)據(jù)交換,比如shuffle的時(shí)候,直接從內(nèi)存里處理
Presto監(jiān)控和配置:監(jiān)控
Web UI
Query基本狀態(tài)的查詢
JMX HTTP API
GET /v1/jmx/mbean[/{objectName}]
? com.facebook.presto.execution:name=TaskManager
? com.facebook.presto.execution:name=QueryManager
? com.facebook.presto.execution:name=NodeScheduler
事件通知
Event Listener
? query start, query complete
Presto監(jiān)控和配置:配置
執(zhí)行計(jì)劃計(jì)劃(Coordinator)
node-scheduler.include-coordinator
? 是否讓coordinator運(yùn)行task
query.initial-hash-partitions
? 每個(gè)GROUP BY操作使?的hash bucket(=tasks)最大數(shù)目(default: 8)
node-scheduler.min-candidates
? 每個(gè)stage并發(fā)運(yùn)行過程中可使用的最大worker數(shù)目(default:10)
query.schedule-split-batch-size
? 每個(gè)split數(shù)據(jù)量
任務(wù)執(zhí)行(Worker)
query.max-memory (default: 20 GB)
? 一個(gè)查詢可以使用的最大集群內(nèi)存
? 控制集群資源使用,防止一個(gè)大查詢占住集群所有資源
? 使用resource_overcommit可以突破限制
query.max-memory-per-node (default: 1 GB)
? 一個(gè)查詢?cè)谝粋€(gè)節(jié)點(diǎn)上可以使用的最大內(nèi)存
舉例
? Presto集群配置: 120G * 40
? query.max-memory=1 TB
? query.max-memory-per-node=20 GB
query.max-run-time (default: 100 d)
? 一個(gè)查詢可以運(yùn)行的最大時(shí)間
? 防止用戶提交一個(gè)長時(shí)間查詢阻塞其他查詢
task.max-worker-threads (default: Node CPUs * 4)
? 每個(gè)worker同時(shí)運(yùn)行的split個(gè)數(shù)
? 調(diào)大可以增加吞吐率,但是會(huì)增加內(nèi)存的消耗
隊(duì)列(Queue)
任務(wù)提交或者資源使用的一些配置,是通過隊(duì)列的配置來實(shí)現(xiàn)的
資源隔離,查詢可以提交到相應(yīng)隊(duì)列中
? 資源隔離,查詢可以提交到相應(yīng)隊(duì)列中
? 每個(gè)隊(duì)列可以配置ACL(權(quán)限)
? 每個(gè)隊(duì)列可以配置Quota
可以并發(fā)運(yùn)行查詢的數(shù)量
排隊(duì)的最大數(shù)量

大數(shù)據(jù)OLAP引擎對(duì)比
Presto:內(nèi)存計(jì)算,mpp架構(gòu)
Druid:時(shí)序,數(shù)據(jù)放內(nèi)存,索引,預(yù)計(jì)算
Spark SQL:基于Spark Core,mpp架構(gòu)
Kylin:Cube預(yù)計(jì)算
最后,一些零散的知識(shí)點(diǎn)
presto適合pb級(jí)的海量數(shù)據(jù)查詢分析,不是說把pb的數(shù)據(jù)放進(jìn)內(nèi)存,比如一張pb表,查詢count,vag這種有個(gè)特點(diǎn),雖然數(shù)據(jù)很多,但是最終的查詢結(jié)果很小,這種就不會(huì)把數(shù)據(jù)都放到內(nèi)存里面,只是在運(yùn)算的過程中,拿出一些數(shù)據(jù)放內(nèi)存,然后計(jì)算,在拋出,在拿,這種的內(nèi)存占用量是很小的,但是join這種,在運(yùn)算的中間過程會(huì)產(chǎn)生大量的數(shù)據(jù),或者說那種查詢的數(shù)據(jù)不大,但是生成的數(shù)據(jù)量很大,這種也是不合適用presto的,但不是說不能做,只是會(huì)占用大量內(nèi)存,消耗很長的時(shí)間,這種hive合適點(diǎn)
presto算是hive的一個(gè)補(bǔ)充,需要盡快得出結(jié)果的用presto,否則用hive
work是部署的時(shí)候就事先部署好的,work啟動(dòng)100個(gè),使用的work不一定100個(gè),而是根據(jù)coordinator來決定拆分成多少個(gè)task,然后分發(fā)到多少個(gè)work去
一個(gè)coordinator可能同時(shí)又多個(gè)用戶在請(qǐng)求query,然后共享work的去執(zhí)行,這是一個(gè)共享的集群
coordinator和discovery server可以啟動(dòng)在一個(gè)節(jié)點(diǎn)一個(gè)進(jìn)程,也可以放在不同的node上,但是現(xiàn)在公司大部分都是放在一個(gè)節(jié)點(diǎn)上,一個(gè)launcher start會(huì)同時(shí)把上述兩個(gè)啟動(dòng)起來
對(duì)于presto的容錯(cuò),如果某個(gè)worker掛掉了,discovery server會(huì)發(fā)現(xiàn)并通知coordinator
但是對(duì)于一個(gè)query,是沒有容錯(cuò)的,一旦一個(gè)work掛了,那么整個(gè)qurey就是敗了
因?yàn)閷?duì)于presto,他的查詢時(shí)間是很短的,與其查詢這里做容錯(cuò)能力,不如重新執(zhí)行來的快來的簡單
對(duì)于coordinator和discovery server節(jié)點(diǎn)的單點(diǎn)故障,presto還沒有開始處理這個(gè)問題貌似