Presto 0.271 Documentation
presto 原有團隊重立了 presto 項目並改名為 prestosql,后來又改名為 Trino,這個版本不支持 Java 8,以及 Java 11 的低級版本,但擁有更活躍的社區和更多的貢獻者。
概覽
presto 不是一個關系型數據庫,不能代替MySQL,PostgreSQL 或者 Oracle,它不是用來處理 OLTP。
presto 是一個能使用分布式查詢高效地查詢大規模數據的工具。它被設計為一個替代使用 MapReduce jobs 通道查詢 HDFS的工具,如 Hive 或者 Pig。但是它不限於訪問 HDFS。它可以並已經擴展操作不同的數據源,包括傳統的關系型數據庫和其他數據源比如 Cassandra。
Presto 旨在處理數據倉庫和分析:數據分析、聚合大量數據並生成報告,這些工作通常被歸為在線分析處理(OLAP)
概念
需要理解下面這些名詞和概念。作為用戶端,應該需要熟悉注入 stage 和 split 的概念來充分使用 presto 高效地查詢。作為 presto 管理員 或者貢獻者,需要理解 presto stage 的概念如何映射到 task 並且 task 包含一組驅動以處理數據。
本節,提供一些 presto 引用的核心概念的可靠定義,本節從最一般到最具體進行排序。
server type
服務器類型:coordinator、worker
coordinator
presto coordinator 是一個負責解析語句,計划查詢,管理 worker 節點的服務器。作為 presto 的大腦,它同時也是與客戶端通信以提交語句來執行的節點。每個 presto 安裝必須有一個 coordinator 和 一個或多個 worker。對於開發和測試的目的,可以配置單個 presto 實例承擔這兩個角色。
coordinator 保持跟蹤每一個worker 的活動,並且協調查詢的執行。coordinator 創建一個查詢的邏輯模型,這個模型涉及的一系列 stage 被翻譯成一系列連接的 task 運行在集群中的 worker 上。
coordinator 使用 REST API 與 worker 通信。
worker
Presto worker 是一個負責執行 task 並處理數據的服務器。worker 節點從連接器獲取數據,並相互交換數據。coordinator 負責從worker獲取結果並返回給最終結果為客戶端。
當 presto worker 處理啟動,它將自己介紹給 coordinator 的發現服務器,這使得 presto coordinator 可以使用 worker 做 task 執行。
worker 使用 REST API 與 coordinator 和其他 worker 通信。
Data Source
通過這篇文檔,你將閱讀到諸如 connector, catalog, schema, and table 的名詞。這些基本概念覆蓋了指定數據源 presto 模型,在下面的章節描述。
Connector
連接器適配 presto 到數據源如 Hive 和 關系型數據庫。你可以將連接器和數據庫的驅動是一樣的。這是一種 prseto 的 SPI 的實現,允許 presto 使用標准 API 與數據源交互。
presto 包含幾個內置的連接器:JMX 連接器,System 連接器提供訪問系統內置表,Hive 連接器和 TPCH 連接器用來服務於 TPC-H benchmark 數據。很多第三方開發者已經貢獻了連接器,prseto 可以訪問各種數據源。
每個目錄都與特定的連接器相關聯。每個 catalog 配置文件包含一個必填屬性 connector.name
被 catalog 管理器用來為一個給定的 catalog 創建連接器。可以有多個 catalog 使用同一個 connector 訪問相似數據庫的兩個不同的實例。例如,你有兩個 Hive 集群,你可以在一個 presto 集群配置兩個 catalog 都是用 Hive connector,允許你從兩個Hive 集群查詢,甚至在同一個 SQL 中。
Catalog
presto catalog 包含 schema 並通過 connector 引用數據源。例如,可以配置 JMX catalog 經由 JMX connector 提供訪問 JMX 信息。當你在 presto 運行一個 SQL 語句時,你針對一個或多個 catalog 運行它。
當在 presto 定位一張表時,全限定表名需要配置在 catalog 中。例如一個全限定表名 hive.test_data.test
會引用 在 hive
catalog 下的 test_data
schema 的 test
表。
在存儲在配置文件目錄下的配置文件中定義 catalog 。
Schema
schema 是組織表的一種方式。catalog 與 schema 一起定義表的集合,以被查詢。當在 presto 訪問 Hive 或者關系型數據庫時,比如 MySQL,schema 轉譯成為在目標數據庫的相同概念。其他類型的 connector 可能選擇以對下游數據源有意義的方式組織表到 schema 。
Table
Query Execution Model
presto 執行 SQL 語句並將這些語句轉換為在 coordinator 和 worker 的分布式集群上執行的語句。
Statement
presto 執行 兼容ANSI 的SQL 語句。當 presto 文檔提及 statement 時,它指的是由子句,表達式,謂詞組成的定義在 ANSI SQL 標准的語句。
一些讀者可能會好奇為什么這節列舉了語句和查詢不同概念。這是必要的,因為在 presto, statement 只是指 SQL 語句的文本表示。 執行語句時,Presto 會創建一個查詢以及一個查詢計划,該計划隨后分布在一系列 Presto worker 中。
Query
當 presto 解析一條語句,它將其轉換為一條查詢並創建分布式查詢計划,然后實現為一系列內連接的 stage 運行在 presto workder中。當你在 presto 獲取關於一條查詢的信息時,你接收到一個每個件的快照,這些組件涉及生成響應語句的結果集。
語句和查詢的區別很簡單。一個語句可以認為是 SQL 文本,傳遞給 Presto,然而查詢指向配置和組件具體執行那條語句。查詢包含 stages, tasks, splits, connectors, 和其他 components,和數據源在?生成結果。
Stage
當 presto 執行查詢時,它將執行拆分為一個層級結構的 stage 來執行它。例如,如果presto 需要聚合在 Hive 的十億行數據,它創建一個根 stage 來聚合其他幾個 stage 的輸出,這些 stage 被設計為實現分布式查詢計划的不同部分。
包含查詢的 stage 的層級結構類似於一棵樹。每個查詢有一個根 stage 負責聚合其他 stage 的輸出。stage 是 coordinator 用來模型化一個分布式查詢計划,但是 stage 本身不運行在 presto worker。
Task
stage 對分布式查詢計划的一個特定部分進行建模,但 stage 本身不運行在 presto worker。為了理解 stage 如何執行,你需要理解 stage 被實現為一系列分布在 worker 網絡上的 task。
task 是 Presto 架構中的“工作馬”,因為分布式查詢計划被解構為一系列 stage,然后將這些 stage 轉換為 task,然后執行或處理拆分。 Presto task 有輸入和輸出,就像一個階段可以由一系列任務並行執行一樣,一個任務與一系列驅動程序並行執行。
Split
task 操作 split,大數據集的部分。分布式查詢計划中最低級的的 stage 從 connector 的分片中獲取數據,分布式查詢計划中中間的 stage 從其他 stage 中獲取數據。
當 presto 調度查詢時,coordinator 會查詢 connector 得到所有表可用的分片的列表。coordinator 跟蹤哪個機器正在運行,哪個 task 和 什么 split 正在被處理。
Driver
task 包括一個或多個並行的 driver。driver 操作數據並結合操作符生產輸出,然后由 task 聚合傳輸到其他的 stage 的 task 。driver 時一系列操作符實例,或者你可以認為driver 是一個內存中操作符的物理集合。這是在presto 結構中最低級的並行。driver由一個輸入和一個輸出。
Operator
operator 消費,轉換並生產數據。例如,表掃描從 connector 獲取數據並生產可以被其他算子消費的數據,和過濾算子通過應用謂詞到輸入數據來消費數據並生產子集
Exchange
exchange 在 presto 節點間傳輸數據給查詢的不同 stage。task 生產數據到輸出緩沖區,並使用 exchange 客戶端從其他 task 消費數據。
安裝
部署
安裝
下載 Presto 服務器tar包並解壓。里面包括一個最高級目錄,稱為安裝目錄。Presto 需要一個數據目錄來存儲日志等。建議創建一個數據目錄在安裝目錄之外,這樣可以在更新的時候方便地保留。
配置
在安裝目錄中創建 etc
目錄。里面包含以下配置文件
- Node Properties:環境配置指定每個節點
- JVM Config:操作Java 虛擬機的命令行選項
- Config Properties:Presto 服務器的配置
- Catalog Properties: 數據源適配器的配置。
Node Properties
etc/node.properties
包含每個節點的配置。一個 節點 是一個在機器上安裝了 Presto 的實例。該文件通常由在 Presto 第一次安裝時由部署系統創建的。下面時一個最小化的配置。
node.environment=production
node.id=ffffffff-ffff-ffff-ffff-ffffffffffff
node.data-dir=/var/presto/data
node.environment
: 環境名稱。在同一個集群的所有 Presto 節點需要有相同的名稱。node.id
: 唯一標識。對於每個節必須是唯一的。此標識符應在 Presto 重新啟動或升級期間保持一致。如果在一台機器上運行多個 Presto 安裝(即同一台機器上的多個節點),每個安裝必須有一個唯一標識符。node.data-dir
: 數據目錄的位置(文件系統路徑)。Presto 將在此處存儲日志和其他數據。
JVM Config
jvm.config
coordinator:
coordinator=true
node-scheduler.include-coordinator=false
http-server.http.port=8080
query.max-memory=50GB
query.max-memory-per-node=1GB
query.max-total-memory-per-node=2GB
discovery-server.enabled=true
discovery.uri=http://node1:8080
workers:
coordinator=false
http-server.http.port=8080
query.max-memory=50GB
query.max-memory-per-node=1GB
query.max-total-memory-per-node=2GB
discovery.uri=http://node1:8080
如果 coordinator 和 workers 在同一個機器上做測試:
coordinator=true
node-scheduler.include-coordinator=true
http-server.http.port=8080
query.max-memory=5GB
query.max-memory-per-node=1GB
query.max-total-memory-per-node=2GB
discovery-server.enabled=true
discovery.uri=http://node1:8080
coordinator
: 允許 presto 實例作為 coordinator 接收客戶端的查詢並管理查詢的執行。node-scheduler.include-coordinator
: 允許在 coordinator 上調度任務。對於大集群,在 coordinator 上處理任務會影響查詢性能,因為機器資源對調度,管理,監控查詢執行的關鍵任務不可用。http-server.http.port
: 指定 HTTP 服務的端口。presto 使用 http 進行內部和外部通信。query.max-memory
: 一個查詢可以使用的分布式內存最大值。query.max-memory-per-node
: 一台機器上一個查詢使用的用戶內存最大值。query.max-total-memory-per-node
: 一台機器上一個查詢使用的用戶和系統內存最大值。系統內存是在由 reader,writer,網絡緩沖等,在執行過程中使用的內存。discovery-server.enabled
: presto 使用發現服務找到集群中的所有節點。每個 presto 實例會在啟動時向發現服務注冊。為了簡化部署,避免運行額外的服務,presto coordinator 可以運行一個發現服務的內置版本。這個服務會與 presto 共享http 服務器,因此會使用相同端口。discovery.uri
: 發現服務器的 URI。因為我們在 presto coordinator 啟動了發現服務的內嵌版本,這應該為 presto coordinator 的 URI。替換example.net:8080
來適配 presto coordinator 的 host 和 port。URI 不能以斜杠結尾。
Properties Reference 參考通用配置
Config Properties
config.properties
coordinator=true
node-scheduler.include-coordinator=true
http-server.http.port=8080
query.max-memory=5GB
query.max-memory-per-node=1GB
query.max-total-memory-per-node=2GB
discovery-server.enabled=true
discovery.uri=http://node1:8080
Log Levels
log.properties
com.facebook.presto=INFO
Node Properties
node.environment=production
node.id=ffffffff-ffff-ffff-ffff-ffffffffffff
node.data-dir=/yg/install/presto-server-0.271/data
Catalog Properties
etc/catalog/
presto 通過 掛載到 catalog 的 connector 訪問數據。connector 在 catalog 提供所有 schema 和 table 。例如,Hive connector 映射每個數據庫到 schema
命令行客戶端
presto cli 提供一個基於終端的交互式 shell 來運行查詢。這個客戶端時自執行的 jar 文件,意思是它像一個普通 UNIX 可執行。
下載 presto-cli-0.271-executable.jar ,重命名為 presto,讓它擁有可執行權限,然后運行
./presto --server localhost:8080 --catalog hive --schema default
運行 --help 查看可用選項
示例
-
安裝好 MySQL 並關閉防火牆,打開用戶遠程登錄權限
-
presto-server/etc/catalog 下編寫配置文件 mysql.properties
connector.name=mysql
connection-url=jdbc:mysql://192.168.40.2:3306?
connection-user=root
connection-password=123456
- 啟動 presto server(coordinator、worker)
bin/launcher run //前台運行,打印日志
bin/launcher start //后台運行
bin/launcher stop //停止
- 啟動 presto-cli-0.271-executable.jar 下載之后改名為 presto,並添加執行權限
./presto --server localhost:8080 --catalog mysql --schema default
- 執行 SQL 語句
show schemas from mysql;
select count(1),job from toys.bank_additional_full3 group by job;
- 在 UI 界面查看集群狀態和 SQL 執行情況。
http://node1:8080
溢出到磁盤
內存管理和溢出
默認情況下,presto 會殺掉那些請求的內存超出配置限制的查詢。()query_max_memory
or query_max_memory_per_node
)。這個機制保證了內存分配給查詢的公平性和避免由內存分配造成的死鎖。這在集群中有很多小查詢時很高效,但是會殺掉超出限制的大查詢。
為了克服這種低效率,這里引入 可撤銷內存 的概念。查詢可以請求不計入限制的內存,但是可以倍內存管理器隨時撤銷。當內存被撤銷時,查詢運行器將中間數據從內存溢出到磁盤,一遍稍后處理它。
實際上,當集群空閑,並且所有內存可用,內存緊張的查詢可以使用集群中所有的內存。另一方面,當集群沒有太多空閑內存時,一些查詢會被強制使用磁盤存儲中間數據。被溢出到磁盤的查詢的執行時間可能要長幾個數量級,相比完全在內存中運行的查詢。
請注意,啟用溢出到磁盤不保證所有內存緊張的查詢執行。有一些內存緊張的操作不支持溢出。查詢運行器有可能無法將中間數據到划分成足夠小的能夠適合內存的 chunk ,進而從磁盤加載數據時導致OOM錯誤。
函數和操作符
比較操作符
操作符 | 說明 |
---|---|
< | |
> | |
<= | |
>= | |
= | |
<> | |
!= | 非標准,但是支持 |
Range Operator: BETWEEN
SELECT 3 BETWEEN 2 AND 6;
SELECT 3 >= 2 AND 3 <= 6;
SELECT 3 NOT BETWEEN 2 AND 6;
SELECT 3 < 2 OR 3 > 6;
SELECT NULL BETWEEN 2 AND 4; -- null 任何涉及 NULL 的比較都會返回 NULL
SELECT 2 BETWEEN NULL AND 6; -- null
SELECT 'Paul' BETWEEN 'John' AND 'Ringo'; -- true
IS NULL and IS NOT NULL
select NULL IS NULL; -- true
SELECT 3.0 IS NULL; -- false
IS DISTINCT FROM and IS NOT DISTINCT FROM
因為涉及到 NULL 的比較會返回 NULL, 因此這兩個操作符將 NULL 視為已知值, 總是會返回 True False
SELECT NULL IS DISTINCT FROM NULL; -- false
SELECT NULL IS NOT DISTINCT FROM NULL; -- true
GREATEST and LEAST
非 SQL 標准, 但是是常見的擴展。若其中一個參數為 NULL 則返回 NULL, 支持下面的格式:
-
DOUBLE
-
BIGINT
-
VARCHAR
-
TIMESTAMP
-
TIMESTAMP WITH TIME ZONE
-
DATE
greatest(value1, value2, ..., valueN) 返回提供的最大的值
Quantified Comparison Predicates: ALL, ANY and SOME
ALL , ANY , SOME 可以和比較操作符一起用
expression operator quantifier ( subquery )
SELECT 'hello' = ANY (VALUES 'hello', 'world'); -- true
SELECT 21 < ALL (VALUES 19, 20, 21); -- false
SELECT 42 >= SOME (SELECT 41 UNION ALL SELECT 42 UNION ALL SELECT 43); -- true
表達式 | 意義 |
---|---|
A = ALL (...) | 等於所有值 |
A <> ALL (...) | 不匹配所有值 |
A < ALL (...) | 比最小的小 |
A = ANY (...) | 等於任意一個值,等價於 A IN (...) |
A <> ANY (...) | 不匹配一個或多個值 |
A < ANY (...) | A 比最大的值小 |
ANY SOME 具有相同的意思, 可以互相使用。
LIKE
正則匹配
expression LIKE pattern [ ESCAPE 'escape_character' ]
[ ESCAPE 'escape_character' ] 代表轉義后面的字符
SELECT * FROM (VALUES ('a_c'), ('_cd'), ('cde')) AS t (name)
WHERE name LIKE '%#_%' ESCAPE '#'
--returns 'a_c' and '_cd'
條件表達式
CASE
標准SQL
IF
if
(condition, true_value)
COALESCE
coalesce
(value1, value2[, ...]) 返回第一個非 null 的值
NULLIF
nullif
(value1, value2)
TRY
try
(expression)
評估一個表達式,遇到指定的錯誤類型時返回 NULL
TRY 處理的錯誤:
- Division by zero
- Invalid cast argument or invalid function argument
- Numeric value out of range
例子
與 coalesce 結合使用:
SELECT COALESCE(TRY(total_cost / packages), 0) AS per_package FROM shipping;
轉換函數
-
cast
(value AS type) → type# -
try_cast
(value AS type) → type# 與cast 類似,但是失敗時返回 null 。 -
parse_presto_data_size
(string)#
SELECT parse_presto_data_size('1B'); -- 1
SELECT parse_presto_data_size('1kB'); -- 1024
SELECT parse_presto_data_size('1MB'); -- 1048576
SELECT parse_presto_data_size('2.3MB'); -- 2411724
typeof
(expr) → varchar#
SELECT typeof(123); -- integer
SELECT typeof('cat'); -- varchar(3)
SELECT typeof(cos(2) + 1.5); -- double
數學函數和操作符
未完...