目錄
?一、概述
1.1Trino不是什么
1.2Trino是什么
二、Trino特點
三、Trino架構
3.1架構和服務節點
3.2Trino數據模型
四、Trino安裝部署
4.1配置JDK
4.2單機版(Coordinator和Worker同進程)
4.2.1啟動服務
4.2.2下載客戶端
五、配置HTTPS(coordinator)
5.1生成證書
5.2設置密碼
5.3配置 kerberos認證
六、新增Worker
七、Hive連接器
7.1無kerberos的hive
7.2帶kerberos的hive
7.3 訪問hivecatalog異常
一、概述
Presto是Facebook開源的MPP(Massively Parallel Processing:大規模并行處理)架構的OLAP(on-line transaction processing:聯機分析處理),完全基于內存的并?計算,可針對不同數據源,執行大容量數據集的一款分布式SQL交互式查詢引擎。 它是為了解決Hive的MapReduce模型太慢以及不能通過BI或Dashboards直接展現HDFS數據等問題。
但是Presto目前有兩大分支:PrestoDB(背靠Facebook)和PrestoSQL現在改名為Trino(Presto的創始團隊),雖然PrestoDB背靠Facebook,但是社區活躍度和使用群體還是遠不如Trino。所以這里以Trino為主展開講解。
PrestoDB官方文檔:https://prestodb.io/docs/current/
Trino官方文檔:Trino documentation — Trino 476 Documentation
Trino 是一個運行速度極快的查詢引擎,專為大數據分析設計,支持快速分布式 SQL 查詢,幫助您探索數據宇宙。
1.1Trino不是什么
由于社區中的許多成員都將Trino稱為數據庫,因此首先定義一下Trino不是什么。不要誤以為Trino理解SQL就意味著它具備標準數據庫的功能。Trino不是通用關系型數據庫。它不是MySQL、PostgreSQL或Oracle等數據庫的替代品。Trino并非為處理在線事務處理(OLTP)而設計。對于許多其他為數據倉庫或分析而設計和優化的數據庫來說,也是如此。
1.2Trino是什么
Trino是一款旨在通過分布式高效查詢海量數據的工具。如果你處理的是TB級或PB級的數據,你很可能正在使用與Hadoop和HDFS交互的工具。Trino被設計為使用MapReduce作業管道查詢HDFS的工具(如Hive或Pig)的替代方案,但Trino并不局限于訪問HDFS。Trino可以并且已經被擴展,以操作不同類型的數據源,包括傳統的關系數據庫以及其他數據源,如Oracle。Trino旨在處理數據倉庫和分析:數據分析、聚合大量數據并生成報告。這些工作負載通常被歸類為聯機分析處理(OLAP)。
二、Trino特點
Trino是基于java開發的,對于大部分開發者和使用者而言,Trino容易學習并對特定的場景進行二次開發和性能優化等。多數據源、支持SQL、擴展性強、高性能,流水線模式。
- 多數據源:目前版本支持20多種數據源,幾乎能覆蓋所有常見情況,Elasticsearch 、Hive 、phoenix 、Kafka、Iceberg 、Local File、clickhouse 、MongoDB 、MySQL 、Redis等等;
- 支持SQL:完成支持ANSI SQL,提供SQL shell;
- 擴展性:支持開發自己的特定數據源的connector;
- 高性能:Trino基于內存計算,在絕大多數情況下,Trino的查詢性能是hive的10倍以上,完全能實現交互式,實時查詢;
- 流水線:Trino是基于PipeLine設計的,在進行大量設計處理過程中,終端不需要等待所有的數據計算完畢之后才能看到結果,計算一部分就可以看部分結果。
三、Trino架構
3.1架構和服務節點
- Trino查詢引擎是一個Master-Slave的架構,有兩種進程
Coordinator
服務進程和worker
服務進程組成。細分的話還有一個Discovery Server
節點,Discovery Server通常內嵌于Coordinator節點中。 Coordinator
主要作用是接收查詢請求,解析查詢語句,生成查詢執行計劃,任務調度和worker管理。Worker
服務進程執行被分解的查詢執行任務:taskWorker
節點啟動完成后向Discovery Server
服務注冊,Coordinator
從Discovery Server
獲得可以正常工作的Worker節點。- 如果配置了Hive Connector,需要配置一個Hive MetaStore服務為Trino提供Hive元信息,Worker節點與HDFS交互讀取數據。
3.2Trino數據模型
Trino就是通過Connector來訪問不同的數據源的,相當于訪問不同數據源的驅動程序,每種connector都實現了Trino的標準SPI接口,因此只要實現了標準SPI接口就可以制定特殊的Connector來訪問數據源。
Trino采取三層表結構:
- Catalog
Trino中Catalog類似于mysql中的一個數據庫實例,Schema類似于mysql當中的一個database。如用Trino去連接一個hive中的一個庫
- Schema
Trino中的schema就相當于mysql中的一個具體的database。
- Table
Trino中的table和mysql中table含義一樣
trino --server ip:port --catalog hive --schema xxx 這樣就可以訪問hive的中的xxx庫。
四、Trino安裝部署
官方安裝文檔:Deploying Trino — Trino 476 Documentation
4.1配置JDK
將JDK放在trino目錄下面 ,我直接 修改了launcher啟動腳本
4.2單機版(Coordinator和Worker同進程)
下載 trino
https://repo1.maven.org/maven2/io/trino/trino-server/367/
# 解壓后的路徑
/opt/trino-367# 創建配置目錄
mkdir etc data
etc目錄下的配置文件
Config properties
cat << EOF > etc/config.properties
# 設置該節點為coordinator節點
coordinator=true
# 指定HTTP服務器的端口。Trino使用HTTP進行內部和外部web的所有通信。
http-server.http.port=8086
# 查詢可以在任何一臺機器上使用的最大用戶內存。【注意】也是不能配置超過jvm配置的最大堆棧內存大小
query.max-memory-per-node=2GB
# 查詢可以使用的最大分布式內存。【注意】不能配置超過jvm配置的最大堆棧內存大小
query.max-memory=4GB
# hdp-node3也可以是IP
discovery.uri=http://hdp-node3:8086
# 允許在協調器上調度工作,也就是coordinator節點又充當worker節點用
node-scheduler.include-coordinator=true
EOF
node properties
cat << EOF > etc/node.properties
# 環境的名字。集群中所有的Trino節點必須具有相同的環境名稱。
node.environment=production
# 此Trino安裝的唯一標識符。這對于每個節點都必須是唯一的。可以填寫md5值
node.id=trino-worker
# 數據目錄的位置(文件系統路徑)。Trino在這里存儲日志和其他數據。
node.data-dir=/opt/trino-367/data
EOF
Log properties
cat << EOF > etc/log.properties
# 設置日志級別,有四個級別:DEBUG, INFO, WARN and ERROR
io.trino=INFO
EOF
JVM config
cat << EOF > etc/jvm.config
-server
-Xmx6G
-XX:-UseBiasedLocking
-XX:G1HeapRegionSize=32M
-XX:+ExplicitGCInvokesConcurrent
-XX:+ExitOnOutOfMemoryError
-XX:+HeapDumpOnOutOfMemoryError
-XX:-OmitStackTraceInFastThrow
-XX:ReservedCodeCacheSize=512M
-XX:PerMethodRecompilationCutoff=10000
-XX:PerBytecodeRecompilationCutoff=10000
-Djdk.attach.allowAttachSelf=true
-Djdk.nio.maxCachedBufferSize=2000000
-XX:+UnlockDiagnosticVMOptions
-XX:+UseAESCTRIntrinsics
EOF
4.2.1啟動服務
cd /opt/trino-367
./bin/launcher start
4.2.2下載客戶端
下載客戶端
cd /opt/trino-367
wget https://repo1.maven.org/maven2/io/trino/trino-cli/367/trino-cli-367.jar
mv trino-cli-367.jar trino-cli.jar
chmod +x trino-cli.jar# 連接測試
[root@hdp-node3 trino-367]# ./bin/trino-cli.jar --server hdp-node3:8086
trino> select * from hive.hive_test.employee_txn;
登錄web查看任務http://hdp-node3:8086/ui/login.html 賬號隨便/密碼為空
五、配置HTTPS(coordinator)
【注意】要使用trino的權限控制,從官方文檔上看,需要先開啟https,因此一定需要證書的。
5.1生成證書
cd /opt/trino-367
mkdir tls && cd tls
# 生成 CA 證書私鑰
openssl genrsa -out trino.key 4096
# 生成 CA 證書
openssl req -x509 -new -nodes -sha512 -days 3650 \-subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=mytrino.com" \-key trino.key \-out trino.cert# 合并
cat trino.key trino.cert > trino.pem
在etc/config.properties添加如下配置:
http-server.https.enabled=true
http-server.https.port=8443
http-server.https.keystore.path=/opt/trino-367/tls/trino.pem
# 節點之間不需要使用https通信,在內網部署無需,外網需打開,默認就是false
internal-communication.https.required=false
web UI:https://hdp-node3:8443/ ,賬號 :admin/123456
5.2設置密碼
【注意】要使用trino的權限控制,從官方文檔上看,需要開啟https,因此一定需要證書的。
# etc/config.properties增加如下配置:
http-server.authentication.type=PASSWORD
創建配置etc/password-authenticator.properties
,此處可以配置使用LDAP
或密碼文件
認證,這里測試我們先采用密碼文件
認證。
password-authenticator.name=file
file.password-file=/opt/trino-367/etc/password.db
etc/password.db內容如下:
admin:$2y$10$YG12RuoTiJjTzXFM.UgRy.AP.c2Me9KaKcYe6ufsy.ztpFRehnpE2
password.db用戶密碼文件,一行就是一個用戶名密碼,用戶密碼用 : 隔開,比如我定義了一個admin/123456的用戶。在使用bcrypt加密的時候,生成的密碼可能是$2a$開頭的,而根據trino文檔內定義的password規范是需要$2y$開頭的,這里需要注意。
在線Bcrypt密碼生成工具: 在線Bcrypt密碼生成工具-Bejson.com
重啟
客戶端訪問輸入密碼
./bin/trino-cli.jar --server https://hdp-node3:8443 --user=admin --password --insecure
5.3配置 kerberos認證
官方文檔:Kerberos authentication — Trino 476 Documentation
【注意】使用Kerberos認證時,訪問Trino協調器必須通過TLS和HTTPS。
kadmin
addprinc -randkey trino@WINNER.COM
addprinc -randkey trino/hdp-node3@WINNER.COM
ktadd -k /etc/security/keytabs/trino.service.keytab trino@WINNER.COM
ktadd -k /etc/security/keytabs/trino.service.keytab trino/hdp-node3@WINNER.COM
config.properties 完整配置如下:
# 設置該節點為coordinator節點
coordinator=true
# 指定HTTP服務器的端口。Trino使用HTTP進行內部和外部web的所有通信。
http-server.http.port=8086
# 查詢可以在任何一臺機器上使用的最大用戶內存。【注意】也是不能配置超過jvm配置的最大堆棧內存大小
query.max-memory-per-node=2GB
# 查詢可以使用的最大分布式內存。【注意】不能配置超過jvm配置的最大堆棧內存大小
query.max-memory=4GB
# hdp-node3也可以是IP
discovery.uri=http://hdp-node3:8086
# 允許在協調器上調度工作,也就是coordinator節點又充當worker節點用
node-scheduler.include-coordinator=true
http-server.https.enabled=true
http-server.https.port=8443
http-server.https.keystore.path=/opt/trino-367/tls/trino.keystore
http-server.https.keystore.key=password
internal-communication.shared-secret=password
http-server.process-forwarded=true#Kerberos 通常對 DNS 名稱敏感。 將此屬性設置為使用 FQDN 可確保正確操作和使用有效的 DNS 主機名。
node.internal-address-source=FQDN
# 多種認證方式用逗號分割
http-server.authentication.type=KERBEROS,PASSWORD
http-server.authentication.krb5.service-name=trino
http-server.authentication.krb5.principal-hostname=hdp-node3
http-server.authentication.krb5.keytab=/etc/security/keytabs/trino.service.keytab
http.authentication.krb5.config=/etc/krb5.conf
http-server.https.secure-random-algorithm=SHA1PRNG
六、新增Worker
直接將trino-367 包拷貝到另一臺服務器上,修改如下配置
node.properties
[root@hdp-node2 trino-367]# cat etc/node.properties
# 環境的名字。集群中所有的Trino節點必須具有相同的環境名稱。
node.environment=production
# 此Trino安裝的唯一標識符。這對于每個節點都必須是唯一的。可以填寫md5值 -- 修改
node.id=trino-worker02
# 數據目錄的位置(文件系統路徑)。Trino在這里存儲日志和其他數據。
node.data-dir=/opt/trino-367/data
config.properties
# 設置為false -- 修改
coordinator=false
# 指定HTTP服務器的端口。Trino使用HTTP進行內部和外部web的所有通信。
http-server.http.port=8086
# 查詢可以在任何一臺機器上使用的最大用戶內存。【注意】也是不能配置超過jvm配置的最大堆棧內存大小
query.max-memory-per-node=2GB
# 查詢可以使用的最大分布式內存。【注意】不能配置超過jvm配置的最大堆棧內存大小
query.max-memory=4GB
# hdp-node3也可以是IP
discovery.uri=http://hdp-node3:8086
# 允許在協調器上調度工作,也就是coordinator節點又充當worker節點用
node-scheduler.include-coordinator=true
http-server.https.enabled=true
http-server.https.port=8443
http-server.https.keystore.path=/opt/trino-367/tls/trino.keystore
http-server.https.keystore.key=password
internal-communication.shared-secret=password
http-server.process-forwarded=true#Kerberos 通常對 DNS 名稱敏感。 將此屬性設置為使用 FQDN 可確保正確操作和使用有效的 DNS 主機名。
node.internal-address-source=FQDNhttp-server.authentication.type=KERBEROS,PASSWORD
http-server.authentication.krb5.service-name=trino
http-server.authentication.krb5.principal-hostname=hdp-node3
http-server.authentication.krb5.keytab=/etc/security/keytabs/trino.service.keytab
http.authentication.krb5.config=/etc/krb5.conf
http-server.https.secure-random-algorithm=SHA1PRNG
查表驗證
./bin/trino-cli.jar \
--server https://hdp-node3:8443 \
--krb5-config-path /etc/krb5.conf \
--krb5-principal trino/hdp-node3@WINNER.COM \
--krb5-keytab-path /etc/security/keytabs/trino.service.keytab \
--krb5-remote-service-name trino \
--keystore-path /opt/trino-367/tls/trino.keystore \
--keystore-password password \
--user trino/hdp-node3@WINNER.COM \
--execute "select * from system.runtime.nodes;" --output-format=TSV_HEADER
七、Hive連接器
連接器其實就是指定某種數據源,如下給出hive連接器示例。
7.1無kerberos的hive
[root@hdp-node3 trino-367]# cat etc/catalog/hive.properties
connector.name=hive
hive.metastore.uri=thrift://192.168.2.100:9083
hive.config.resources=/opt/datasophon/core-site.xml,/opt/datasophon/hdfs-site.xml
7.2帶kerberos的hive
【注意】使用Kerberos認證時,訪問Trino協調器必須通過TLS和HTTPS。
# 生成新的密鑰庫,包含 hdp-node3 作為主機名
keytool -genkeypair \-alias trino \-keyalg RSA \-keysize 2048 \-validity 3650 \-keystore /opt/trino-367/tls/trino.keystore \-storepass password \-keypass password \-dname "CN=hdp-node3, OU=Trino, O=Example, L=Beijing, ST=Beijing, C=CN" \-ext "SAN=dns:hdp-node3,dns:localhost,ip:127.0.0.1"
config.properties
# 設置該節點為coordinator節點
coordinator=true
# 指定HTTP服務器的端口。Trino使用HTTP進行內部和外部web的所有通信。
http-server.http.port=8086
# 查詢可以在任何一臺機器上使用的最大用戶內存。【注意】也是不能配置超過jvm配置的最大堆棧內存大小
query.max-memory-per-node=2GB
# 查詢可以使用的最大分布式內存。【注意】不能配置超過jvm配置的最大堆棧內存大小
query.max-memory=4GB
# hdp-node3也可以是IP
discovery.uri=http://hdp-node3:8086
# 允許在協調器上調度工作,也就是coordinator節點又充當worker節點用
node-scheduler.include-coordinator=true
http-server.https.enabled=true
http-server.https.port=8443
http-server.https.keystore.path=/opt/trino-367/tls/trino.keystore
http-server.https.keystore.key=password
internal-communication.shared-secret=password
http-server.process-forwarded=true#Kerberos 通常對 DNS 名稱敏感。 將此屬性設置為使用 FQDN 可確保正確操作和使用有效的 DNS 主機名。
node.internal-address-source=FQDNhttp-server.authentication.type=KERBEROS,PASSWORD
http-server.authentication.krb5.service-name=trino
http-server.authentication.krb5.principal-hostname=hdp-node3
http-server.authentication.krb5.keytab=/etc/security/keytabs/trino.service.keytab
http.authentication.krb5.config=/etc/krb5.conf
http-server.https.secure-random-algorithm=SHA1PRNG
jvm.config
-server
-Xmx8G
-XX:-UseBiasedLocking
-XX:G1HeapRegionSize=32M
-XX:+ExplicitGCInvokesConcurrent
-XX:+ExitOnOutOfMemoryError
-XX:+HeapDumpOnOutOfMemoryError
-XX:-OmitStackTraceInFastThrow
-XX:ReservedCodeCacheSize=512M
-XX:PerMethodRecompilationCutoff=10000
-XX:PerBytecodeRecompilationCutoff=10000
-Djdk.attach.allowAttachSelf=true
-Djdk.nio.maxCachedBufferSize=2000000
-XX:+UnlockDiagnosticVMOptions
-XX:+UseAESCTRIntrinsics
-Dsun.security.krb5.debug=true
-Djava.security.krb5.conf=/etc/krb5.conf
hive catalog
[root@hdp-node3 trino-367]# cat etc/catalog/hive.properties
connector.name=hive
hive.metastore.uri=thrift://hdp-node2:9083
hive.metastore.authentication.type=KERBEROS
hive.metastore.service.principal=hive/_HOST@WINNER.COM;
hive.metastore.client.principal=trino/hdp-node3@WINNER.COM
hive.metastore.client.keytab=/etc/security/keytabs/trino.service.keytab
hive.hdfs.authentication.type=KERBEROS
hive.hdfs.trino.principal=trino/hdp-node3@WINNER.COM
hive.hdfs.trino.keytab=/etc/security/keytabs/trino.service.keytab
hive.config.resources=/etc/hadoop/conf/core-site.xml,/etc/hadoop/conf/hdfs-site.xml
hive.hdfs.impersonation.enabled=true
# 是否開啟向Hive的外部表寫入數據,默認是False
hive.non-managed-table-writes-enabled=true
客戶端訪問
./bin/trino-cli-367-executable.jar \
--server https://hdp-node3:8443 \
--krb5-config-path /etc/krb5.conf \
--krb5-principal trino/hdp-node3@WINNER.COM \
--krb5-keytab-path /etc/security/keytabs/trino.service.keytab \
--krb5-remote-service-name trino \
--keystore-path /opt/trino-367/tls/trino.keystore \
--keystore-password password \
--user trino/hdp-node3@WINNER.COM \
--catalog hive
執行查詢
7.3 訪問hivecatalog異常
2025-08-11T13:34:06.371+0800 ERROR SplitRunner-0-92 io.trino.execution.executor.TaskExecutor Error processing Split 20250811_053355_00000_97364.2.0.0-0 io.trino.connector.informationschema.InformationSchemaSplit@35e48236 (start = 1.6171929350256409E10, wall = 9739 ms, cpu = 0 ms, wait = 2 ms, calls = 1)
com.google.common.util.concurrent.UncheckedExecutionException: java.lang.RuntimeException: javax.security.auth.login.LoginException: Message stream modified (41)at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2055)at com.google.common.cache.LocalCache.get(LocalCache.java:3966)at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3989)at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4950)at com.google.common.cache.LocalCache$LocalLoadingCache.getUnchecked(LocalCache.java:4956)at io.trino.plugin.hive.metastore.cache.CachingHiveMetastore.get(CachingHiveMetastore.java:261)at io.trino.plugin.hive.metastore.cache.CachingHiveMetastore.getAllDatabases(CachingHiveMetastore.java:295)at io.trino.plugin.hive.HiveMetastoreClosure.getAllDatabases(HiveMetastoreClosure.java:66)at io.trino.plugin.hive.metastore.SemiTransactionalHiveMetastore.getAllDatabases(SemiTransactionalHiveMetastore.java:197)at io.trino.plugin.hive.HiveMetadata.listSchemaNames(HiveMetadata.java:416)at io.trino.plugin.base.classloader.ClassLoaderSafeConnectorMetadata.listSchemaNames(ClassLoaderSafeConnectorMetadata.java:205)at io.trino.metadata.MetadataManager.listSchemaNames(MetadataManager.java:293)at io.trino.metadata.MetadataListing.listSchemas(MetadataListing.java:100)at io.trino.metadata.MetadataListing.listSchemas(MetadataListing.java:95)at io.trino.connector.informationschema.InformationSchemaPageSource.addSchemataRecords(InformationSchemaPageSource.java:316)at io.trino.connector.informationschema.InformationSchemaPageSource.buildPages(InformationSchemaPageSource.java:225)at io.trino.connector.informationschema.InformationSchemaPageSource.getNextPage(InformationSchemaPageSource.java:183)at io.trino.operator.TableScanOperator.getOutput(TableScanOperator.java:311)at io.trino.operator.Driver.processInternal(Driver.java:388)at io.trino.operator.Driver.lambda$processFor$9(Driver.java:292)at io.trino.operator.Driver.tryWithLock(Driver.java:685)at io.trino.operator.Driver.processFor(Driver.java:285)at io.trino.execution.SqlTaskExecution$DriverSplitRunner.processFor(SqlTaskExecution.java:1076)at io.trino.execution.executor.PrioritizedSplitRunner.process(PrioritizedSplitRunner.java:163)at io.trino.execution.executor.TaskExecutor$TaskRunner.run(TaskExecutor.java:488)at io.trino.$gen.Trino_367____20250811_053005_2.run(Unknown Source)at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.RuntimeException: javax.security.auth.login.LoginException: Message stream modified (41)
修改了 krb5.cof
vim /etc/ krb5.conf刪除 krb5.conf 配置文件里的 renew_lifetime = xxx 這行配置即可
參考文章
javax.security.auth.login.LoginException: Message stream modified (41)-CSDN博客
Kerberos authentication — Trino 476 Documentation
大數據Hadoop之——基于內存型SQL查詢引擎Presto(Presto-Trino環境部署) - 大數據老司機 - 博客園
【大數據】通過 docker-compose 快速部署 Presto(Trino)保姆級教程 - 大數據老司機 - 博客園
【大數據】Presto(Trino)SQL 語法進階 - 大數據老司機 - 博客園
presto(trino)+kerberos+https - mzjnumber1 - 博客園
Presto/Trino的Hive Connector的使用(內部表、外部表、分區表):
Presto/Trino的Hive Connector的使用(內部表、外部表、分區表)_presto分區表-CSDN博客
HDFS file system support — Trino 476 Documentation
trino 安裝(帶web ui 與 coordinator 和 worker 與 coordinator 安全通訊)_trino webui-CSDN博客