一 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调优参数 presto 配置_System

如果用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

presto调优参数 presto 配置_presto调优参数_02


presto调优参数 presto 配置_mysql_03

配置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=

运行起来,然后会报类找不到错误

presto调优参数 presto 配置_elasticsearch_04

我怀疑是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