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. 不同的业务场景举例
  1. 企业工商数据分析
    • Presto可以连接企业的工商数据存储,如企业数据库、Hive表等,快速查询和分析企业的工商注册信息、营业数据、财务信息等。
    • 通过Presto,企业可以实现对工商数据的即席查询和交互式分析,探索企业的运营情况、财务状况以及市场表现等关键指标。
  2. 舆情数据分析
    • Presto可以连接舆情数据库,如社交媒体、新闻网站等,实现对舆情数据的实时抓取查询和分析。
    • 通过Presto,企业可以实时监测和分析舆情动态,了解公众对企业品牌、产品和服务的看法和态度,及时回应和调整公关策略。
  3. 跨数据库分析
    • Presto支持跨数据库的查询和分析,可以将企业工商数据和舆情数据等多个数据库进行合并分析,帮助企业发现不同数据库之间的关联和趋势。
    • 通过Presto的即席查询功能,企业可以在不同数据库之间灵活进行探索和发现,发现潜在的商业机会和风险。
  4. 实时决策支持
    • 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优点
  1. 高性能:Presto相对于Hive在处理PB级数据时性能更好,因为它是基于内存运算,减少了硬盘IO操作,因此在处理某些类型的查询时速度更快。

  2. 多数据库连接:Presto能够连接多个数据库,进行跨数据库的查询和连接操作,这使得用户可以方便地从不同的数据库中获取数据进行联合分析。

  3. 部署简单:相较于Hive,Presto的部署更加简单,因为不需要先部署HDFS,这降低了部署和配置的复杂性,使得用户可以更快速地搭建起数据分析平台。

​ 多数据库连接查询:

1-4-2. Presto缺点
  1. 内存管理:尽管Presto能够处理PB级别的数据,但在一些场景下并不是将全部数据加载到内存中进行计算的。对于一些聚合运算,Presto是边读取数据边计算,因此在连表查询等情况下可能会产生大量的临时数据,导致速度变慢。

  2. 实时查询限制:虽然Presto支持实时查询,但是直接连接MySQL等数据库并不会提高查询效率,反而可能会引入网络瓶颈,导致查询速度较慢。因此在一些实时查询场景下,性能可能不如预期。

Presto在高性能、多数据库连接和部署简单等方面具有明显优势,但在内存管理和实时查询的限制方面还存在一些缺点,需要根据具体的使用场景来权衡选择。

1-4-3. Presto与竞品对比
特点PrestoHiveImpalaSpark
发布公司FacebookApacheClouderaApache
数据处理方式基于内存计算,支持实时查询和交互式分析基于MapReduce,较慢;可通过Tez或Spark提速基于MPP架构,较快的交互式SQL查询内存计算和硬盘计算混合,可处理多种数据处理任务
查询语言标准SQLHiveQL(SQL-like)SQLSpark 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都是用于大数据处理和分析的工具,它们各有优缺点,相对来说对内存要求都很高,组件的取舍取决于具体的需求和场景。

  1. 性能:Impala通常比Presto快,特别是在处理较大数据集时。这是因为Impala使用更接近传统数据库的架构,执行查询时不需要转换为MapReduce作业。

  2. 查询语法:Presto支持标准SQL,而Impala使用的是类似SQL的HiveQL。如果您更熟悉标准SQL,可能会更喜欢Presto。

  3. 扩展性:Presto的扩展性较好,可以轻松地连接多种数据库,而Impala主要适用于连接HDFS和HBase。

  4. 部署复杂度:Presto的部署相对简单,而Impala可能需要更多的配置和管理。

  5. 生态系统:Presto有一个活跃的社区和丰富的生态系统,而Impala在这方面稍显不足。

基于以上考虑因素,如果对性能要求较高且数据集较大,可能更倾向于选择Impala。但impala只能对接hive,而presto能对接很多种类的数据源,如果业务场景更偏向标准SQL、跨数据库、对扩展性要求较高或希望部署简单,则可能更适合选择Presto。

1-5. Presto强大的功能示例

通过几个示例可以更好的体会Presto的优势

  • 联合查询

假设有一个需求是要统计每个用户在不同数据库中的活动情况,包括用户信息(存储在Hive中)、订单信息(存储在MySQL中)和日志信息(存储在Elasticsearch中)。可以通过Presto进行联合查询,将这些数据库的信息合并在一起进行分析

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将数据从不同数据库中取出,进行聚合和转换

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,实时地分析和关联数据

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数据解析为表格形式,并进行进一步的分析

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成为一个强大的数据分析工具,可以处理各种数据库

