一、Presto简介
1、PRESTO是什么?
Presto是一个开源的分布式SQL查询引擎,适用于交互式分析查询,数据量支持GB到PB字节。
Presto的设计和编写完全是为了解决像Facebook这样规模的商业数据仓库的交互式分析和处理速度的问题。
2、它可以做什么?
Presto支持在线数据查询,包括Hive, Cassandra, 关系数据库以及专有数据存储。一条Presto查询可以将多个数据源的数据进行合并,可以跨越整个组织进行分析。
Presto以分析师的需求作为目标,他们期望响应时间小于1秒到几分钟。 Presto终结了数据分析的两难选择,要么使用速度快的昂贵的商业方案,要么使用消耗大量硬件的慢速的“免费”方案。
3、介绍
Presto是一个运行在多台服务器上的分布式系统。 完整安装包括一个coordinator和多个worker。 由客户端提交查询,从Presto命令行CLI提交到coordinator。 coordinator进行解析,分析并执行查询计划,然后分发处理队列到worker。
4、需求
Presto的基本需求
Linux or Mac OS X
Java 8, 64-bit
Python 2.4+
5、连接器
Presto支持插接式连接器提供的数据。 各连接器的设计需求会有所不同。
HADOOP / HIVE
Presto支持从以下版本的Hadoop中读取Hive数据:
Apache Hadoop 1.x
Apache Hadoop 2.x
Cloudera CDH 4
Cloudera CDH 5
支持以下文件类型:Text, SequenceFile, RCFile, ORC
此外,需要有远程的Hive元数据。 不支持本地或嵌入模式。 Presto不使用MapReduce,只需要HDFS。
二、Presto安装部署
1、下载presto tar包:
https://repo1.maven.org/maven2/com/facebook/presto/presto-server/0.189/presto-server-0.189.tar.gz
2、将下载的presto tar包通过ftp工具上传到linux服务器上,然后解压安装文件。
tar -zxvf presto-server-0.189.tar.gz -C /opt/cdh-5.3.6/
chown -R hadoop:hadoop /opt/cdh-5.3.6/presto-server-0.189/
3、配置presto
分别执行以下步骤:
在安装目录中创建一个etc目录。 在这个etc目录中放入以下配置信息:
l 节点属性:每个节点的环境配置信息
l JVM 配置:JVM的命令行选项
l 配置属性:Presto server的配置信息
l Catalog属性:configuration forConnectors(数据源)的配置信息
1)Node Properties
节点属性配置文件:etc/node.properties包含针对于每个节点的特定的配置信息。 一个节点就是在一台机器上安装的Presto实例。 这份配置文件一般情况下是在Presto第一次安装的时候,由部署系统创建的。 一个etc/node.properties配置文件至少包含如下配置信息:
node.environment=production
node.id=ffffffff-ffff-ffff-ffff-ffffffffffff
node.data-dir=/var/presto/data
针对上面的配置信息描述如下:
node.environment: 集群名称。所有在同一个集群中的Presto节点必须拥有相同的集群名称。
node.id: 每个Presto节点的唯一标示。每个节点的node.id都必须是唯一的。在Presto进行重启或者升级过程中每个节点的node.id必须保持不变。如果在一个节点上安装多个Presto实例(例如:在同一台机器上安装多个Presto节点),那么每个Presto节点必须拥有唯一的node.id。
node.data-dir: 数据存储目录的位置(操作系统上的路径)。Presto将会把日期和数据存储在这个目录下。
2)JVM配置
JVM配置文件,etc/jvm.config, 包含一系列在启动JVM的时候需要使用的命令行选项。这份配置文件的格式是:一系列的选项,每行配置一个单独的选项。由于这些选项不在shell命令中使用。 因此即使将每个选项通过空格或者其他的分隔符分开,java程序也不会将这些选项分开,而是作为一个命令行选项处理。(就想下面例子中的OnOutOfMemoryError选项)。
一个典型的etc/jvm.config配置文件如下:
-server
-Xmx16G
-XX:+UseG1GC
-XX:G1HeapRegionSize=32M
-XX:+UseGCOverheadLimit
-XX:+ExplicitGCInvokesConcurrent
-XX:+HeapDumpOnOutOfMemoryError
-XX:+ExitOnOutOfMemoryError
由于OutOfMemoryError将会导致JVM处于不一致状态,所以遇到这种错误的时候我们一般的处理措施就是将dump headp中的信息(用于debugging),然后强制终止进程。
Presto会将查询编译成字节码文件,因此Presto会生成很多class,因此我们我们应该增大Perm区的大小(在Perm中主要存储class)并且要允许Jvm class unloading。
3)Config Properties
Presto的配置文件:etc/config.properties包含了Presto server的所有配置信息。 每个Presto server既是一个coordinator也是一个worker。 但是在大型集群中,处于性能考虑,建议单独用一台机器作为 coordinator。
一个coordinator的etc/config.properties应该至少包含以下信息:
coordinator=true
node-scheduler.include-coordinator=false
http-server.http.port=8080
query.max-memory=50GB
query.max-memory-per-node=1GB
discovery-server.enabled=true
discovery.uri=http://example.net:8080
以下是最基本的worker配置:
coordinator=false
http-server.http.port=8080
query.max-memory=50GB
query.max-memory-per-node=1GB
discovery.uri=http://example.net:8080
但是如果你用一台机器进行测试,那么这一台机器将会即作为coordinator,也作为worker。配置文件将会如下所示:
coordinator=true
node-scheduler.include-coordinator=true
http-server.http.port=8080
query.max-memory=5GB
query.max-memory-per-node=1GB
discovery-server.enabled=true
discovery.uri=http://example.net:8080
对配置项解释如下:
coordinator:指定是否运维Presto实例作为一个coordinator(接收来自客户端的查询情切管理每个查询的执行过程)。
node-scheduler.include-coordinator:是否允许在coordinator服务中进行调度工作。对于大型的集群,在一个节点上的Presto server即作为coordinator又作为worke将会降低查询性能。因为如果一个服务器作为worker使用,那么大部分的资源都不会被worker占用,那么就不会有足够的资源进行关键任务调度、管理和监控查询执行。
http-server.http.port:指定HTTP server的端口。Presto 使用 HTTP进行内部和外部的所有通讯。
task.max-memory=1GB:一个单独的任务使用的最大内存 (一个查询计划的某个执行部分会在一个特定的节点上执行)。 这个配置参数限制的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一定不能以“/“结尾。
4)日志级别
日志配置文件:etc/log.properties。在这个配置文件中允许你根据不同的日志结构设置不同的日志级别。每个logger都有一个名字(通常是使用logger的类的全标示类名). Loggers通过名字中的“.“来表示层级和集成关系。 (像java里面的包). 如下面的log配置信息:
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.
5)Catalog Properties
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的注册。 例如:可以先创建一个etc/catalog/jmx.properties文件,文件中的内容如下,完成在jmxcatalog上挂载一个jmxconnector:
connector.name=jmx
查看Connectors的详细配置选项。
4、运行Presto
在安装目录的bin/launcher文件,就是启动脚本。Presto可以使用如下命令作为一个后台进程启动:
bin/launcher start
另外,也可以在前台运行, 日志和相关输出将会写入stdout/stderr(可以使用类似daemontools的工具捕捉这两个数据流):
bin/launcher run
运行bin/launcher–help,Presto将会列出支持的命令和命令行选项。 另外可以通过运行bin/launcher–verbose命令,来调试安装是否正确。
启动完之后,日志将会写在var/log目录下,该目录下有如下文件:
launcher.log: 这个日志文件由launcher创建,并且server的stdout和stderr都被重定向到了这个日志文件中。 这份日志文件中只会有很少的信息,包括:
在server日志系统初始化的时候产生的日志和JVM产生的诊断和测试信息。
server.log: 这个是Presto使用的主要日志文件。一般情况下,该文件中将会包括server初始化失败时产生的相关信息。这份文件会被自动轮转和压缩。
http-request.log: 这是HTTP请求的日志文件,包括server收到的每个HTTP请求信息,这份文件会被自动轮转和压缩。
三、部署presto client
1、下载:
https://repo1.maven.org/maven2/com/facebook/presto/presto-cli/0.189/presto-cli-0.189-executable.jar
上传linux服务器上,重命名为presto:
$mv presto-cli-0.189-executable.jar presto
$chmod a+x presto
执行以下命令:
$ ./presto --server localhost:8080 --catalog hive --schema default
四、proste连接hive
1、编辑hive-site.xml文件,增加以下内容:
<property>
<name>hive.server2.thrift.port</name>
<value>10000</value>
</property>
<property>
<name>hive.server2.thrift.bind.host</name>
<value>chavin.king</value>
</property>
<property>
<name>hive.metastore.uris</name>
<value>thrift://chavin.king:9083</value>
</property>
2、启动hiveserver2和hive元数据服务:
bin/hive --service hiveserver2 &
bin/hive --service matestore &
3、配置hive插件,etc/catalog目录下创建hive.properties文件,输入如下内容。
3.1)hive配置:
connector.name=hive-hadoop2 #这个连接器的选择要根据自身集群情况结合插件包的名字来写
hive.metastore.uri=thrift://chavin.king:9083 #修改为 hive-metastore 服务所在的主机名称,这里我是安装在master节点
3.2)HDFS Configuration:
如果hive metastore的引用文件存放在一个存在联邦的HDFS上,或者你是通过其他非标准的客户端来访问HDFS集群的,请添加以下配置信息来指向你的HDFS配置文件:
hive.config.resources=/etc/hadoop/conf/core-site.xml,/etc/hadoop/conf/hdfs-site.xml
大多数情况下,Presto会在安装过程中自动完成HDFS客户端的配置。 如果确实需要特殊配置,只需要添加一些额外的配置文件,并且需要指定这些新加的配置文件。 建议将配置文件中的配置属性最小化。尽量少添加一些配置属性,因为过多的添加配置属性会引起其他问题。
3.3)Configuration Properties
Property Name |
Description |
Example |
hive.metastore.uri |
The URI of the Hive Metastore to connect to using the Thrift protocol. This property is required. |
thrift://192.0.2.3:9083 |
hive.config.resources |
An optional comma-separated list of HDFS configuration files. These files must exist on the machines running Presto. Only specify this if absolutely necessary to access HDFS. |
/etc/hdfs-site.xml |
hive.storage-format |
The default file format used when creating new tables |
RCBINARY |
hive.force-local-scheduling |
Force splits to be scheduled on the same node as the Hadoop DataNode process serving the split data. This is useful for installations where Presto is collocated with every DataNode. |
true |
4、presto连接hive schema,注意presto不能进行垮库join操作,测试结果如下:
$ ./presto --server localhost:8080 --catalog hive --schema chavin
presto:chavin> select * from emp;
empno | ename | job | mgr | hiredate | sal | comm | deptno
-------+--------+-----------+------+------------+--------+--------+--------
7369 | SMITH | CLERK | 7902 | 1980/12/17 | 800.0 | NULL | 20
7499 | ALLEN | SALESMAN | 7698 | 1981/2/20 | 1600.0 | 300.0 | 30
7521 | WARD | SALESMAN | 7698 | 1981/2/22 | 1250.0 | 500.0 | 30
7566 | JONES | MANAGER | 7839 | 1981/4/2 | 2975.0 | NULL | 20
7654 | MARTIN | SALESMAN | 7698 | 1981/9/28 | 1250.0 | 1400.0 | 30
7698 | BLAKE | MANAGER | 7839 | 1981/5/1 | 2850.0 | NULL | 30
7782 | CLARK | MANAGER | 7839 | 1981/6/9 | 2450.0 | NULL | 10
7788 | SCOTT | ANALYST | 7566 | 1987/4/19 | 3000.0 | NULL | 20
7839 | KING | PRESIDENT | NULL | 1981/11/17 | 5000.0 | NULL | 10
7844 | TURNER | SALESMAN | 7698 | 1981/9/8 | 1500.0 | 0.0 | 30
7876 | ADAMS | CLERK | 7788 | 1987/5/23 | 1100.0 | NULL | 20
7900 | JAMES | CLERK | 7698 | 1981/12/3 | 950.0 | NULL | 30
7902 | FORD | ANALYST | 7566 | 1981/12/3 | 3000.0 | NULL | 20
7934 | MILLER | CLERK | 7782 | 1982/1/23 | 1300.0 | NULL | 10
(14 rows)
Query 20170711_081802_00002_ydh8n, FINISHED, 1 node
Splits: 17 total, 17 done (100.00%)
0:05 [14 rows, 657B] [2 rows/s, 130B/s]
presto:chavin>
五、JDBC驱动
通过使用JDBC驱动,可以访问Presto。下载presto-jdbc-0.100.jar并将这个jar文件添加到你的java应用程序的classpath中,Presto支持的URL格式如下:
jdbc:presto://host:port
jdbc:presto://host:port/catalog
jdbc:presto://host:port/catalog/schema
例如,可以使用下面的URL来连接运行在example.net服务器8080端口上的Presto的hive catalog中的sales schema:
jdbc:presto://example.net:8080/hive/sales
六、presto管理之队列配置
排队规则定义在一个Json文件中,用于控制能够提交给Presto的查询的个数,以及每个队列中能够同时运行的查询的个数。用config.properties中的query.queue-config-file来指定Json配置文件的名字。
排队规则如果定义了多个队列,查询会按顺序依次进入不同的队列中。排队规则将按照顺序进行处理,并且使用第一个匹配上的规则。在以下的配置例子中,有5个队列模板,在user.${USER}队列中,${USER}表示着提交查询的用户名。同样的${SOURCE}表示提交查询的来源。
同样有五条规则定义了哪一类查询会进入哪一个队列中:
第一条规则将使bob成为管理员,bob提交的查询进入admin队列。
第二条规则表示,所有使用了experimental_big_querysession参数并且来源包含pipeline的查询将首先进入 用户的个人队列中,然后进入pipeline队列,最后进入big队列中。当一个查询进入一个新的队列后,直到查询结束 才会离开之前的队列。
第三条规则同上一条类似,但是没有experimental_big_query的要求,同时用global队列替换了big队列。
最后两条规则跟以上两条规则类似,但是没有了pipeline来源的要求。
所有这些规则实现了这样的策略,bob是一个管理员,而其他用户需要遵循以下的限制:
每个用户最多能同时运行5个查询。
big查询同时只能运行一个
最多能同时运行10个pipeline来源的查询。
最多能同时运行100个非big查询
{
"queues": {
"user.${USER}": {
"maxConcurrent": 5,
"maxQueued": 20
},
"pipeline": {
"maxConcurrent": 10,
"maxQueued": 100
},
"admin": {
"maxConcurrent": 100,
"maxQueued": 100
},
"global": {
"maxConcurrent": 100,
"maxQueued": 1000
},
"big": {
"maxConcurrent": 1,
"maxQueued": 10
}
},
"rules": [
{
"user": "bob",
"queues": ["admin"]
},
{
"session.experimental_big_query": "true",
"source": ".*pipeline.*",
"queues": [
"user.${USER}",
"pipeline",
"big"
]
},
{
"source": ".*pipeline.*",
"queues": [
"user.${USER}",
"pipeline",
"global"
]
},
{
"session.experimental_big_query": "true",
"queues": [
"user.${USER}",
"big"
]
},
{
"queues": [
"user.${USER}",
"global"
]
}
]
}
七、presto连接mysql数据库
1、在etc/catalog目录下创建文件mysql.properties,输入如下内容,保存退出。
connector.name=mysql
connection-url=jdbc:mysql://example.net:3306
connection-user=root
connection-password=secret
2、presto客户端连接mysql服务并执行查询:
$ ./presto --server localhost:8080 --catalog mysql --schema chavin
presto:chavin> select * from mysql.chavin.emp;
empno | ename | job | mgr | hiredate | sal | comm | deptno
-------+--------+-----------+------+------------+--------+--------+--------
7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.0 | NULL | 20
7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.0 | 300.0 | 30
7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.0 | 500.0 | 30
7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.0 | NULL | 20
7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.0 | 1400.0 | 30
7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.0 | NULL | 30
7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.0 | NULL | 10
7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.0 | NULL | 20
7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.0 | NULL | 10
7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.0 | 0.0 | 30
7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.0 | NULL | 20
7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.0 | NULL | 30
7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.0 | NULL | 20
7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.0 | NULL | 10
(14 rows)
Query 20170711_085557_00002_hpvqh, FINISHED, 1 node
Splits: 17 total, 17 done (100.00%)
0:00 [14 rows, 0B] [28 rows/s, 0B/s]
八、presto连接postgresql
1、在etc/catalog目录下创建文件postgresql.properties文件,添加如下内容:
connector.name=postgresql
connection-url=jdbc:postgresql://example.net:5432/database
connection-user=root
connection-password=secret
2、通过presto客户端查询postgresql数据库:
$ ./presto --server localhost:8080 --catalog postgresql --schema postgres
附:
参考文档:https://prestodb.io/docs/current/