1、概述
Presto是一个分布式SQL查询引擎,用于查询分布在一个或多个不同数据源中的大数据集。presto可以通过使用分布式查询,可以快速高效的完成海量数据的查询。它是完全基于内存的,所以速度非常快。presto不仅可以查询HDFS,还可以查询RDMBS数据库。
具体的介绍可以参考官方:https://prestodb.io/docs/current/overview/concepts.html
presto是facebook开源的,目前很多国内知名企业都在用如唯品会、美团、阿里。
2、部署
目前最新的版本是presto-server-0.189.tar.gz,下载地址:http://maven.aliyun.com/nexus/content/groups/public/com/facebook/presto/presto-server/
相应的cli版本presto-cli-0.189-executable.jar,下载地址:http://maven.aliyun.com/nexus/content/groups/public/com/facebook/presto/presto-cli/
下载需要的版本后,进行解压并重命名:
# tar xf presto-server-0.189.tar.gz
#mv presto-server-0.189 presto
presto集群包括coordinator(调度节点)和多个worker。 由客户端提交查询,从Presto命令行CLI提交到coordinator。 coordinator进行解析,分析并执行查询计划,然后分发处理队列到worker
presto需要一个data目录用来存放logs、etc,建议目录创建在安装目录外面,方便升级。
在安装目录中创建一个etc目录。 在这个etc目录中放入以下配置信息:
- 节点属性:每个节点的环境配置信息
- JVM 配置:JVM的命令行选项
- 配置属性:Presto server的配置信息
- Catalog属性:configuration forConnectors(数据源)的配置信息
coordinator节点:
#mkdir presto/etc
#ls presto/etc
catalog config.properties jvm.config log.properties node.properties
#cat node.properties
node.environment=huoqiu
node.id=huoqiu_coordinator
node.data-dir=/data/presto/data
- node.environment: 集群名称。所有在同一个集群中的Presto节点必须拥有相同的集群名称。
- node.id: 每个Presto节点的唯一标示。每个节点的node.id都必须是唯一的。在Presto进行重启或者升级过程中每个节点的node.id必须保持不变。如果在一个节点上安装多个Presto实例(例如:在同一台机器上安装多个Presto节点),那么每个Presto节点必须拥有唯一的node.id。
- node.data-dir: 数据存储目录的位置(操作系统上的路径)。Presto将会把日期和数据存储在这个目录下。
# cat config.properties
coordinator=true
node-scheduler.include-coordinator=false
http-server.http.port=8080
query.max-memory=3GB
query.max-memory-per-node=3GB
discovery-server.enabled=true
discovery.uri=http://192.168.1.202:8080
- coordinator:指定是否运维Presto实例作为一个coordinator(接收来自客户端的查询情切管理每个查询的执行过程)。
- node-scheduler.include-coordinator:是否允许在coordinator服务中进行调度工作。对于大型的集群,在一个节点上的Presto server即作为coordinator又作为worke将会降低查询性能。因为如果一个服务器作为worker使用,那么大部分的资源都不会被worker占用,那么就不会有足够的资源进行关键任务调度、管理和监控查询执行。
- http-server.http.port:指定HTTP server的端口。Presto 使用 HTTP进行内部和外部的所有通讯。
- query.max-memory=3GB:一个单独的任务使用的最大内存 (一个查询计划的某个执行部分会在一个特定的节点上执行)。 这个配置参数限制的GROUP BY语句中的Group的数目、JOIN关联中的右关联表的大小、ORDER BY语句中的行数和一个窗口函数中处理的行数。 该参数应该根据并发查询的数量和查询的复杂度进行调整。如果该参数设置的太低,很多查询将不能执行;但是如果设置的太高将会导致JVM把内存耗光。
- discovery-server.enabled:Presto 通过Discovery 服务来找到集群中所有的节点。为了能够找到集群中所有的节点,每一个Presto实例都会在启动的时候将自己注册到discovery服务。Presto为了简化部署,并且也不想再增加一个新的服务进程,Presto coordinator 可以运行一个内嵌在coordinator 里面的Discovery 服务。这个内嵌的Discovery 服务和Presto共享HTTP server并且使用同样的端口。
- discovery.uri:Discovery server的URI。由于启用了Presto coordinator内嵌的Discovery 服务,因此这个uri就是Presto coordinator的uri。修改example.net:8080,根据你的实际环境设置该URI。注意:这个URI一定不能以“/“结尾。
# cat jvm.config
-server
-Xmx1G
-XX:+UseG1GC
-XX:+ExplicitGCInvokesConcurrent
-XX:+CMSClassUnloadingEnabled
-XX:+AggressiveOpts
-XX:+HeapDumpOnOutOfMemoryError
-XX:OnOutOfMemoryError=kill -9 %p
-XX:ReservedCodeCacheSize=150M
# cat log.properties
com.facebook.presto=INFO
@This would set the minimum level to INFO for both com.facebook.presto.server and com.facebook.presto.hive. The default minimum level is INFO (thus the above example does not actually change anything). There are four levels: DEBUG, INFO, WARN and ERROR.
# cd catalog/
# cat hive.properties
connector.name=hive-hadoop2
hive.metastore.uri=thrift://192.168.1.202:9083
hive.config.resources=/data/hadoop-2.7.3/etc/hadoop/core-site.xml,/data/hadoop-2.7.3/etc/hadoop/hdfs-site.xml
#hive.allow-drop-table=true
# cat jmx.properties
connector.name=jmx
@Presto通过connectors访问数据。这些connectors挂载在catalogs上。 connector 可以提供一个catalog中所有的schema和表。 例如: Hive connector 将每个hive的database都映射成为一个schema, 所以如果hive connector挂载到了名为hive的catalog, 并且在hive的web有一张名为clicks的表, 那么在Presto中可以通过hive.web.clicks来访问这张表。
通过在etc/catalog目录下创建catalog属性文件来完成catalogs的注册.
worker节点:
#mkdir presto/etc
#ls presto/etc
catalog config.properties jvm.config log.properties node.properties
#cat node.properties
node.environment=huoqiu
node.id=huoqiu_worker1
node.data-dir=/data/presto/data
- node.environment: 集群名称。所有在同一个集群中的Presto节点必须拥有相同的集群名称。
- node.id: 每个Presto节点的唯一标示。每个节点的node.id都必须是唯一的。在Presto进行重启或者升级过程中每个节点的node.id必须保持不变。如果在一个节点上安装多个Presto实例(例如:在同一台机器上安装多个Presto节点),那么每个Presto节点必须拥有唯一的node.id。
- node.data-dir: 数据存储目录的位置(操作系统上的路径)。Presto将会把日期和数据存储在这个目录下。
# cat config.properties
coordinator=true node-scheduler.include-coordinator=false http-server.http.port=8082 query.max-memory=7GB query.max-memory-per-node=4GB query.client.timeout=3m query.max-length=100000000 query.min-expire-age=30m discovery-server.enabled=true discovery.uri=http://192.168.1.202:8080
- coordinator:指定是否运维Presto实例作为一个coordinator(接收来自客户端的查询情切管理每个查询的执行过程)。
- node-scheduler.include-coordinator:是否允许在coordinator服务中进行调度工作。对于大型的集群,在一个节点上的Presto server即作为coordinator又作为worke将会降低查询性能。因为如果一个服务器作为worker使用,那么大部分的资源都不会被worker占用,那么就不会有足够的资源进行关键任务调度、管理和监控查询执行。
- http-server.http.port:指定HTTP server的端口。Presto 使用 HTTP进行内部和外部的所有通讯。
- query.max-memory=3GB:一个单独的任务使用的最大内存 (一个查询计划的某个执行部分会在一个特定的节点上执行)。 这个配置参数限制的GROUP BY语句中的Group的数目、JOIN关联中的右关联表的大小、ORDER BY语句中的行数和一个窗口函数中处理的行数。 该参数应该根据并发查询的数量和查询的复杂度进行调整。如果该参数设置的太低,很多查询将不能执行;但是如果设置的太高将会导致JVM把内存耗光。
- query.max-length=100000000: 这个参数在查询和写入数据量较大的时候会用到,默认值是1000000。
- discovery-server.enabled:Presto 通过Discovery 服务来找到集群中所有的节点。为了能够找到集群中所有的节点,每一个Presto实例都会在启动的时候将自己注册到discovery服务。Presto为了简化部署,并且也不想再增加一个新的服务进程,Presto coordinator 可以运行一个内嵌在coordinator 里面的Discovery 服务。这个内嵌的Discovery 服务和Presto共享HTTP server并且使用同样的端口。
- discovery.uri:Discovery server的URI。由于启用了Presto coordinator内嵌的Discovery 服务,因此这个uri就是Presto coordinator的uri。修改example.net:8080,根据你的实际环境设置该URI。注意:这个URI一定不能以“/“结尾。
# cat jvm.config
-server -Xmx2G -XX:+UseG1GC -XX:+ExplicitGCInvokesConcurrent -XX:+CMSClassUnloadingEnabled -XX:+AggressiveOpts -XX:+HeapDumpOnOutOfMemoryError -XX:OnOutOfMemoryError=kill -9 %p -XX:ReservedCodeCacheSize=150M
# cat log.properties
com.facebook.presto=INFO
@This would set the minimum level to INFO for both com.facebook.presto.server and com.facebook.presto.hive. The default minimum level is INFO (thus the above example does not actually change anything). There are four levels: DEBUG, INFO, WARN and ERROR.
# cd catalog/
# cat hive.properties
connector.name=hive-hadoop2 hive.metastore.uri=thrift://192.168.1.202:9083 hive.config.resources=/data/hadoop-2.7.3/etc/hadoop/core-site.xml,/data/hadoop-2.7.3/etc/hadoop/hdfs-site.xml #hive.allow-drop-table=true
# cat jmx.properties
connector.name=jmx
@Presto通过connectors访问数据。这些connectors挂载在catalogs上。 connector 可以提供一个catalog中所有的schema和表。 例如: Hive connector 将每个hive的database都映射成为一个schema, 所以如果hive connector挂载到了名为hive的catalog, 并且在hive的web有一张名为clicks的表, 那么在Presto中可以通过hive.web.clicks来访问这张表。
通过在etc/catalog目录下创建catalog属性文件来完成catalogs的注册.
worker节点只需要修改node.id=huoqiu_worker1,coordinator=false。可以创建多个worker节点。
3、启动
如果连接hive metastore,需要先配置hive-site.xml
<property> <name>hive.metastore.local</name> <value>false</value> </property> <property> <name>hive.metastore.uris</name> <value>thrift://192.168.1.202:9083</value> </property>
首先要启动hive metatsore:
# nohup ./hive --service metastore >>/data/nohuo.out 2>&1 &
在安装目录下有个bin目录,有个可执行文件:
launcher
有两种启动方式:
1)./launcher run
这种方式是前台运行,日志直接输出在屏幕上。
2)./launcher start
这种方式是后台运行,会在上面配置的data(node.data-dir=/data/presto/data)生成var目录,里面是程序的日志,还有etc、plugin的软链接。
4、客户端
将下载的presto-cli-0.189-executable.jar上传至服务器,
只能连接coordinator,因为他是整个个入口:
#mv presto-cli-0.189-executable.jar presto
#chmod +x presto
#./presto --server 192.168.1.202:8080 --catalog hive --schema default
presto:default> show tables;
Table
-------
test
(1 row)
Query 20171123_163250_00025_s3abt, FINISHED, 2 nodes
Splits: 18 total, 18 done (100.00%)
0:01 [1 rows, 21B] [0 rows/s, 16B/s]
5、web
http://192.168.1.202:8080
QA:
1、最近在使用presto的时候碰到一个请求报错:
[Simba][Presto] (1060) Presto Query Error: Query text length (1012684) exceeds the maximum length (1000000) (35)
超过最大长度限制了,然而去官网并没有找到相关的参数设置,于是google一番找到一个解决方法,原来有一个可以参数可以修改这个默认值。下面给出链接:
https://github.com/prestodb/presto/pull/7001/files#diff-3ac3edac3816e47832034679379d250cR172
import io.airlift.units.Duration; import io.airlift.units.MinDuration; import javax.validation.constraints.Max; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; @@ -40,6 +41,7 @@ private int initialHashPartitions = 100; private Duration minQueryExpireAge = new Duration(15, TimeUnit.MINUTES); private int maxQueryHistory = 100; private int maxQueryLength = 1_000_000; private Duration clientTimeout = new Duration(5, TimeUnit.MINUTES); private int queryManagerExecutorPoolSize = 5; @@ -160,6 +162,20 @@ public QueryManagerConfig setMaxQueryHistory(int maxQueryHistory) return this; } @Min(0) @Max(1_000_000_000) public int getMaxQueryLength() { return maxQueryLength; } @Config("query.max-length") public QueryManagerConfig setMaxQueryLength(int maxQueryLength) { this.maxQueryLength = maxQueryLength; return this; } @MinDuration("5s") @NotNull public Duration getClientTimeout()
有一个 query.max-length的配置可以修改那个默认值,在配置文件config.properties文件里面添加这个配置,重启presto server生效,再次尝试发现问题解决了。
coordinator=true node-scheduler.include-coordinator=false http-server.http.port=8082 query.max-memory=7GB query.max-memory-per-node=4GB query.client.timeout=3m query.max-length=100000000 query.min-expire-age=30m discovery-server.enabled=true discovery.uri=http://192.168.1.202:8080
2、升级presto到0.218版本后,使用presto查询的时候总是报错:
Presto Upgraded to 0.218 Version, Corrupted statistics for column "[nickname] BINARY" in Parquet file
原因是存储的parquet文件有部分是损坏的,而presto在0.216开始添加了一个文件完整性检测,这个默认是开启的,可以直接关掉:
# vim catalog/hive.properties
hive.parquet.fail-on-corrupted-statistics=false
重启服务即可解决。