SELECT * FROM s3.my_bucket.my_table;
  • 动态分区和分区裁剪

Presto支持动态分区和分区裁剪,可以根据查询条件自动选择需要查询的分区,提高查询性能。

SELECT *
FROM hive.my_table
WHERE date_column = date '2024-02-23';
  • 数据加密插件

数据加密插件来创建一个加密表。该表的数据将被加密存储,以提高数据安全性

-- 创建加密表
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系统

-- 使用用户名/密码进行认证
SET SESSION user = 'username';
SET SESSION password = 'password';

1-6. Presto常见的数据库支持

  1. Hive:基于Hadoop的数据仓库系统。
  2. MySQL:流行的关系型数据库管理系统。
  3. PostgreSQL:强大的开源关系型数据库。
  4. Elasticsearch:分布式搜索和分析引擎。
  5. Oracle:企业级关系型数据库管理系统。
  6. Cassandra:分布式NoSQL数据库管理系统。
  7. MongoDB:面向文档的NoSQL数据库管理系统。
  8. SQL Server:微软开发的关系型数据库管理系统。
  9. S3:亚马逊提供的对象存储服务。
  10. HDFS:Apache Hadoop分布式文件系统。
  11. Kafka:分布式事件流平台。
  12. Redis:内存数据库,用作缓存、消息队列等。
  13. JDBC:支持通过JDBC连接到各种关系型数据库。
  14. Avro:序列化数据格式,通常与Hadoop生态系统一起使用。
  15. Parquet:一种列式存储格式,用于大数据分析。
  16. ORC:另一种列式存储格式,用于大数据分析。
  17. Delta Lake:构建在Apache Spark之上的数据湖解决方案,支持ACID事务和增量数据加载。
  18. Greenplum:基于PostgreSQL的开源大数据分析平台。
  19. Teradata:一种用于数据仓库和分析的关系型数据库管理系统。
  20. PrestoDB:另一个分布式SQL查询引擎,可以作为Presto的数据库之一。
  21. ClickHouse:开源列式数据库管理系统,用于在线分析处理(OLAP)。
  22. MemSQL:分布式内存数据库管理系统,用于实时数据分析。
  23. Couchbase:分布式NoSQL文档数据库,用于实时数据存储和分析。
  24. Vertica:大数据分析平台,用于数据仓库和实时分析。
  25. Splunk:用于搜索、监控和分析大规模实时数据的平台。
  26. Snowflake:云数据仓库平台,支持结构化和半结构化数据的分析。
  27. DynamoDB:亚马逊提供的NoSQL数据库服务,用于实时应用程序。
  28. BigQuery:Google Cloud提供的大数据分析平台,用于处理大规模结构化数据。
  29. Azure SQL Database:微软提供的云端关系型数据库服务,用于数据存储和分析。
  30. Redshift:亚马逊提供的云端数据仓库服务,用于大规模数据分析。

2. Presto安装部署

2-1. presto集群规划与环境准备

  • 服务器
主机名角色环境要求
poc01coordinatorpython版本是2.4+ ; java版本是8u151+
poc02workerpython版本是2.4+ ; java版本是8u151+
poc03workerpython版本是2.4+ ; java版本是8u151+
  • 环境查看(各机器 )
