Presto简介、部署、原理和使用介绍
1. Presto简介
1-1. Presto概念
Presto是由Facebook开发的一款开源的分布式SQL查询引擎,最初于2012年发布,并在2013年成为Apache项目的一部分;Presto 作为现在在企业中流行使用的即席查询框架,已经在不同的领域得到了越来越多的应用。
Presto官方网站:https://prestosql.io/
Presto被广泛用作即席查询引擎,用户可以使用标准的SQL语句向Presto提交查询,并且能够在几秒钟或更短的时间内获取结果。这种即时性使得用户能够快速探索和分析数据,发现模式和洞见,而无需等待长时间的批处理作业完成。
即席查询(Ad-hoc query)是指用户可以根据自己的需求,在需要的时候灵活地提交查询请求,并且可以在实时或近实时的情况下获取查询结果。即席查询通常用于快速探索数据、解决临时问题、做出即时决策等场景。与之相对的是常规查询,即预先设计好的、固定的查询模板或流程,通常用于执行已经定义好的常规任务或报表。
1-2. Presto使用场景
Presto是一款支持在线数据查询的工具,可连接多种数据库如Hive、MySQL、Oracle等,一次查询可合并多个数据库进行跨组织分析。
1-2-1. 不同的功能使用场景
-
数据探索和交互式分析
- Presto提供了快速、实时的查询功能,用户可以使用标准SQL语句对大规模数据进行即席查询,探索数据集中的模式、趋势和异常值,并与数据进行交互式分析。
-
实时数据仪表盘和报表
- Presto可以用于构建实时数据仪表盘和报表,用户可以通过查询实时数据库来生成实时报表和可视化图表,监控业务指标、趋势和实时数据变化。
-
数据湖查询和分析
- Presto支持多种数据存储和计算框架的集成,包括Hadoop、Hive、S3等,可以用于查询和分析数据湖中的大规模数据,快速从海量数据中提取有用信息。
-
ETL和数据处理
- Presto可以用于执行复杂的数据转换、清洗和处理任务,支持各种数据库之间的连接和数据转换操作,帮助用户实现数据ETL(Extract-Transform-Load)流程。
-
实时事件分析和流式数据处理
- Presto可以与流式数据处理框架(如Apache Kafka)集成,用于执行实时事件分析和流式数据处理任务,从实时数据流中提取、过滤和分析有用信息。
-
数据科学和机器学习
- Presto可以用于数据科学和机器学习任务,支持从大规模数据集中提取特征、训练模型、执行预测和推断等操作,帮助数据科学家和机器学习工程师分析数据和构建模型。
-
多租户数据查询服务
- Presto可以作为多租户数据查询服务的基础,为多个用户或组织提供数据查询和分析功能,支持对不同用户或组织的数据进行隔离和访问控制。
1-2-2. 不同的业务场景举例
- 企业工商数据分析 :
- Presto可以连接企业的工商数据存储,如企业数据库、Hive表等,快速查询和分析企业的工商注册信息、营业数据、财务信息等。
- 通过Presto,企业可以实现对工商数据的即席查询和交互式分析,探索企业的运营情况、财务状况以及市场表现等关键指标。
- 舆情数据分析 :
- Presto可以连接舆情数据库,如社交媒体、新闻网站等,实现对舆情数据的实时抓取查询和分析。
- 通过Presto,企业可以实时监测和分析舆情动态,了解公众对企业品牌、产品和服务的看法和态度,及时回应和调整公关策略。
- 跨数据库分析 :
- Presto支持跨数据库的查询和分析,可以将企业工商数据和舆情数据等多个数据库进行合并分析,帮助企业发现不同数据库之间的关联和趋势。
- 通过Presto的即席查询功能,企业可以在不同数据库之间灵活进行探索和发现,发现潜在的商业机会和风险。
- 实时决策支持 :
- Presto提供了实时的查询和分析能力,可以帮助企业快速获取最新的工商数据和舆情数据,并支持实时决策和应对突发事件。
- 通过Presto的高性能和低延迟,企业可以及时了解市场变化和舆情动态,做出及时的决策和调整。
1-3. Presto的诞生
早期大多公司业务场景,做数仓分析时普遍采用了hive,而hive底层原理用MR,这样速度比较慢;并且公司hadoop集群调度批任务主要集中于晚上到凌晨,可白天工作时间负载不是很高。但在工作时间内,公司业务人员却又存在实时查询的需求,主要借助于hive提供业务人员的査询。hive基于MR类的SQL查询工具,会输入的查询SQL解析为MapReduce,好处是能极大的降低使用大数据门槛,通用SQL,业务人员有着基础上手很快,让一般的业务人员可以直接准对大数据进行查询,但缺点也显而易见,也正是因为它的査询基于MR,会让人等待比较着急,等待的时间可能是几十分钟甚至数个小时。
Hive是FaceBooke在几年前专门为Hadoop打造的一款数据仓库工具,在以前,facebook的科学家和分析师一直靠hive进行数据分析,随着数据的不断增多,不能满足查询需求。后来factbook公司在hive上面开发一套利器,使得hive可以通过sql语句进行快速查询,也就是现在的presto。相比原来的Hive数据分析,新的架构如下。
1-4. Presto 优缺点
1-4-1. Presto优点
-
高性能:Presto相对于Hive在处理PB级数据时性能更好,因为它是基于内存运算,减少了硬盘IO操作,因此在处理某些类型的查询时速度更快。
-
多数据库连接:Presto能够连接多个数据库,进行跨数据库的查询和连接操作,这使得用户可以方便地从不同的数据库中获取数据进行联合分析。
-
部署简单:相较于Hive,Presto的部署更加简单,因为不需要先部署HDFS,这降低了部署和配置的复杂性,使得用户可以更快速地搭建起数据分析平台。
多数据库连接查询:
1-4-2. Presto缺点
-
内存管理:尽管Presto能够处理PB级别的数据,但在一些场景下并不是将全部数据加载到内存中进行计算的。对于一些聚合运算,Presto是边读取数据边计算,因此在连表查询等情况下可能会产生大量的临时数据,导致速度变慢。
-
实时查询限制:虽然Presto支持实时查询,但是直接连接MySQL等数据库并不会提高查询效率,反而可能会引入网络瓶颈,导致查询速度较慢。因此在一些实时查询场景下,性能可能不如预期。
Presto在高性能、多数据库连接和部署简单等方面具有明显优势,但在内存管理和实时查询的限制方面还存在一些缺点,需要根据具体的使用场景来权衡选择。
1-4-3. Presto与竞品对比
特点 | Presto | Hive | Impala | Spark |
---|---|---|---|---|
发布公司 | Apache | Cloudera | Apache | |
数据处理方式 | 基于内存计算,支持实时查询和交互式分析 | 基于MapReduce,较慢;可通过Tez或Spark提速 | 基于MPP架构,较快的交互式SQL查询 | 内存计算和硬盘计算混合,可处理多种数据处理任务 |
查询语言 | 标准SQL | HiveQL(SQL-like) | SQL | Spark SQL(标准SQL) |
数据库连接 | 支持多种数据库,如Hive、MySQL、Oracle等 | 主要连接HDFS和Hive表 | 只能连接HDFS和HBase | 支持多种数据库,如HDFS、Hive、Kafka等 |
数据格式 | 支持多种数据格式,如Parquet、ORC等 | 支持多种数据格式,如Parquet、ORC等 | 支持多种数据格式,如Parquet、ORC等 | 支持多种数据格式,如Parquet、ORC、JSON、CSV等 |
部署复杂度 | 相对较低 | 相对较高 | 相对较低 | 相对较低 |
实时性 | 支持实时查询 | 不适合实时查询 | 支持实时查询 | 部分支持实时查询 |
扩展性 | 高 | 一般 | 高 | 高 |
压缩算法支持 | 支持多种压缩算法,如Snappy、LZO等 | 支持多种压缩算法,如Snappy、LZO等 | 支持多种压缩算法,如Snappy、LZO等 | 支持多种压缩算法,如Snappy、LZO、GZIP等 |
SQL优化 | 有较好的查询优化器,能够生成高效的查询计划 | 通过Tez或Spark可提高查询性能 | 有较好的查询优化器,能够生成高效的查询计划 | 有较好的查询优化器,能够生成高效的查询计划 |
- Presto与Impala取舍
Presto和Impala都是用于大数据处理和分析的工具,它们各有优缺点,相对来说对内存要求都很高,组件的取舍取决于具体的需求和场景。
性能:Impala通常比Presto快,特别是在处理较大数据集时。这是因为Impala使用更接近传统数据库的架构,执行查询时不需要转换为MapReduce作业。
查询语法:Presto支持标准SQL,而Impala使用的是类似SQL的HiveQL。如果您更熟悉标准SQL,可能会更喜欢Presto。
扩展性:Presto的扩展性较好,可以轻松地连接多种数据库,而Impala主要适用于连接HDFS和HBase。
部署复杂度:Presto的部署相对简单,而Impala可能需要更多的配置和管理。
生态系统:Presto有一个活跃的社区和丰富的生态系统,而Impala在这方面稍显不足。
基于以上考虑因素,如果对性能要求较高且数据集较大,可能更倾向于选择Impala。但impala只能对接hive,而presto能对接很多种类的数据源,如果业务场景更偏向标准SQL、跨数据库、对扩展性要求较高或希望部署简单,则可能更适合选择Presto。
1-5. Presto强大的功能示例
通过几个示例可以更好的体会Presto的优势
- 联合查询
假设有一个需求是要统计每个用户在不同数据库中的活动情况,包括用户信息(存储在Hive中)、订单信息(存储在MySQL中)和日志信息(存储在Elasticsearch中)。可以通过Presto进行联合查询,将这些数据库的信息合并在一起进行分析
sql
SELECT u.user_id, COUNT(o.order_id) AS order_count, COUNT(l.log_id) AS log_count
FROM hive.users u
LEFT JOIN mysql.orders o ON u.user_id = o.user_id
LEFT JOIN elasticsearch.logs l ON u.user_id = l.user_id
GROUP BY u.user_id;
- 数据转换和聚合
假设需要对Hive中的用户行为数据进行聚合,并与MySQL中的用户信息进行关联,以便进行更深入的分析。可以使用Presto将数据从不同数据库中取出,进行聚合和转换
sql
SELECT u.user_id, u.username, COUNT(1) AS activity_count
FROM hive.user_activity a
JOIN mysql.users u ON a.user_id = u.user_id
GROUP BY u.user_id, u.username;
- 实时数据分析
假设有一个需求是要对Elasticsearch中的实时日志数据进行分析,并与MySQL中的用户信息进行关联。可以使用Presto查询Elasticsearch和MySQL,实时地分析和关联数据
sql
SELECT l.timestamp, u.username, l.action
FROM elasticsearch.logs l
JOIN mysql.users u ON l.user_id = u.user_id
WHERE l.timestamp > NOW() - INTERVAL 1 HOUR;
- 复杂数据处理
Presto支持复杂的数据处理和转换操作,如JSON解析、正则表达式处理等。例如,可以使用Presto将JSON数据解析为表格形式,并进行进一步的分析
sql
SELECT json_extract_scalar(data, '$.name') AS name,
json_extract_scalar(data, '$.age') AS age
FROM json_table;
- 连接不同存储系统
除了Hive、MySQL和Elasticsearch外,Presto还可以连接其他存储系统,如马逊提供的一种云存储服务S3、Azure Blob Storage等。这使得Presto成为一个强大的数据分析工具,可以处理各种数据库
sql
SELECT * FROM s3.my_bucket.my_table;
- 动态分区和分区裁剪
Presto支持动态分区和分区裁剪,可以根据查询条件自动选择需要查询的分区,提高查询性能。
sql
SELECT *
FROM hive.my_table
WHERE date_column = date '2024-02-23';
- 数据加密插件
数据加密插件来创建一个加密表。该表的数据将被加密存储,以提高数据安全性
sql
-- 创建加密表
CREATE TABLE encrypted_table (
id INT,
name VARCHAR,
encrypted_data VARBINARY
) WITH (
format = 'ORC',
encryption = 'aes256',
key_provider = 'kms',
key = 'arn:aws:kms:us-east-1:123456789012:key/abcd1234-12ab-34cd-56ef-1234567890ab'
);
- 认证插件
通过设置这些认证信息,用户可以使用用户名和密码进行身份验证,以确保只有经过授权的用户可以访问Presto系统
sql
-- 使用用户名/密码进行认证
SET SESSION user = 'username';
SET SESSION password = 'password';
1-6. Presto常见的数据库支持
- Hive:基于Hadoop的数据仓库系统。
- MySQL:流行的关系型数据库管理系统。
- PostgreSQL:强大的开源关系型数据库。
- Elasticsearch:分布式搜索和分析引擎。
- Oracle:企业级关系型数据库管理系统。
- Cassandra:分布式NoSQL数据库管理系统。
- MongoDB:面向文档的NoSQL数据库管理系统。
- SQL Server:微软开发的关系型数据库管理系统。
- S3:亚马逊提供的对象存储服务。
- HDFS:Apache Hadoop分布式文件系统。
- Kafka:分布式事件流平台。
- Redis:内存数据库,用作缓存、消息队列等。
- JDBC:支持通过JDBC连接到各种关系型数据库。
- Avro:序列化数据格式,通常与Hadoop生态系统一起使用。
- Parquet:一种列式存储格式,用于大数据分析。
- ORC:另一种列式存储格式,用于大数据分析。
- Delta Lake:构建在Apache Spark之上的数据湖解决方案,支持ACID事务和增量数据加载。
- Greenplum:基于PostgreSQL的开源大数据分析平台。
- Teradata:一种用于数据仓库和分析的关系型数据库管理系统。
- PrestoDB:另一个分布式SQL查询引擎,可以作为Presto的数据库之一。
- ClickHouse:开源列式数据库管理系统,用于在线分析处理(OLAP)。
- MemSQL:分布式内存数据库管理系统,用于实时数据分析。
- Couchbase:分布式NoSQL文档数据库,用于实时数据存储和分析。
- Vertica:大数据分析平台,用于数据仓库和实时分析。
- Splunk:用于搜索、监控和分析大规模实时数据的平台。
- Snowflake:云数据仓库平台,支持结构化和半结构化数据的分析。
- DynamoDB:亚马逊提供的NoSQL数据库服务,用于实时应用程序。
- BigQuery:Google Cloud提供的大数据分析平台,用于处理大规模结构化数据。
- Azure SQL Database:微软提供的云端关系型数据库服务,用于数据存储和分析。
- Redshift:亚马逊提供的云端数据仓库服务,用于大规模数据分析。
2. Presto安装部署
2-1. presto集群规划与环境准备
- 服务器
主机名 | 角色 | 环境要求 |
---|---|---|
poc01 | coordinator | python版本是2.4+ ; java版本是8u151+ |
poc02 | worker | python版本是2.4+ ; java版本是8u151+ |
poc03 | worker | python版本是2.4+ ; java版本是8u151+ |
- 环境查看(各机器 )
shell
[root@poc01 software]# python -V
Python 2.7.5
[root@poc01 software]# java -version
java version "1.8.0_371"
Java(TM) SE Runtime Environment (build 1.8.0_371-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.371-b11, mixed mode)
2-2. 下载安装presto
- 下载
shell
[root@poc01 software]# wget https://repo1.maven.org/maven2/com/facebook/presto/presto-server/0.285.1/presto-server-0.285.1.tar.gz
官方安装文档:https://prestodb.io/docs/current/installation/deployment.html#
- 解压
shell
[root@poc01 software]# tar -xf presto-server-0.285.1.tar.gz -C /opt/module/
presto将包含一个顶级目录presto-server-0.285.1,我们将其称为presto安装目录。
Presto需要一个路径来存储log日志、etc配置等。建议在安装目录之外创建这个目录,这样在升级Presto时可以很容易地保留它。
-
分发
[root@poc01 software]# scp -r /opt/module/presto-server-0.285.1 poc02:/opt/module/
[root@poc01 software]# scp -r /opt/module/presto-server-0.285.1 poc03:/opt/module/
这一步也可以等全部配置结束后再分发,但是要注意分发后再去逐个服务器上改对应配置文件
2-3. 配置presto
- 创建存储数据文件夹
shell
[root@poc01 opt]# mkdir /opt/data
[root@poc01 opt]# mkdir -p /opt/data/prestodata
- 创建配置文件目录
注意:官方的安装包默认没有etc配置文件目录,需要自行创建
shell
[root@poc01 etc]# cd /opt/module/presto-server-0.285.1/
[root@poc01 presto-server-0.285.1]# mkdir etc
etc目录。这将包含以下配置:
- node节点配置: 每个节点的环境配置
- JVM配置: Java虚拟机的命令行选项
- Config 配置属性: Presto服务器的配置。有关可用的配置属性
- Catalog属性配置: 连接器(数据源)的配置
- 日志配置:配置日志级别,可选
- node节点配置
节点属性文件node.properties
,包含特定于每个节点的配置。节点是机器上安装的Presto的单个实例。这个文件通常在Presto首次安装时部署系统时创建。以下是etc/node.properties的最少配置项
node.environment : 环境的名称。集群中的所有Presto节点必须具有相同的环境名称
node.id : Presto安装的唯一标识符。这对于每个节点都必须是唯一的。这个标识符应该在重新启动或升级Presto时保持一致,这里的格式复制了官方的格式,如果简单的用1、2、3来表示node.id也可以
node.data-dir : 数据目录的位置(文件系统路径)。Presto将存储日志和其他数据
shell
### 服务器-poc01
[root@poc01 opt]# cd /opt/module/presto-server-0.285.1/etc/
[root@poc01 etc]# vim node.properties
node.environment=production
node.id=ffffffff-ffff-ffff-ffff-fffffffffff1
node.data-dir=/opt/data/prestodata
### 服务器-poc02
[root@poc02 opt]# cd /opt/module/presto-server-0.285.1/etc/
[root@poc02 etc]# vim node.properties
node.environment=production
node.id=ffffffff-ffff-ffff-ffff-fffffffffff2
node.data-dir=/opt/data/prestodata
### 服务器-poc03
[root@poc01 opt]# cd /opt/module/presto-server-0.285.1/etc/
[root@poc01 etc]# vim node.properties
node.environment=production
node.id=ffffffff-ffff-ffff-ffff-fffffffffff3
node.data-dir=/opt/data/prestodata
- JVM配置文件(各节点配置相同即可)
包含用于启动Java虚拟机的命令行选项列表。文件的格式是一个选项列表,每行一个。这些选项不会被shell解释,所以不要出现包含空格或其他特殊字符
shell
[root@poc01 opt]# cd /opt/module/presto-server-0.285.1/etc/
[root@poc01 etc]# vim jvm.config
-server
-Xmx16G
-XX:+UseG1GC
-XX:G1HeapRegionSize=32M
-XX:+UseGCOverheadLimit
-XX:+ExplicitGCInvokesConcurrent
-XX:+HeapDumpOnOutOfMemoryError
-XX:+ExitOnOutOfMemoryError
由于OutOfMemoryError通常会使JVM处于不一致的状态,因此我们编写堆转储(用于调试),并在发生这种情况时强制终止进程
-Xmx16G 根据服务器的内存配置来调整
-
配置config.properties
包含Presto服务配置。每个Presto服务都可以同时充当协调器和工作器,但是在较大的集群中,将一台机器专门用于执行协调工作可以提供最佳性能。
虽然presto server可以同时作为coordinator和worker;但是为了更好的性能,一般让server要么作为coordinator,要么作为worker
shell
### 服务器-poc01
[root@poc01 etc]# vim config.properties
coordinator=true
node-scheduler.include-coordinator=false
http-server.http.port=8880
query.max-memory=50GB
query.max-memory-per-node=1GB
discovery-server.enabled=true
discovery.uri=http://poc01:8880
### 服务器-poc02 / poc03
coordinator=false
http-server.http.port=8880
query.max-memory=50GB
discovery.uri=http://poc01:8880
http-server.http.port端口可以自定义,例如常用的8080等等均可。
其它参数的值均可以根据服务器的内存等资源进行调整
- 日志配置
日志配置可选,均有默认值,如需要对日志进行配置则对应etc/log.properties
shell
[root@poc01 etc]# vim log.properties
com.facebook.presto=INFO
默认的最小级别是INFO(因此上面的示例实际上没有改变任何东西)。但也可以根据实际情况调整级别,
有四个级别:DEBUG, INFO, WARN和ERROR。
- catalog配置(MySQL示例)
官方关于catalog的配置介绍:https://prestodb.io/docs/0.285.1/connector.html
catalog 可以根据业务场景,随意配置,例如常见的hive-catalog配置等等均可,原理类似,仅仅是配置不同,可以打开上方的地址,打开不同的connector选项进入查看
不同的catalog配置本质对应了应用目录下plugin 插件目录下的不同插件,默认安装约40多个,可以满足非常多的使用场景;如默认plugin没有,需要去官方搜索下载。
catalog 涉及的配置相对较多,故使用catalog目录进行归档
shell
[root@poc01 data]# cd /opt/module/presto-server-0.285.1/etc/
[root@poc01 etc]# mkdir catalog
[root@poc01 etc]# cd catalog/
[root@poc01 catalog]# vim mysql.properties
connector.name=mysql
connection-url=jdbc:mysql://116.63.88.111:3306
connection-user=root
connection-password=123456
# 分发 mysql.properties
[root@poc01 catalog]# scp -r /opt/module/presto-server-0.285.1/etc/catalog poc02:/opt/module/presto-server-0.285.1/etc/
[root@poc01 catalog]# scp -r /opt/module/presto-server-0.285.1/etc/catalog poc03:/opt/module/presto-server-0.285.1/etc/
在Presto中配置Catalog Properties是为了定义连接到不同数据源的参数,例如数据库连接信息、认证信息等。要配置Catalog Properties,你需要编辑Presto的配置文件,并在其中指定相关的属性
在这个示例中,
connector.name
定义了使用的连接器名称(这里是mysql)。connection-url
指定了要连接的MySQL数据库的URL,connection-user
和connection-password
是连接数据库所需的用户名和密码。
< 以下这段是一个踩坑分享,安装部署可以忽略跳过下面这段 >在配置
mysql.properties
时,connection-url的参数开始配置成了:
connection-url=jdbc:mysql://116.63.88.111:3306/test
在jdbc后面加上了库名: test,因平时开发习惯,jdbc后面大多场景都是跟上库名,这样配置以后,进行了服务启动报错了
shell2024-02-22T14:30:33.289+0800 ERROR main com.facebook.presto.server.PrestoServer Unable to create injector, see the following errors: 1) Explicit bindings are required and com.facebook.presto.plugin.mysql.MySqlConfig is not explicitly bound. while locating com.facebook.presto.plugin.mysql.MySqlConfig for the 3rd parameter of com.facebook.presto.plugin.mysql.MySqlClient.<init>(MySqlClient.java:68) at com.facebook.presto.plugin.mysql.MySqlClientModule.setup(MySqlClientModule.java:35) 2) An exception was caught and reported. Message: Database (catalog) must not be specified in JDBC URL for MySQL connector at com.google.inject.internal.InjectorShell$Builder.build(InjectorShell.java:137) 2 errors com.google.inject.CreationException: Unable to create injector, see the following errors: 1) Explicit bindings are required and com.facebook.presto.plugin.mysql.MySqlConfig is not explicitly bound. while locating com.facebook.presto.plugin.mysql.MySqlConfig for the 3rd parameter of com.facebook.presto.plugin.mysql.MySqlClient.<init>(MySqlClient.java:68) at com.facebook.presto.plugin.mysql.MySqlClientModule.setup(MySqlClientModule.java:35) 2) An exception was caught and reported. Message: Database (catalog) must not be specified in JDBC URL for MySQL connector at com.google.inject.internal.InjectorShell$Builder.build(InjectorShell.java:137)
根据报错信息,可以看出有两个问题:
缺少对com.facebook.presto.plugin.mysql.MySqlConfig的绑定
在MySQL连接器的JDBC URL中指定了数据库(catalog),这是不允许的
所以后面把库名去除
2-4. 启动presto服务
shell
### 服务器-poc01
[root@poc01 catalog]# /opt/module/presto-server-0.285.1/bin/launcher start
[root@poc01 log]# jps
19860 PrestoServer
20440 Jps
### 服务器-poc02
[root@poc02 catalog]# /opt/module/presto-server-0.285.1/bin/launcher start
Started as 29132
[root@poc02 catalog]# jps
29235 Jps
29132 PrestoServer
### 服务器-poc03
[root@poc03 catalog]# /opt/module/presto-server-0.285.1/bin/launcher start
Started as 15714
[root@poc03 catalog]# jps
15714 PrestoServer
15855 Jps
PrestoServer进程如果没有挂起,则说明服务启动失败
在
node.properties
配置中,指定了node.data-dir=/opt/data/prestodata
,所以日志查看可以进到这个目录,会生成一个var/log目录进行日志写入。
日志分析路径:
shell
[root@poc01 prestodata]# ll
total 4
lrwxrwxrwx 1 root root 37 Feb 22 14:39 etc -> /opt/module/presto-server-0.285.1/etc
lrwxrwxrwx 1 root root 40 Feb 22 14:39 plugin -> /opt/module/presto-server-0.285.1/plugin
drwxr-xr-x 4 root root 4096 Feb 22 14:30 var
[root@poc01 prestodata]# cd var/log/
[root@poc01 log]# ll
total 684
-rw-r--r-- 1 root root 49662 Feb 22 14:44 http-request.log
-rw-r--r-- 1 root root 900 Feb 22 14:39 launcher.log
-rw-r--r-- 1 root root 636570 Feb 22 14:39 server.log
[root@poc01 log]# tail -f server.log
2024-02-22T14:39:47.350+0800 INFO main com.facebook.presto.security.AccessControlManager -- Loaded system access control allow-all --
2024-02-22T14:39:47.351+0800 INFO main com.facebook.presto.storage.TempStorageManager -- Loading temp storage local --
2024-02-22T14:39:47.372+0800 INFO main com.facebook.presto.storage.TempStorageManager -- Loaded temp storage local --
2024-02-22T14:39:47.385+0800 INFO main com.facebook.presto.server.PrestoServer ======== SERVER STARTED ========
2-5. presto的web-ui界面
config.properties
配置中,http-server.http.port=8880
则对应了web-ui的服务端口
shell
[root@poc01 log]# netstat -tnlpu|grep 8880
tcp6 0 0 :::8880 :::* LISTEN 19860/java
[root@poc01 log]# jps -l | grep 19860
19860 com.facebook.presto.server.PrestoServer
通过IP:8880来页面访问
2-6. presto-cli客户端连接工具
官网下载地址:https://prestodb.io/getting-started/ [ Command Line Interface ]
shell
[root@poc01 software]# wget https://repo1.maven.org/maven2/com/facebook/presto/presto-cli/0.285.1/presto-cli-0.285.1-executable.jar
[root@poc01 software]# mv presto-cli-0.285.1-executable.jar presto
[root@poc01 software]# chmod +x presto
# 使用示例
[root@poc01 software]# ./presto --server poc01:8880 --catalog mysql
presto> show schemas;
Schema
--------------------
db3_2
flinkcdc
information_schema
ke
myemployees
pandas
performance_schema
test
test2
test3
world
wow
xinhuadb
(13 rows)
Query 20240222_070945_00000_qcp9s, FINISHED, 3 nodes
Splits: 36 total, 36 done (100.00%)
[Latency: client-side: 0:02, server-side: 0:02] [13 rows, 163B] [8 rows/s, 102B/s]
-- server 指定的是 coordinator 的地址 -- catalog 指定的是连接的数据源
针对MySQL的catalog,
show schemas;
应该对应着MySQL中的databases
3. presto原理
3-1. Presto架构
3-1-1. 系统架构
Presto查询引擎是一个Master-Slave的主从架构,Coordinator是主,worker是从
- Coordinator节点
- Worker节点
3-1-2. 软件架构
Coordinator 与 Worker、Client 通信是通过 REST API
-
Coordinator节点:
- Coordinator节点是Presto集群的中心节点,负责接收来自客户端的查询请求,并协调集群中的其他工作节点来执行这些查询。
- 它负责解析SQL查询语句、优化查询计划、分配任务给工作节点、收集和汇总结果,并将结果返回给客户端。
- discovery server ,负责维护Coordinator和worker节点的关系,worker节点启动后向discovery service服务注册,Coordinator通过discovery service获取注册的worker节点以及catalog,通常内嵌于Coordinator节点中。
Coordinator节点:Coordinator节点就像是一个指挥中心,负责接收指令(查询请求),并协调工作人员(Worker节点)来执行任务。
-
Worker节点:
- Worker节点是Presto集群中的工作节点,负责实际执行查询任务。
- 每个Worker节点都运行着一个Presto进程,该进程负责执行查询计划中的特定任务,如扫描数据、过滤数据、聚合数据等。
Worker节点:Worker节点就像是工厂里的工人,负责执行具体的任务。每个工人都有自己的工作台(Presto进程),按照指示完成任务,并将结果报告给指挥中心。
-
数据库连接器:
- Presto通过连接器(connector)与各种数据库进行通信,包括Hive、MySQL、PostgreSQL、Elasticsearch等。
- 每个连接器负责实现与特定数据库的通信协议,并将数据库中的数据转换为Presto可理解的格式。
数据库连接器:数据库连接器就像是工厂的供应链,负责与不同的供应商(数据库)进行通信,并将所需的原材料(数据)转换成工厂可以使用的格式
-
查询执行流程:
- 当客户端提交一个查询请求时,Coordinator节点接收到该请求并解析SQL语句。
- 然后,Coordinator节点将查询计划分解为一系列任务,并将这些任务分配给Worker节点执行。
- 每个Worker节点负责执行分配给它的任务,并将结果返回给Coordinator节点。
- 最后,Coordinator节点将所有结果合并并返回给客户端。
查询执行流程:查询执行流程就像是生产流水线,指挥中心将生产计划安排好后,工人们按照流程一步一步地完成工作,最终将成品交付给客户。
-
查询优化器:
- Presto具有强大的查询优化器,能够根据查询的特性和数据的分布情况生成高效的查询计划。
- 查询优化器负责选择最佳的执行计划、重排序操作、选择合适的连接算法等,以提高查询性能。
查询优化器:查询优化器就像是生产计划员,负责规划生产流程,安排工作顺序,以最大程度地提高生产效率。
3-2. presto几个重要点
-
分布式架构: Presto是一个分布式系统,由多个节点组成,包括协调器(Coordinator)和工作节点(Worker)。协调器负责接收和解析用户查询请求,生成查询计划,并协调工作节点执行任务。工作节点负责实际执行查询任务,从数据源读取数据并进行计算处理。
-
查询计划生成: Presto使用成本优化器(Cost-Based Optimizer)生成查询计划。优化器根据查询的复杂性、连接的表数以及数据分布等因素,选择最佳的查询计划,以提高查询性能。
-
presto对一个传入的sql语句如何进行解析并生成最终的执行计划
-
-
任务调度与并行执行: 查询计划被转换为一系列任务,这些任务被分配给工作节点并行执行。任务调度器负责将任务分配给可用的工作节点,并协调任务的执行顺序。
- 在调度任务时,有几个决策点,第一:分配多少个任务,第二:每个任务分配到哪些机器上
- presto提供了一种基于拓扑的调度算法(Topology Aware schedule),以使source节点尽量靠近数据
-
数据传输与交互: Presto使用高性能的数据传输协议在节点之间传输数据。这些协议被优化以提供低延迟和高吞吐量。节点之间通过这些协议进行数据交互,完成查询的执行和结果的传输。
-
元数据管理: Presto的元数据存储在内存中,包括表和列的信息。元数据管理器负责维护元数据,并在查询解析时使用元数据来了解查询需要访问哪些数据源。
-
查询优化与性能: Presto通过优化查询计划、并行执行任务以及高效的数据传输等技术,提高了查询性能和可扩展性。成本优化器和任务调度器在整个查询执行过程中起着关键作用,确保查询能够在分布式环境下高效执行。
-
容错性与健壮性: Presto具有一定的容错机制,可以处理节点故障和任务失败等情况。当发生故障时,Presto会重新分配任务并继续执行查询,以确保查询的完成和结果的正确性。
3-3. Presto数据模型
-
Catalog(目录):
- Catalog是Presto中的最顶层概念,类似于数据库管理系统(DBMS)中的数据库。
- 每个Catalog对应一个数据源,可以是Hive、MySQL、PostgreSQL等。
- Catalog包含了一组Schema,以及这些Schema中的表和视图等对象。
-
Schema(模式):
- Schema是Catalog中的一个逻辑概念,类似于关系数据库中的数据库(Database)。
- 每个Schema对应一个命名空间,用于组织和管理表、视图等对象。
- Schema可以包含多个表,每个表都有一个唯一的名称,并且属于特定的Schema。
-
表(Table):
- 表是Schema中的一个基本单元,用于存储数据记录。
- 每个表都有一个唯一的名称,并且包含多个列和多行数据。
- 表可以来自不同的数据源,如Hive表、MySQL表等。
-
列(Column):
- 列是表中的一个属性,用于存储特定类型的数据。
- 每个列都有一个名称和数据类型,例如整数、字符串、日期等。
- 列组成了表的结构,描述了表中每条记录的各个属性。
-
行(Row):
- 行是表中的一个数据记录,包含了每个列的具体数值。
- 每行代表了一个数据实体,例如一个用户、一笔交易等。
- 通过查询可以检索、过滤和操作行数据。
-
分区(Partition):
- 分区是对表数据的逻辑划分,用于提高查询性能和管理数据。
- 每个分区根据某个列的值将表数据分成多个逻辑部分。
- 分区可以基于时间、地区、类别等维度进行划分。
4. presto使用
4-1. presto数据类型
数据类型可以在业务使用中,根据实际情况参考官方文档:https://prestodb.io/docs/current/language/types.html
Boolean
Integer
Floating-Point
Fixed-Precision
String
Date and Time
Structural
Network Address
UUID
HyperLogLog
KHyperLogLog
SetDigest
Quantile Digest
T-Digest
4-2. presto-SQL语法
SQL-语法:https://prestodb.io/docs/current/sql.html
建议遇到具体场景,尽量查询官方的文档,相对全面并附带Examples示例
- ALTER SCHEMA
sql
-- 修改schema名称
ALTER SCHEMA name RENAME TO new_name;
- ALTER TABLE
sql
-- 修改表名称
ALTER TABLE [ IF EXISTS ] name RENAME TO new_name;
-- 添加新列
ALTER TABLE [ IF EXISTS ] name ADD COLUMN [ IF NOT EXISTS ] column_name data_type [ COMMENT comment ] [ WITH ( property_name = expression [, ...] ) ];
-- 删除列
ALTER TABLE [ IF EXISTS ] name DROP COLUMN column_name;
-- 修改列名称
ALTER TABLE [ IF EXISTS ] name RENAME COLUMN [ IF EXISTS ] column_name TO new_column_name;
- ANALYZE
sql
-- 分析表的统计信息
ANALYZE table_name [ WITH ( property_name = expression [, ...] ) ];
- CALL
sql
-- 调用存储过程
CALL procedure_name ( [ name => ] expression [, ...] );
- COMMIT
sql
-- 提交事务
COMMIT [ WORK ];
- CREATE ROLE
sql
-- 创建角色
CREATE ROLE role_name
[ WITH ADMIN ( user | USER user | ROLE role | CURRENT_USER | CURRENT_ROLE ) ];
- CREATE SCHEMA
sql
-- 创建schema
CREATE SCHEMA [ IF NOT EXISTS ] schema_name
[ WITH ( property_name = expression [, ...] ) ];
- CREATE TABLE
sql
-- 创建表
CREATE TABLE [ IF NOT EXISTS ]
table_name (
{ column_name data_type [ COMMENT comment ] [ WITH ( property_name = expression [, ...] ) ]
| LIKE existing_table_name [ { INCLUDING | EXCLUDING } PROPERTIES ] }
[, ...]
)
[ COMMENT table_comment ]
[ WITH ( property_name = expression [, ...] ) ];
-- 创建表并插入数据
CREATE TABLE [ IF NOT EXISTS ] table_name [ ( column_alias, ... ) ]
[ COMMENT table_comment ]
[ WITH ( property_name = expression [, ...] ) ]
AS query
[ WITH [ NO ] DATA ];
- CREATE VIEW
sql
-- 创建视图
CREATE [ OR REPLACE ] VIEW view_name
[ SECURITY { DEFINER | INVOKER } ]
AS query;
- DEALLOCATE PREPARE
sql
-- 取消预处理语句
DEALLOCATE PREPARE statement_name;
- DELETE
sql
-- 删除数据
DELETE FROM table_name [ WHERE condition ];
- DESCRIBE
sql
-- 查看表结构
DESCRIBE table_name;
-- 查看预处理语句的输入参数
DESCRIBE INPUT statement_name;
-- 查看预处理语句的输出参数
DESCRIBE OUTPUT statement_name;
- DROP
sql
-- 删除角色
DROP ROLE role_name;
-- 删除schema
DROP SCHEMA [ IF EXISTS ] schema_name;
-- 删除表
DROP TABLE [ IF EXISTS ] table_name;
-- 删除视图
DROP VIEW [ IF EXISTS ] view_name;
- EXECUTE
sql
-- 执行预处理语句
EXECUTE statement_name [ USING parameter1 [ , parameter2, ... ] ];
- EXPLAIN
sql
-- 解释查询计划
EXPLAIN [ ( option [, ...] ) ] statement;
-- 解释查询计划并执行
EXPLAIN ANALYZE [ VERBOSE ] statement;
- GRANT
sql
-- 授予用户权限
GRANT ( privilege [, ...] | ( ALL PRIVILEGES ) )
ON [ TABLE ] table_name TO ( user | USER user | ROLE role )
[ WITH GRANT OPTION ];
-- 授予角色权限
GRANT role [, ...]
TO ( user | USER user | ROLE role ) [, ...]
[ GRANTED BY ( user | USER user | ROLE role | CURRENT_USER | CURRENT_ROLE ) ]
[ WITH ADMIN OPTION ];
- INSERT
sql
-- 插入数据
INSERT INTO table_name [ ( column [, ... ] ) ] query;
- PREPARE
sql
-- 准备预处理语句
PREPARE statement_name FROM statement;
- RESET SESSION
sql
-- 重置会话参数
RESET SESSION name;
RESET SESSION catalog.name;
- REVOKE
sql
-- 撤销用户权限
REVOKE [ GRANT OPTION FOR ]
( privilege [, ...] | ALL PRIVILEGES )
ON [ TABLE ] table_name FROM ( user | USER user | ROLE role );
-- 撤销角色权限
REVOKE
[ ADMIN OPTION FOR ]
role [, ...]
FROM ( user | USER user | ROLE role) [, ...]
[ GRANTED BY ( user | USER user | ROLE role | CURRENT_USER | CURRENT_ROLE ) ];
- ROLLBACK
sql
-- 回滚事务
ROLLBACK [ WORK ];
- SELECT
sql
-- 查询数据
[ WITH with_query [, ...] ]
SELECT [ ALL | DISTINCT ] select_expr [, ...]
[ FROM from_item [, ...] ]
[ WHERE condition ]
[ GROUP BY [ ALL | DISTINCT ] grouping_element [, ...] ]
[ HAVING condition]
[ { UNION | INTERSECT | EXCEPT } [ ALL | DISTINCT ] select ]
[ ORDER BY expression [ ASC | DESC ] [, ...] ]
[ OFFSET count [ { ROW | ROWS } ] ]
[ { LIMIT [ count | ALL ] } ];
- SET
sql
-- 设置角色
SET ROLE ( role | ALL | NONE );
-- 设置会话参数
SET SESSION name = expression;
SET SESSION catalog.name = expression;
- SHOW
sql
-- 显示catalogs
SHOW CATALOGS [ LIKE pattern ];
-- 显示表的列信息
SHOW COLUMNS FROM table;
-- 显示函数的创建语句
SHOW CREATE FUNCTION function_name [ ( parameter_type[, ...] ) ];
-- 显示表的创建语句
SHOW CREATE TABLE table_name;
-- 显示视图的创建语句
SHOW CREATE VIEW view_name;
-- 显示函数列表
SHOW FUNCTIONS [ LIKE pattern [ ESCAPE 'escape_character' ] ];
-- 显示表的权限信息
SHOW GRANTS [ ON [ TABLE ] table_name ];
-- 显示角色的权限信息
SHOW ROLE GRANTS [ FROM catalog ];
-- 显示当前角色
SHOW [ CURRENT ] ROLES [ FROM catalog ];
-- 显示schema列表
SHOW SCHEMAS [ FROM catalog ] [ LIKE pattern ];
-- 显示会话信息
SHOW SESSION [ LIKE pattern ];
-- 显示表的统计信息
SHOW STATS FOR table;
SHOW STATS FOR ( SELECT * FROM table [ WHERE condition
4-3. java连接presto
利用jdbc协议来连接presto
pom.xml中添加配置:
xml
<dependency>
<groupId>com.facebook.presto</groupId>
<artifactId>presto-jdbc</artifactId>
<version>0.285.1</version>
</dependency>
java代码示例java2presto.java
java
package com.zenitera.bigdata.service;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class java2presto {
public static void main(String[] args) {
try {
// 加载Presto的JDBC驱动程序
Class.forName("com.facebook.presto.jdbc.PrestoDriver");
// 创建连接
Connection connection = DriverManager.getConnection("jdbc:presto://poc01:8880/mysql/test", "root", null);
// 创建Statement对象
Statement stmt = connection.createStatement();
// 执行查询
ResultSet rs = stmt.executeQuery("show schemas");
// 处理结果集
while (rs.next()) {
System.out.println(rs.getString(1));
}
// 关闭连接
rs.close();
stmt.close();
connection.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
查看运行效果:
4-4. python连接presto
涉及2个包模块
shell
# 连接工具
pip install presto-python-client
# urllib3的高版本对OpenSSL版本要求较高
pip install urllib3==1.26.7
python代码 test_presto.py
python
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# @Project :wangting_python
# @File :test_presto.py
# @Time :2024/2/27 14:40
# @Author :wangting_666
# @Email :wangting@zenitera.com
# pip install presto-python-client
# pip install urllib3==1.26.7
import prestodb
conn = prestodb.dbapi.connect(
host='116.63.88.66',
port=8880,
user='root',
catalog='mysql',
schema='test',
ssl=False
)
# 创建一个 cursor 对象
cur = conn.cursor()
# 执行查询
cur.execute('show schemas')
# 检索结果
rows = cur.fetchall()
for row in rows:
print(row)
# 关闭连接
cur.close()
conn.close()
执行效果如下: