一 presto安装
1.安装前提
Linux Java8_64
2.安装分布
node01 | node02 | ||
协调者coordinator | √ | ||
workers | √ | ||
客户端 | √ |
3.详细步奏
3.1 下载
先从官网下载得到https://prestodb.io/docs/current/installation.html
得到服务端和客户端
presto-server-0.271tar.gz
presto-cli-0.271-executable.jar
3.2 解压后配置
在presto-server-0.271下创建etc进行配置,下面这些配置都是在etc目录下
vim node.properties 主要是节点配置
# 环境名称。集群中的所有Presto节点必须具有相同的环境名称。
node.environment=production
# 此Presto安装的唯一标识符不能重复
node.id=presto-1
# 数据目录的位置(文件系统路径)。Presto将在这里存储日志和其他数据。注意要先创建data/presto这个文件夹
node.data-dir=/data/xmt/data/presto
vim jvm Config
-server
-Xmx16G
-XX:+UseG1GC
-XX:G1HeapRegionSize=32M
-XX:+UseGCOverheadLimit
-XX:+ExplicitGCInvokesConcurrent
-XX:+HeapDumpOnOutOfMemoryError
-XX:+ExitOnOutOfMemoryError
-XX:ReservedCodeCacheSize=256M
因为OutOfMemoryError
通常会使 JVM 处于不一致的状态,所以编写了一个堆转储(用于调试)并在发生这种情况时强制终止进程。具体的内存配置大小可以根据机器的内存大小设置,用命令free -g查看,不宜设置过大,也不能太小。目前我设置-Xmx为5G,因为是测试。
vim config.properties
# 允许这个Presto实例充当协调器;true:协调者,false:表示workers
coordinator=true
# 这个就是说允不允许这个coordinator充当worker
node-scheduler.include-coordinator=true
# 指定HTTP服务器的端口。Presto使用HTTP进行所有内部和外部通信。
http-server.http.port=8091
# 查询可能使用的最大分布式内存量
query.max-memory=5GB
# 查询可在任何一台计算机上使用的最大用户内存量
query.max-memory-per-node=1GB
# 查询可在任何一台机器上使用的最大用户和系统内存量,其中系统内存是读取器、写入器和网络缓冲区等执行过程中使用的内存。
query.max-total-memory-per-node=2GB
# Presto使用发现服务查找集群中的所有节点。每个Presto实例将在启动时向DiscoveryService注册。为了简化部署和避免运行额外的服务,Presto协调器可以运行发现服务的嵌入式版本。它与Presto共享HTTP服务器,因此使用相同的端口。
discovery-server.enabled=true
# 访问地址;发现号服务器的URI
discovery.uri=http://ip:8091
上面这个端口号是随便写的,放到生产的话,建议还是改一下,
vim log.properties
com.facebook.presto=INFO
设置日志级别 INFO、DEBUG、ERROR。
4.配置多数据源catalog
还是在etc目录下(注意不是根目录的etc)
4.1 mysql
vim catalog/mysql.properties
connector.name=mysql
connection-url=jdbc:mysql://ip:3306
connection-user=root
connection-password=password
注意 命名可以随便命名,如devmysql.properties ,但是必须 .properties结尾,这也就是说,可以配置多个mysql,或者多个redis数据源
4.2 redis
vim redis.properties
connector.name=redis
redis.nodes=ip:6379
redis.password=
redis.key-delimiter=:
redis.key-prefix-schema-table=false
redis.hide-internal-columns=false
redis.table-names=user_profile.user_info,schema1.redishash
redis中的配置参数挺多的,具体可以看官网,redis.key-prefix-schema-table=false,这个要配置,否则查询到的redis不是全局,而是某个key.
presto 对于redis目前只支持的有两种 String 和 hash,配置映射文件 /presto-server-0.271/etc 在这个目录下创建 redis目录,在redis目录下,配置映射文件,如 vim redis1.json 简单说下,下面这个json,主要对应的是redis存储的hash类型,tablename就是表名,schemaName是数据库名,key的对应的是 (hset key1 key2 value)对应的是key1 ,value对应的是value,dataFormat可以有很多,比如说 json csv hash
{
"tableName": "user_info",
"schemaName": "user_profile",
"key": {
"dataFormat": "raw",
"fields": [
{
"name": "redis_key",
"type": "varchar",
"hidden": "false"
}
]
},
"value": {
"dataFormat": "hash",
"fields": [
{
"name": "name",
"type": "varchar",
"mapping": "name"
},{
"name": "age",
"type": "int",
"mapping": "age"
},{
"name": "id",
"type": "int",
"mapping": "id"
}
]
}
}
下面这个是String的配置
第一种,把set key value中的value解析成字符串
{
"tableName": "test",
"schemaName": "default",
"key": {
"dataFormat": "raw",
"fields": [
{
"name":"redis_key",
"type":"VARCHAR",
"hidden":"false"
}
]
},
"value": {
"dataFormat": "json",
"fields": [
{
"name":"row_number",
"mapping":"rowNumber",
"type":"BIGINT"
},
{
"name":"customer_key",
"mapping":"customerKey",
"type":"BIGINT"
},
{
"name":"name",
"mapping":"name",
"type":"VARCHAR"
}
]
}
}
第二种,不解析value
{
"tableName": "simple",
"schemaName": "default",
"key": {
"dataFormat": "raw",
"fields": [
{
"name":"redis_key",
"type":"VARCHAR",
"hidden":"false"
}
]
},
"value": {
"dataFormat": "raw",
"fields": [
{
"name":"redis_value",
"type":"VARCHAR"
}
]
}
}
二 运行
1.服务端
服务端先后运行 先运行coordinator后运行workers
/xmt/libs/presto/presto-server-0.271/bin/launcher start 日志打印在/xmt/data/prosto
/xmt/libs/presto/presto-server-0.271/bin/launcher stop
/xmt/libs/presto/presto-server-0.271/bin/launcher run 日志打印到控制台
服务端启动后 discovery.uri=http://ip:8091/ui/# ,可以看你在config.properties那个文件里配置的网址,进行看下运行情况。
2.客户端 (通过presto-cli.jar连接,注意这个版本要和presto版本一致都是0.271)
启动mysql为例:
/xmt/libs/presto/presto-server-0.271/presto-cli.jar --server ip:8091 --catalog mysql(你在catalog下配置的文件名) --schema dc_indexs(你在.properties中配置的数据库名称)
当你连接上后,发现,所有数据库都可以访问,并不仅仅有启动这一个。
启动多数据源join:
./presto-cli.jar --server ip:8091 --catalog system --schema runtime
runtime 就是默认的数据库,system就是默认的数据源,可以理解为所有数据源 ,使用sql时 要用 数据源.数据库.表 ,不能只写表命。比如
select a.id,a.title,b.name from mysql61.vueblog.m_blog a left join redis.user_profile.user_info as b on a.id = b.id;
三 IDEA的连接
引入依赖
<dependency>
<groupId>com.facebook.presto</groupId>
<artifactId>presto-jdbc</artifactId>
<version>0.212</version>
</dependency>
然后向连接mysql一样的代码就差不多了,区别是这里的用户名随便写,密码为空,要不然报SSL错误,程序不会验证账户密码,主要是为了对应Connection的格式
public class Demo {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
Class.forName("com.facebook.presto.jdbc.PrestoDriver");
//system是指默认的catalog内所有的源数据连接,runtime是数据源中默认的schema
//用户随便写,密码为空,否则SSL错误,presto是不会比较用户密码的,所以这样很不安全,当然要配置的话,也是可以的。
Connection connection= DriverManager.getConnection("jdbc:presto://ip:8091/system/runtime","root","");
Statement statement=connection.createStatement();
ResultSet resCatalog=statement.executeQuery("select * from redis.user_profile.user_info");
while(resCatalog.next()){
System.out.println(resCatalog.getString(1));
System.out.println(resCatalog.getString(2));
System.out.println(resCatalog.getString(3));
}
ResultSet resultSet = statement.executeQuery("select * from mysql61.vueblog.m_blog a right join redis.user_profile.user_info b on a.id = b.id");
while(resultSet.next()){
System.out.println(resultSet.getString(1));
System.out.println(resultSet.getString(2));
System.out.println(resultSet.getString(3));
System.out.println(resultSet.getString(4));
System.out.println(resultSet.getString(5));
System.out.println(resultSet.getString(6));
System.out.println(resultSet.getString(7)); System.out.println(resultSet.getString(8)); System.out.println(resultSet.getString(9));
}
resCatalog.close();
resultSet.close();
connection.close();
}
}
##四 踩坑
连接redis
面临的问题是 .json文件映射问题 还有redis不支持集群(最新版0.271)。
首先只能映射String和hash
第二hash的存放规则 你要 hset 数据库名:表名:test1 age 1 这样存才能映射(就是说 json映射文件中 ,key的值是 数据库名:表名:test1 value的值是 age 1)hash说实话就是<key,map>类型,要想presto连接redis,map你就必须像上面说的那样存,而不能这样存,像这样存得话,你就咋也映射不了。
如果用presto 查询redis查找的数据不全
按照规定 hset 数据库名:表名:key value 安装好后,发现查数据,发现数据不全。
在redis.propertise中加入下面这个参数。
redis.key-prefix-schema-table#
如果为 true,则仅schema-name:table-name:扫描以 为前缀的键以查找表,并且将过滤掉所有其他键。如果为 false,则扫描所有键。请注意,如果架构名称是默认架构,那么要扫描的前缀就是table-name:.
连接ES
两个问题:
1集群不能像redis那样配了
一个.properties只能配置一个es地址(我采用的是,我有三个presto,三个es,这时候,我把worker中的地址配成其他的ES)
2 账户密码
ES一般公司都设置的有账户密码,但是persto没有这两个参数,所以presto是垃圾,presto有个分支Trino
https://trino.io/docs/current/connector.html 这个可以配置ES密码账户,但是它要想连接clickhouse啥的只支持jdk11 以上。而大部分我们公司用的都是jdk1.8
连接clickhouse
presto不支持的,trino可以,但是如果你非要用presto,就把下面这个下载了。
https://github.com/zeeshanabid94/presto/tree/presto-clickhouse/presto-clickhouse
配置Plugin是为了让presto识别,所以运行jar包的时候说没有找到clickhouse,就是这配置的不对,注意META-INF.services是两个目录
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.facebook.test</groupId>
<artifactId>presto-clickhouse</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!--- Clickhouse JDBC Driver -->
<dependency>
<groupId>ru.yandex.clickhouse</groupId>
<artifactId>clickhouse-jdbc</artifactId>
<version>0.1.50</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.7</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.airlift</groupId>
<artifactId>log</artifactId>
<version>0.178</version>
</dependency>
<dependency>
<groupId>io.airlift</groupId>
<artifactId>configuration</artifactId>
<version>0.178</version>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>24.1-jre</version>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>com.facebook.presto</groupId>
<artifactId>presto-spi</artifactId>
<version>0.224</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>io.airlift</groupId>
<artifactId>slice</artifactId>
</exclusion>
<exclusion>
<groupId>io.airlift</groupId>
<artifactId>units</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.facebook.presto</groupId>
<artifactId>presto-base-jdbc</artifactId>
<version>0.224</version>
<exclusions>
<exclusion>
<groupId>com.facebook.presto</groupId>
<artifactId>presto-spi</artifactId>
</exclusion>
<exclusion>
<groupId>io.airlift</groupId>
<artifactId>slice</artifactId>
</exclusion>
<exclusion>
<groupId>io.airlift</groupId>
<artifactId>units</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.airlift</groupId>
<artifactId>slice</artifactId>
<version>0.34</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.airlift</groupId>
<artifactId>units</artifactId>
<version>1.3</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
<version>2.1.5</version>
<configuration>
<!-- ".git"文件路径;默认值:${project.basedir}/.git; -->
<dotGitDirectory>${project.basedir}/.git</dotGitDirectory>
<!--若项目打包类型为pom,是否取消构建;默认值:true;-->
<skipPoms>false</skipPoms>
<!--是否生成"git.properties"文件;默认值:false;-->
<generateGitPropertiesFile>true</generateGitPropertiesFile>
<!--指定"git.properties"文件的存放路径(相对于${project.basedir}的一个路径);-->
<generateGitPropertiesFilename>/src/main/resource/git.properties</generateGitPropertiesFilename>
<!--".git"文件夹未找到时,构建是否失败;若设置true,则构建失败;若设置false,则跳过执行该目标;默认值:true;-->
<failOnNoGitDirectory>true</failOnNoGitDirectory>
<!--git描述配置,可选;由JGit提供实现;-->
<gitDescribe>
<!--是否生成描述属性-->
<skip>false</skip>
<!--提交操作未发现tag时,仅打印提交操作ID,-->
<always>false</always>
<!--提交操作ID显式字符长度,最大值为:40;默认值:7;
0代表特殊意义;后面有解释;
-->
<abbrev>7</abbrev>
<!--构建触发时,代码有修改时(即"dirty state"),添加指定后缀;默认值:"";-->
<dirty>-dirty</dirty>
<!--always print using the "tag-commits_from_tag-g_commit_id-maybe_dirty" format, even if "on" a tag.
The distance will always be 0 if you're "on" the tag.
-->
<forceLongFormat>false</forceLongFormat>
</gitDescribe>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<finalName>presto-clickhouse-0.223</finalName>
</build>
</project>
打成jar包放到presto-server-0.271/plugin/clickhouse下面然后配置
catalog/clickhouse.properties
connector.name=clickhouse
connection-url=jdbc:clickhouse://ip:8123
connection-user=
connection-password=
运行起来,然后会报类找不到错误
我怀疑是persto的版本太新了,然后找不到类,最终连接clickhouse失败。
总结
presto 真的不行,连redis时的hash要按照固定格式,连ES,ES不能有密码,而且集群模式,让worker对应一个ES的机器吗?worker如果和ES数量不相等怎么配置,连clickhouse,配不好呀,类找不到。外网都找遍了还没找到那个类。
所以,建议直接用trino 他是presto的一个分支吧。但是最新版的最差的jdk都得11以上,如果jdk1.8的公司也不要着急,在trino的启动bin/lanch中配置11的环境就可以了。所以presto一般人玩不了,直接用trino一步到位
https://trino.io/docs/current/connector.html