[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

  • 下载
[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#

  • 解压
[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

  • 创建存储数据文件夹
[root@poc01 opt]# mkdir /opt/data
[root@poc01 opt]# mkdir -p /opt/data/prestodata
  • 创建配置文件目录

注意:官方的安装包默认没有etc配置文件目录,需要自行创建

[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将存储日志和其他数据

### 服务器-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解释,所以不要出现包含空格或其他特殊字符

[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

### 服务器-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

[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目录进行归档

[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-userconnection-password是连接数据库所需的用户名和密码。

< 以下这段是一个踩坑分享,安装部署可以忽略跳过下面这段 >

在配置mysql.properties时,connection-url的参数开始配置成了:

connection-url=jdbc:mysql://116.63.88.111:3306/test

在jdbc后面加上了库名: test,因平时开发习惯,jdbc后面大多场景都是跟上库名,这样配置以后,进行了服务启动报错了

2024-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服务

### 服务器-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目录进行日志写入。

日志分析路径:

[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的服务端口

[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 ]

[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

  1. Coordinator节点

    • Coordinator节点是Presto集群的中心节点,负责接收来自客户端的查询请求,并协调集群中的其他工作节点来执行这些查询。
    • 它负责解析SQL查询语句、优化查询计划、分配任务给工作节点、收集和汇总结果,并将结果返回给客户端。
    • discovery server ,负责维护Coordinator和worker节点的关系,worker节点启动后向discovery service服务注册,Coordinator通过discovery service获取注册的worker节点以及catalog,通常内嵌于Coordinator节点中。

    Coordinator节点:Coordinator节点就像是一个指挥中心,负责接收指令(查询请求),并协调工作人员(Worker节点)来执行任务。

  2. Worker节点

    • Worker节点是Presto集群中的工作节点,负责实际执行查询任务。
    • 每个Worker节点都运行着一个Presto进程,该进程负责执行查询计划中的特定任务,如扫描数据、过滤数据、聚合数据等。

    Worker节点:Worker节点就像是工厂里的工人,负责执行具体的任务。每个工人都有自己的工作台(Presto进程),按照指示完成任务,并将结果报告给指挥中心。

  3. 数据库连接器

    • Presto通过连接器(connector)与各种数据库进行通信,包括Hive、MySQL、PostgreSQL、Elasticsearch等。
    • 每个连接器负责实现与特定数据库的通信协议,并将数据库中的数据转换为Presto可理解的格式。

    数据库连接器:数据库连接器就像是工厂的供应链,负责与不同的供应商(数据库)进行通信,并将所需的原材料(数据)转换成工厂可以使用的格式

  4. 查询执行流程

    • 当客户端提交一个查询请求时,Coordinator节点接收到该请求并解析SQL语句。
    • 然后,Coordinator节点将查询计划分解为一系列任务,并将这些任务分配给Worker节点执行。
    • 每个Worker节点负责执行分配给它的任务,并将结果返回给Coordinator节点。
    • 最后,Coordinator节点将所有结果合并并返回给客户端。

    查询执行流程:查询执行流程就像是生产流水线,指挥中心将生产计划安排好后,工人们按照流程一步一步地完成工作,最终将成品交付给客户。

  5. 查询优化器

    • Presto具有强大的查询优化器,能够根据查询的特性和数据的分布情况生成高效的查询计划。
    • 查询优化器负责选择最佳的执行计划、重排序操作、选择合适的连接算法等,以提高查询性能。

    查询优化器:查询优化器就像是生产计划员,负责规划生产流程,安排工作顺序,以最大程度地提高生产效率。

3-2. presto几个重要点

  1. 分布式架构: Presto是一个分布式系统,由多个节点组成,包括协调器(Coordinator)和工作节点(Worker)。协调器负责接收和解析用户查询请求,生成查询计划,并协调工作节点执行任务。工作节点负责实际执行查询任务,从数据源读取数据并进行计算处理。

  2. 查询计划生成: Presto使用成本优化器(Cost-Based Optimizer)生成查询计划。优化器根据查询的复杂性、连接的表数以及数据分布等因素,选择最佳的查询计划,以提高查询性能。

    • presto对一个传入的sql语句如何进行解析并生成最终的执行计划

  3. 任务调度与并行执行: 查询计划被转换为一系列任务,这些任务被分配给工作节点并行执行。任务调度器负责将任务分配给可用的工作节点,并协调任务的执行顺序。

    • 在调度任务时,有几个决策点,第一:分配多少个任务,第二:每个任务分配到哪些机器上
    • presto提供了一种基于拓扑的调度算法(Topology Aware schedule),以使source节点尽量靠近数据

  4. 数据传输与交互: Presto使用高性能的数据传输协议在节点之间传输数据。这些协议被优化以提供低延迟和高吞吐量。节点之间通过这些协议进行数据交互,完成查询的执行和结果的传输。

  5. 元数据管理: Presto的元数据存储在内存中,包括表和列的信息。元数据管理器负责维护元数据,并在查询解析时使用元数据来了解查询需要访问哪些数据源。

  6. 查询优化与性能: Presto通过优化查询计划、并行执行任务以及高效的数据传输等技术,提高了查询性能和可扩展性。成本优化器和任务调度器在整个查询执行过程中起着关键作用,确保查询能够在分布式环境下高效执行。

  7. 容错性与健壮性: Presto具有一定的容错机制,可以处理节点故障和任务失败等情况。当发生故障时,Presto会重新分配任务并继续执行查询,以确保查询的完成和结果的正确性。

3-3. Presto数据模型

  1. Catalog(目录)

    • Catalog是Presto中的最顶层概念,类似于数据库管理系统(DBMS)中的数据库。
    • 每个Catalog对应一个数据源,可以是Hive、MySQL、PostgreSQL等。
    • Catalog包含了一组Schema,以及这些Schema中的表和视图等对象。
  2. Schema(模式)

    • Schema是Catalog中的一个逻辑概念,类似于关系数据库中的数据库(Database)。
    • 每个Schema对应一个命名空间,用于组织和管理表、视图等对象。
    • Schema可以包含多个表,每个表都有一个唯一的名称,并且属于特定的Schema。
  3. 表(Table)

    • 表是Schema中的一个基本单元,用于存储数据记录。
    • 每个表都有一个唯一的名称,并且包含多个列和多行数据。
    • 表可以来自不同的数据源,如Hive表、MySQL表等。
  4. 列(Column)

    • 列是表中的一个属性,用于存储特定类型的数据。
    • 每个列都有一个名称和数据类型,例如整数、字符串、日期等。
    • 列组成了表的结构,描述了表中每条记录的各个属性。
  5. 行(Row)

    • 行是表中的一个数据记录,包含了每个列的具体数值。
    • 每行代表了一个数据实体,例如一个用户、一笔交易等。
    • 通过查询可以检索、过滤和操作行数据。
  6. 分区(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
-- 修改schema名称
ALTER SCHEMA name RENAME TO new_name;
  • ALTER TABLE
-- 修改表名称
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
-- 分析表的统计信息
ANALYZE table_name [ WITH ( property_name = expression [, ...] ) ];
  • CALL
-- 调用存储过程
CALL procedure_name ( [ name => ] expression [, ...] );
  • COMMIT
-- 提交事务
COMMIT [ WORK ];
  • CREATE ROLE
-- 创建角色
CREATE ROLE role_name
[ WITH ADMIN ( user | USER user | ROLE role | CURRENT_USER | CURRENT_ROLE ) ];
  • CREATE SCHEMA
-- 创建schema
CREATE SCHEMA [ IF NOT EXISTS ] schema_name
[ WITH ( property_name = expression [, ...] ) ];
  • CREATE TABLE
-- 创建表
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
-- 创建视图
CREATE [ OR REPLACE ] VIEW view_name
[ SECURITY { DEFINER | INVOKER } ]
AS query;
  • DEALLOCATE PREPARE
-- 取消预处理语句
DEALLOCATE PREPARE statement_name;
  • DELETE
-- 删除数据
DELETE FROM table_name [ WHERE condition ];
  • DESCRIBE
-- 查看表结构
DESCRIBE table_name;

-- 查看预处理语句的输入参数
DESCRIBE INPUT statement_name;

-- 查看预处理语句的输出参数
DESCRIBE OUTPUT statement_name;
  • DROP
-- 删除角色
DROP ROLE role_name;

-- 删除schema
DROP SCHEMA [ IF EXISTS ] schema_name;

-- 删除表
DROP TABLE  [ IF EXISTS ] table_name;

-- 删除视图
DROP VIEW [ IF EXISTS ] view_name;
  • EXECUTE
-- 执行预处理语句
EXECUTE statement_name [ USING parameter1 [ , parameter2, ... ] ];
  • EXPLAIN
-- 解释查询计划
EXPLAIN [ ( option [, ...] ) ] statement;

-- 解释查询计划并执行
EXPLAIN ANALYZE [ VERBOSE ] statement;
  • GRANT
-- 授予用户权限
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
-- 插入数据
INSERT INTO table_name [ ( column [, ... ] ) ] query;
  • PREPARE
-- 准备预处理语句
PREPARE statement_name FROM statement;
  • RESET SESSION
-- 重置会话参数
RESET SESSION name;
RESET SESSION catalog.name;
  • REVOKE
-- 撤销用户权限
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
-- 回滚事务
ROLLBACK [ WORK ];
  • SELECT
-- 查询数据
[ 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
-- 设置角色
SET ROLE ( role | ALL | NONE );

-- 设置会话参数
SET SESSION name = expression;
SET SESSION catalog.name = expression;
  • SHOW
-- 显示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中添加配置:

        <dependency>
            <groupId>com.facebook.presto</groupId>
            <artifactId>presto-jdbc</artifactId>
            <version>0.285.1</version>
        </dependency>

java代码示例java2presto.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个包模块

# 连接工具
pip install presto-python-client
#  urllib3的高版本对OpenSSL版本要求较高
pip install urllib3==1.26.7

python代码 test_presto.py

#!/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()

执行效果如下:

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