PRESTO & TRINO
一、简介
1.起源
首先来简述一下Presto的发展起源,Presto其实是由FaceBook开源的一个MPP计算引擎,主要用来以解决 Facebook 海量 Hadoop 数据仓库的低延迟交互分析问题,Facebook版本的Presto更多的是以解决企业内部需求功能为主,也叫Presto DB,版本号以http://0.xxx来划分。后来,Presto其中的几个人出来创建了更通用的Presto分支,取名Presto SQL,版本号以xxx来划分,例如345版本,这个开源版本也是更为被大家通用的版本。前一段时间,为了更好的与Facebook的Presto进行区分,Presto SQL将名字改为Trino,除了名字改变了其他都没变。所以我们以后慢慢接受Trino这个引擎吧~(后面统一用Trino吧)
2.特点及原理
Trino这个查询引擎之前在大数据查询一章中讲到过,那时候还叫他Presto,这个查询引擎的特点正如文章标题描述的这样,多源、即席。多源就是它可以支持跨不同数据源的联邦查询,即席即实时计算,将要做的查询任务实时拉取到本地进行现场计算,然后返回计算结果。
- 架构图
整个Trino主要是由Client、Coordinator、Worker以及Connector来构成
-
Client
Client就是来接受客户端查询请求的
-
Coordinator
Coordinator来对接受到的查询进行词法、语法分析,然后进行任务和资源的调度
-
Worker
Worker来做具体的工作了,例如去数据源拉取数据,然后进行计算
-
Connector
那Connector就是Worker去数据源拉取数据的连接器(适配器/管道)
3.应用与意义
-
附图
上图能够非常形象等展示出Trino这种多源数据即席查询引擎的优点:
(1)屏蔽底层数据源,提供统一的查询接口:通过统一的SQL查询,你可以查询结构化的数据库(例如Oracle、MySql等)、非结构化数据库(Neo4j、MongoDB)、Hive/HDFS、Kafka以及Terradata、GreemPlum等等;
(2)提高效率:一方面,基于内存计算,查询速度快是其一个特点;另一方面,由于它可以跨不同的数据源拉取数据并进行连接、聚合等操作,这也减少了数据搬家、数据迁移等步骤,从整个的计算逻辑上来看也是大大加快了;
(3)提高数据治理能力:在大数据时代,提高数据治理能力、发挥数据价值是重中之重,通过Trino可以很方便的进行异构数据的提取、整合与分析,对于打破数据孤岛、提高数据治理能力至关重要。
二、安装
1. 单节点安装-tar.gz
- 环境要求
组件 | 版本 |
---|---|
Linux | 64位 |
Java | 11 |
python | 2.6.x 、2.7.x或3.x版本 |
-
详细配置
https://trino.io/docs/current/installation/deployment.html
-
安装
#下载压缩包
curl -o ~/trino-server-354.tar.gz https://repo1.maven.org/maven2/io/trino/trino-server/354/trino-server-354.tar.gz
#解压
tar xf ~/trino-server-354.tar.gz
#自行安装jdk 与python 环境
# 切换trino主目录
cd trino-server-354
#准备相关配置
tree etc
etc
├── catalog
│ └── jmx.properties
├── config.properties
├── jvm.config
├── log.properties
└── node.properties
#启动测试
./bin/launcher run
-
查看
TODO
2. docker安装
#拉取镜像
docker pull trinodb/trino:latest
#测试运行
docker run -p 8080:8080 trinodb/trino
#执行运行
docker exec -it a901420d43c4 trino
trino> show catalogs
-> ;
Catalog
---------
jmx
memory
system
tpcds
tpch
(5 rows)
3.集群安装
参见 https://trino.io/docs/current/installation/deployment.html
三、简单使用
1.连接器
序号 | 链接器 | 说明 |
---|---|---|
1 | Accumulo Connector | |
2 | BigQuery Connector | |
3 | Black Hole Connector | |
4 | Cassandra Connector | |
5 | ClickHouse connector | |
6 | Delta Lake Connector | |
7 | Druid Connector | |
8 | Elasticsearch Connector | |
9 | Hive Connector | |
10 | Hive Security Configuration | |
11 | Hudi connector | |
12 | Iceberg Connector | |
13 | JMX Connector | |
14 | Kafka Connector | |
15 | Kafka Connector Tutorial | |
16 | Kudu Connector | |
17 | Lark Sheets connector | |
18 | Local File Connector | |
19 | Memory Connector | |
20 | MongoDB Connector | |
21 | MySQL Connector | |
22 | Oracle Connector | |
23 | Apache Pinot Connector | |
24 | PostgreSQL Connector | |
25 | Prometheus Connector | |
26 | Redis Connector | |
27 | Redshift Connector | |
28 | SQL Server Connector | |
29 | System Connector | |
30 | Thrift Connector | |
31 | TPCDS Connector | |
32 | TPCH Connector |
2.快速配置使用 -mysql 为例
-
创建配置
vi mysql.properties
connector.name=mysql connection-url=jdbc:mysql://192.168.11.229:3306 connection-user=root connection-password=123456
-
重启服务
docker restart a901420d43c4 && docker logs -f a901420d43c4
-
查看
docker exec -it a901420d43c4 trino trino> show catalogs; Catalog --------- jmx memory mysql system tpcds tpch trino> show SCHEMAS from mysql; Schema ------------------------ big-whale cels-zipkin certificate ctj ctj-test cup cup_boot cup_db cup_meta dap_auth data_cloud db-mcms-open dps_v5 ems_v6 esmcnts ewp_give_alarm_details …… trino> show tables from mysql.dap_auth; Table ---------------------- cup_attach cup_client cup_code cup_datasource cup_dept cup_dict cup_dict_biz cup_ds cup_ds_def cup_log_api cup_log_error cup_log_usual cup_menu cup_notice cup_oss ……
3. 分页测试
docker exec -it a901420d43c4 trino
# 分页查询
trino> select * from mysql.dap_auth.cup_user offset 1 limit 10;
trino> select * from mysql.dap_auth.cup_user offset 2 limit 10;
-
对比查询结果
- 查询结果 1
- 查询结果 2
-
更多参考官方说明
https://trino.io/docs/current/connector.html
四、源码编译
1.前置条件
环境 | 版本 | 备注 |
---|---|---|
system | Linux、windows、mac | |
java | jdk17 | jdk11 以上 |
maven | apache-maven-3.8.1 |
2.注意事项
-
Trino 参考博客 链接
-
关闭license 检查
<air.check.skip-spotbugs>true</air.check.skip-spotbugs> <air.check.skip-pmd>true</air.check.skip-pmd>
3.开始编译
-
clone 代码
git clone https://github.com/trinodb/trino.git
cd trino
-
maven 编辑打包
mvn clean install -DskipTests
-
启动测试
-
配置catalog
工程目录创建 etc/catalog
-
启动参数
main class: io.trino.server.DevelopmentServer vm options: -Dconfig=testing/trino-server-dev/etc/config.properties -Dlog.levels-file=testing/trino-server-dev/etc/log.properties -Djdk.attach.allowAttachSelf=true
-
启动日志
-
-
通过client 连接
#切到客户端工具 工程目录 cd client/trino-cli/target #执行jar --server 指定 ./trino-cli-411-SNAPSHOT-executable.jar --server http://localhost:8080 trino> show catalogs; Catalog --------- jmx system (2 rows)
五、插件实现
1.插件开发参考
2.样例插件实现
-
实现插件核心类
-
Plugin
-
Module
-
ConnectorFactory
-
ConnectorMetadata
-
ConnectorSplitManager
-
ConnectorRecordSetProvider
-
ConnectorTableHandle
-
ColumnHandle
-
ConnectorHandleResolver
-
ConnectorSplit
-
ConnectorSplitManager
-
ConnectorTableLayoutHandle
-
ConnectorTransactionHandle
-
RecordCursor
-
RecordSet
-
3.扩展插入数据
-
Connector
- getPageSinkProvider() 插入数据需要
-
ConnectorPageSinkProvider
- createPageSink
-
ConnectorMetadata
- createTable() 创建表
- dropTable() 删除表
- beginInsert() 插入数据前 返回表列定义
- finishInsert()
-
ConnectorPageSink
- appendPage 方法
-
DemoColumnHandle
- 重写 equals; hashCode (很重要)
-
注意点
-
SchemaTableName 会将schemaName、tableName 对象转小写,需要映射实现 ,获取数据需要
-
ColumnMetadata 会将查询列转小写 查询返回需 as Column.toLowerCase()
-
-
开始编写
-
实现接口 ConnectorMetadata
ConnectorMetadata 定义接口实现指定中间件的类SQL操作
-
读操作插件需要实现相关方法
T method(){ //jdbc or http 等客户端操作 返回接口需要的数据 } //获取库schema对象 List<String> getSchemaNames(); //获取指定table对象行数据 Iterator<Row> select(String tableName); //获取指定schema对象所有table对象 List<String> getTableName(String schemaName); //获取指定table对象字段描述信息 List<Column> getColumnsByTableName(String tableName)
-
六、验证插件
1、启动服务加载配置
-
启动主类
- com.facebook.presto.server.PrestoServer
-
VM Options
- -XX:+UseG1GC -XX:G1HeapRegionSize=32M -XX:+UseGCOverheadLimit -XX:+ExplicitGCInvokesConcurrent -Xmx2G -Dconfig=etc/config.properties -Dlog.levels-file=etc/log.properties
-
增加测试配置文件
#connector.name 名称必须与自定义 ConnectorFactory getName 匹配 connector.name=demo connection-url=jdbc:mysql://192.168.11.229:3306 connection-user=root connection-password=123456
-
修改配置加载插件
vi presto-main/etc/config.properties plugin.bundles=\ ../presto-mysql/pom.xml,\ ../presto-demo/pom.xml
2、客户端连接测试
#连接服务
./presto-cli-0.278.1-SNAPSHOT-executable.jar --server http://localhost:8080
#查看连接器
presto> SHOW catalogs;
Catalog
---------
demo
mysql
system
(3 rows)
#查看所有schema
presto> SHOW schemas from demo;
Schema
--------------------
db1
db2
db3
information_schema
(4 rows)
#查看schema下的表
presto> SHOW tables from demo.db1;
Table
--------
table1
table2
(2 rows)
#查看指定表结构
presto> SHOW COLUMNS FROM demo.db1.table1;
Column | Type | Extra | Comment
--------+---------+-------+---------
name | varchar | |
age | integer | |
(2 rows)
#查看数据
presto> select * from demo.db1.table1;
name | age
----------+-----
zhangsan | 18
(1 row)
七、后续集成实现插件
1、clone bigdata组下presto工程
git clone http://192.168.11.101:8083/bigdata/presto.git
2、复制 presto-demo模板模块
3、DemoDBHelper 实现相关方法代码
package com.facebook.presto.demo.thirtpart;
import com.facebook.presto.common.type.IntegerType;
import com.facebook.presto.common.type.VarcharType;
import com.facebook.presto.demo.DemoConfig;
import com.facebook.presto.demo.DemoRow;
import com.facebook.presto.spi.ColumnMetadata;
import com.google.common.collect.ImmutableList;
import javax.inject.Inject;
import java.util.*;
/**
* 操作数据库
*/
public class DemoDBHelper {
private String url;
private String user;
private String password;
@Inject
public DemoDBHelper(DemoConfig demoConnectorId) {
this.url = demoConnectorId.getUrl();
this.user = demoConnectorId.getUser();
this.password = demoConnectorId.getPassword();
}
/**
* 返回所有schema 对象
* @return
*/
public List<String> listSchemaNames() {
//TODO
return null;
}
/**
* 返回表定义结构信息
* @param schemaName
* @param tableName
* @return
*/
public List<ColumnMetadata> getColumnMetaData(String schemaName, String tableName) {
//TODO
return null;
}
/**
* 返回指定schema 下所有表
* @param schemaName
* @return
*/
public List<String> getTableNames(String schemaName) {
//TODO
return null;
}
/**
* 返回指定 List<Map> 对象
* @param schemaName
* @param tableName
* @return
*/
public Iterator<DemoRow> select(String schemaName, String tableName) {
//TODO
return null;
}
}