PrestoOnYarn搭建及其问题解决方案总结

Presto搭建整合流程总结

一、环境准备

本次搭建内容是: presto on yarn + kerberos 整合

本次presto集群搭建过程基于一下环境:

  • hadoop版本: hadoop-2.7.3
  • presto版本:0.223
  • slider版本: slider-0.91.0-incubating
  • jdk版本: jdk1.8.0_181

注意,jdk版本要求在jdk1.8_151以上,否则可能会出现bug:

Java HotSpot™ 64-Bit Server VM warning: CMSFullGCsBeforeCompaction is deprecated and will likely be removed in a future release.
Presto requires Java 8u151+ (found 1.8.0_144)

搭建前期说明

  • hadoop集群jdk版本低的问题,可以尝试将高版本jdk打包到prestoServer中去(后面说),这是prestoServer启动的时候用自带的jdk而不是系统本地的;

  • 配置文件也可以和prestoServer一起打包,不使用appConfig.conf这种方式配置

  • presto on yarn这种方式,我们只部署worker节点;coordinator单独找一台物理机部署

    原因:coordinator on yarn的方式会出现coordinator不知道会被yarn启动到哪台机器,导致dicovery.uri指向的host不确定出现worker连接不上coordinator的情况。为处理这种情况,采用此策略。后续会补充其余两种策略也可以处理这种情况。

二、开始搭建
2.1、presto-yarn的配置

step1: 我们要下载presto-yarn的安装包:

git clone https://github.com/prestodb/presto-yarn.git

这里我挑选了测试环境hadoop集群的test-32-201.bd.com进行部署安装,路径:/opt/presto/presto-yarn

[root@test-32-201 presto-yarn]# ll
total 32
-rw-r--r-- 1 root root 7346 Sep 17 10:03 mvnw
-rw-r--r-- 1 root root 6747 Sep 17 10:07 pom.xml
drwxr-xr-x 4 root root 4096 Sep 17 10:14 presto-yarn-docs
drwxr-xr-x 4 root root 4096 Sep 27 17:38 presto-yarn-package
drwxr-xr-x 6 root root 4096 Sep 17 10:11 presto-yarn-test
-rw-r--r-- 1 root root 2520 Sep 17 10:03 README.md

step2: 修改上面的pom.xml文件 ,改下presto版本和slider版本

<presto.version>0.223</presto.version>
<slider.version>0.91.0-incubating</slider.version>

step3: 退出pom.xml编辑,进入下面的目录

cd  /opt/presto/presto-yarn/presto-yarn-package/src/main/slider/package/scripts

configure.py文件内容改成下面:

#!/usr/bin/env python

from resource_management import *
import ast, os, shutil

def set_configuration(component=None):

    import params

    if (os.path.exists(format("{data_dir}"))):
        shutil.rmtree(format("{data_dir}"))

    if (os.path.lexists(format("{conf_dir}"))):
        os.remove(format("{conf_dir}"))

    _directory(params.pid_dir, params)
    _directory(params.log_dir, params)
 

    if params.addon_plugins:
        plugins_dict = ast.literal_eval(params.addon_plugins)
        for key, value in plugins_dict.iteritems():
            plugin_dir = os.path.join(params.presto_plugin_dir, key)
            if not os.path.exists(plugin_dir):
                os.makedirs(plugin_dir)
            for jar in value:
                shutil.copy2(os.path.join(params.source_plugin_dir, jar), plugin_dir)
            
def _directory(path, params):
    Directory(path,
              owner=params.presto_user,
              group=params.user_group,
              recursive=True
              )

这个文件在presto运行的时候,会被用到,具体调用地方在presto_server.py,做一些jar包等的配置

然后修改presto_server.py,将整个文件修改为下面的内容:

#!/usr/bin/env python

from resource_management import *
from configure import set_configuration
import os

class PrestoServer(Script):
    def __init__(self, component):
        self.component = component

    def install(self, env):
        self.install_packages(env)
        pass

    def configure(self):
        set_configuration(self.component)

    def start(self, env):
        import params

        env.set_params(params)

        self.configure()
        #修改此处
        # os.symlink(format('{conf_dir}'), os.path.join(format('{presto_root}'), 'etc'))
        os.symlink(os.path.join(format('{presto_root}'), 'etc'),format('{conf_dir}'))
        process_cmd = format("PATH={presto_root}/jdk1.8.0_181/bin:$PATH {presto_root}/bin/launcher run --node-config {conf_dir}/node.properties --jvm-config {conf_dir}/jvm.config --config {conf_dir}/config.properties >> {log_file} 2>&1")

        Execute(process_cmd,
                logoutput=True,
                wait_for_finish=False,
                pid_file=params.pid_file,
                poll_after=3
                )

    def stop(self, env):
        pass

    def status(self, env):
        import params

        env.set_params(params)
        check_process_status(params.pid_file)


if __name__ == "__main__":
    self.fail_with_error('Component name missing')

这个文件是worker和coordinator启动的时候的脚本。其中我把上面的jdk调整为我们自己丢到prestoServer目录下的jdk。除此之外,使用的jvm.config、node.properties、config.properties都是和presto配置相关的文件(和普通部署presto,不走on yarn模式的配置文件基本一样)

step4:打包编译

上面的准备工作做好后,就可以打包了

mvn clean package -DskipTests

编译完后的包在presto-yarn-package/target目录下

/opt/presto/presto-yarn/presto-yarn-package/target/presto-yarn-package-1.6-SNAPSHOT-0.223.zip

step5: prestoServer配置

我们用unzip命令解压上面的zip包,可以看到有下面的文件:

appConfig-default.json  
metainfo.xml  
package  
resources-default.json

继续,进入到package/files目录下,可以看找到文件presto-server-0.223.tar.gz

这个文件就是prestoServer,后续presto实际运行就是通过这个文件下的launcher.py启动的。对presto-server-0.223.tar.gz文件解压,进入到解压后的目录中,发现缺少了etc目录

之所以没有etc目录,是因为官方配置的时候是使用

appConfig-default.json 指定参数来配置的,但我们这里不采用这种方式,按照prestoServer正常的方式部署。

注意,虽然不试用appConfig-default.json来配置prestoServer,但是slider启动的时候需要从它获取相关的jvm参数等信息,所以还是有用的,后面会给出说明。

创建etc目录,并且把你上面在presto_server.py中配置的jdk1.8.0_181放入到当前目录中,最后的目录构造如下:

[root@test-32-201 presto-server-0.223]# ll
total 220
drwxr-xr-x  3 root  root    4096 Oct 12 15:45 bin
drwxr-xr-x  3 root  root    4096 Oct 12 14:38 etc
drwxr-xr-x  8 10143 10143   4096 Jun  9 21:58 jdk1.8.0_301
drwxr-xr-x  2 root  root   12288 Oct  8 18:08 lib
-rw-r--r--  1 root  root  191539 Jul 26  2019 NOTICE
drwxr-xr-x 30 root  root    4096 Sep 17 14:42 plugin
-rw-r--r--  1 root  root     126 Jul 26  2019 README.txt

进入etc目录,创建如下文件

jvm.config
log.properties
node.properties
config.properties

其中文件具体内容:

  • jvm.config定义prestoServer启动jvm相关参数

    -server
    -Xmx800M
    -XX:+UseConcMarkSweepGC
    -XX:+ExplicitGCInvokesConcurrent
    -XX:+CMSClassUnloadingEnabled
    -XX:+AggressiveOpts
    -XX:+HeapDumpOnOutOfMemoryError
    -XX:OnOutOfMemoryError=kill -9 %p
    -XX:ReservedCodeCacheSize=150M
    -Dsun.security.krb5.debug=true
    -Dlog.enable-console=true
    -Djava.security.krb5.conf=/etc/krb5.conf
    -Dsun.security.krb5.debug=true
    
    

    -Dsun.security.krb5.debug=true
    -Djava.security.krb5.conf=/etc/krb5.conf
    -Dsun.security.krb5.debug=true
    这几项和安全认证相关,因为我们要整合kerberos+presto

  • node.properties

node.environment=production
#node.id=presto-server
node.data-dir=/data/presto/data

这个文件定义了presto启动时数据存放路径、nodeid等信息。发现我其实注释掉了node Id, 这个node Id实际上是要全局唯一的,如果写死的话,会出现重复,导致prestoServer启动失败。故把它注释掉,让它自动分配。

另一种思路,可以在prestoSever的bin目录下的launcher.py中动态指定node.properties文件,可以临时生成一个node.properties文件,填写其中的内容,并指向它(未经测试,后续可以验证)。

  • log.properties
com.facebook.presto=INFO

支持DEBUG、INFO日志级别,输出prestoServer的日志,其中这个日志存放的位置,就是在node.properties指定的node.data-dir 下面:

[root@test-32-201 etc]# ll /data/presto/data/var/log/
http-request.log  launcher.log      server.log  
  • config.properties
coordinator=false
http-server.http.port=8666
query.max-memory=200MB
query.max-memory-per-node=400MB
query.max-total-memory-per-node=450MB
query.max-total-memory=600MB
discovery.uri=http://test-32-201.bd.com:8999

这个配置文件配置当前节点的角色、节点查询使用的内存限制、服务发现节点地址

其中:

  1. coordinator=false:是否为coordinator,false表示是worker。
  2. http-server.http.port: prestoServer启动的端口
  3. discovery.uri : 服务发现地址,这里一般都是指向coordinator,discovery服务发现也是在coordinator中启动的。后面,我们也会在test-32-201.bd.com这台机器上,单独启动coordinator。

前面说了,这里presto on yarn仅部署worker,暂时不考虑coordinator先。上面的config.properties是针对worker角色来配置的。

  • 在etc目录下创建catalog目录

prestoServer需要和hive、mysql等进行交互,需要指定hive、mysql等配置的地址。

  1. 创建hive.properties文件,键入:

    connector.name=hive-hadoop2
    hive.metastore.uri=thrift://test-32-202.bd.com:9083
    hive.config.resources=/opt/hadoop-2.7.3/etc/hadoop/core-site.xml,/opt/hadoop-2.7.3/etc/hadoop/hdfs-site.xml
    
    
    ##下面几项是访问hive时kerberos认证相关的配置
    hive.metastore.authentication.type=KERBEROS
    hive.metastore.service.principal=hive/_HOST@bd.com
    hive.metastore.client.principal=hive/_HOST@bd.com
    hive.metastore.client.keytab=/etc/security/keytabs/hive.service.keytab
    
    hive.hdfs.authentication.type=KERBEROS
    hive.hdfs.impersonation.enabled=true
    hive.hdfs.presto.principal=hive/_HOST@bd.com
    hive.hdfs.presto.keytab=/etc/security/keytabs/hive.service.keytab
    

    上面,由于我们的hive集成了kerberos,所以要引入kerberos相关的认证配置。简单说下这几个项的含义:

  • connector.name: Connector的类型,其值参考如下:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kxg4JQlo-1639037664739)(C:\Users\luohaizhang\AppData\Roaming\Typora\typora-user-images\1634029564382.png)]

由于这里是hadoop2.x版本,故使用hive-hadoop2。

  • hive.metastore.uri : hiveMetastore服务地址,获取hive元数据信息。
  • hive.config.resources : 指向hadoop的配置文件,一般指定hive目录下的core-site.xml,如果存在mountable.xml(做了viewfs的)也需要一并指定。同时,这些文件的路径可以使用相对路径,相对路径就是在你prestoserver安装目录算起,比如etc/catalog/xxx.xml 说明prestoserver安装目录的catalog目录的xxx.xml文件。

​ 后面相关的kerberos认证配置,需要注意的是,principal指定的用户需要可以访问hive,对应的keytab文件,需要在每个机器上都存在,并且路径得和上面指定的一样。

请注意:上面的hive.config.resource指定的所有配置文件,必须要存在于所有presto的worker节点上!如果不存在,会出现各种奇怪的问题!(官方原话)

具体情况参考:https://github.com/prestodb/presto/blob/master/presto-docs/src/main/sphinx/connector/hive.rst

  1. 创建mysql.properties 文件,键入:

    connector.name=mysql
    connection-url=jdbc:mysql://10.131.0.251:3306
    connection-user=root
    connection-password=bd.com
    

    这里配置不做过多展开说明,就是普通的链接数据库配置。

通过上面的配置,我们就可以通过prestoServer访问hive和mysql了。

至此,整个prestoServer就改造完成了,打包即可:

tar -cvf presto-server-0.223.tar.gz  presto-server-0.223/ 

随后我们进入到slider的配置。

2.2、slider的配置

地址https://archive.apache.org/dist/incubator/slider/,这里我们下载的版本是0.91.0-incubating,一定要选择和自己hadoop版本一致的版本

wget https://archive.apache.org/dist/incubator/slider/0.91.0-incubating/apache-slider-0.91.0-incubating-source-release.zip  

我将它部署在/opt/slider 目录下,解压后对应目录结构:

[root@test-32-201 apache-slider-0.91.0-incubating]# ll
total 144
drwxr-xr-x 15 root root  4096 Oct 12 17:33 app-packages
drwxr-xr-x  2 root root  4096 Oct 12 17:33 bin
-rw-r--r--  1 root root 13436 Jun 23  2016 DEPENDENCIES
-rw-r--r--  1 root root   532 Jun 19  2016 DISCLAIMER
-rw-r--r--  1 root root 21915 Jun 19  2016 LICENSE
-rw-r--r--  1 root root   167 Jun 19  2016 NOTICE
-rw-r--r--  1 root root 59913 Jun 23  2016 pom.xml
-rw-r--r--  1 root root  5598 Jun 19  2016 README.md
drwxr-xr-x  4 root root  4096 Oct 12 17:33 slider-agent
drwxr-xr-x  3 root root  4096 Oct 12 17:33 slider-assembly
drwxr-xr-x  3 root root  4096 Oct 12 17:33 slider-core
drwxr-xr-x  3 root root  4096 Oct 12 17:33 slider-funtest
drwxr-xr-x  4 root root  4096 Jun 19  2016 src

随后,修改pom.xml, 改下hadoop版本为你当前hadoop的版本

<hadoop.version>2.7.1</hadoop.version>

编译:

mvn clean package -Dmaven.test.skip=true -DskipTests 

编译完成在/slider-assembly/target目录找到slider-0.91.0-incubating-all.tar.gz

配置slider

step1: 解压slider-0.91.0-incubating-all.tar.gz,进入slider-0.91.0-incubating/conf

配置其中的slider-env.sh,slider-client.xml

  • 修改slider-env.sh
vim slider-env.sh

export JAVA_HOME=/usr/java/jdk1.8.0_301/
export HADOOP_CONF_DIR=/opt/hadoop-2.7.3/etc/hadoop
  • 修改slider-client.xml
<configuration>
    <property>
      <name>slider.client.resource.origin</name>
      <value>conf/slider-client.xml</value>
      <description>This is just for diagnostics</description>
    </property>

    <property>
      <name>slider.security.protocol.acl</name>
      <value>*</value>
      <description>When security is enabled, set appropriate acl. Default value means allow everyone.</description>
    </property>
<!--
    <property>
      <name>slider.yarn.queue</name>
      </value>
      <description>the name of the YARN queue to use.</description>
    </property>
-->
    <property>
      <name>slider.yarn.queue.priority</name>
      <value>1</value>
      <description>the priority of the application.</description>
    </property>

    <property>
      <name>slider.am.login.keytab.required</name>
      <value>false</value>
      <description>Declare that a keytab must be provided.</description>
    </property>
    
    <property>
      <name>yarn.log-aggregation-enable</name>
      <value>true</value>
    </property>

    <property>
      <name>yarn.application.classpath</name>
    <value>$HADOOP_CONF_DIR,$HADOOP_COMMON_HOME/share/hadoop/common/*,$HADOOP_COMMON_HOME/share/hadoop/common/lib/*,$HADOOP_HDFS_HOME/share/hadoop/hdfs/*,$HADOOP_HDFS_HOME/share/hadoop/hdfs/lib/*,$HADOOP_YARN_HOME/share/hadoop/yarn/*,$HADOOP_YARN_HOME/share/hadoop/yarn/lib/*,/etc/hadoop/secure/*</value>
    </property>

    <property>
      <name>yarn.resourcemanager.address</name>
      <value>test-hadoop-32-36.bd.com:8050</value>
    </property>

    <property>
      <name>yarn.resourcemanager.scheduler.address</name>
      <value>test-hadoop-32-36.bd.com:8030</value>
    </property>

    <property>
      <name>fs.defaultFS</name>
      <value>hdfs://hdfscluster</value>
    </property>

    <property>
      <name>hadoop.registry.zk.quorum</name>
      <value>test-32-202.bd.com:2181,test-32-203.bd.com:2181,test-32-201.bd.com:2181</value>
    </property>
    <property>
      <name>yarn.resourcemanager.principal</name>
      <value>rm/_HOST@bd.com</value>
    </property>

    <property>
      <name>dfs.namenode.kerberos.principal</name>
      <value>nn/_HOST@bd.com</value>
    </property>
</configuration>

上面的_HOST 会在运行时替换成当前的机器名

这个文件主要配置了当前客户端启动slider提交presto任务的时候的一些配置参数,比如zk(用于注册presto节点),访问yarn的kerberos凭证等

  • 配置presto yarn参数
  1. 将之前解压的presto-yarn-package-1.6-SNAPSHOT-0.223.zip目录下的appConfig-default.json,resources-default.json文件,拷贝到slider-0.91.0-incubating/conf目录中

  2. 可以参考官方配置https://prestodb.github.io/presto-yarn/installation-yarn-configuration-options.html

    给出我的配置:

    {
        "schema":"http://example.org/specification/v2.0.0",
        "metadata":{
    
        },
        "global":{
            "java_home":"/usr/java/jdk1.8.0_301",
            "site.global.app_user":"hive",
            "site.global.user_group":"hdfs",
            "site.global.app_name":"presto-server-0.223",
            "site.global.data_dir":"/data/presto/data",
            "site.global.config_dir":"/data/presto/etc",
            "zookeeper.quorum":"test-32-202.bd.com:2181,test-32-203.bd.com:2181,test-32-201.bd.com:2181",
            "application.def":".slider/package/presto/presto-yarn-package-1.6-SNAPSHOT-0.223.zip",
            "site.global.singlenode":"false",
            "site.global.coordinator_host":"10.131.3.87",
            "site.global.app_pkg_plugin":"${AGENT_WORK_ROOT}/app/definition/package/plugins/",
            "site.global.presto_query_max_memory":"1GB",
            "site.global.presto_query_max_memory_per_node":"3GB",
            "site.global.presto_server_port":"18088",
            "site.global.catalog":"{'hive':{'connector.name=hivehadoop2','hive.config.resources=/opt/hadoop2.7.3/etc/hadoop/coresite.xml,/opt/hadoop-2.7.3/etc/hadoop/hdfs-site.xml','hive.metastore.uri=thrift://test-32-202.bd.com:9083'], 'tpch': ['connector.name=tpch']}",
            "site.global.jvm_args":"['-server', '-Xmx2048M', '-XX:+UseConcMarkSweepGC', '-XX:+ExplicitGCInvokesConcurrent', '-XX:+CMSClassUnloadingEnabled', '-XX:+AggressiveOpts', '-XX:+HeapDumpOnOutOfMemoryError', '-XX:OnOutOfMemoryError=kill -9 %p']",
            "site.global.log_properties":"['com.facebook.presto.hive=WARN','com.facebook.presto.server=INFO']",
            "site.global.additional_config_properties":"['task.max-worker-threads=50', 'distributed-joins-enabled=true']"
        },
        "components":{
            "slider-appmaster":{
                "jvm.heapsize":"256M",
                "jvm.opts":"-Djava.security.auth.login.config=/etc/hadoop/secure/hdfs_jaas.conf -Djava.awt.headless=true -Xmx256m -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8001 -DHADOOP_USER_NAME=hive"
            },
            "MYAPP_COMPONENT":{
    
            }
        }
    }
    

    其中slider-appmaster这里的配置项,在slider提交任务的时候,slider会去读取这些参数,设置slider的jvm相关参数。

    • site.global.app_user:默认是yarn,该用户是以后执行slider命令的,并且执行完slider会在hdfs上创建presto的数据工作空间。需要在hdfs上首先存在/user/yarn的目录。命令执行完后会创建目录/user/yarn/.slider。且该账户需要有访问创建执行hdfs文件的权限,这里我选择了用hive账户
    • site.global.user_group:默认hadoop组,这里使用hdfs组
    • application.def:指向hdfs上的presto-yarn压缩包
    • java_home:java版本与presto版本有对应关系,presto版本要求java除了大版本1.8之外,还要满足小版本。
    • site.global.jvm_args: presto启动使用的jvm配置

    可以发现,appConfig-default.json有很多配置实际上在上面我们提到的jvm.config,node.properties都有设置,优先按照jvm.config,node.properties这些文件值运行。

详细的参数说明可参考文档:https://prestodb.io/presto-yarn/installation-yarn-configuration-options.html#appconfig-json

  1. resources-default.json配置

我的配置:

{
  "schema": "http://example.org/specification/v2.0.0",
  "metadata": {
  },
  "global": {
    "yarn.vcores": "1"
  },
  "components": {
    "slider-appmaster": {
    },
    "WORKER": {
      "yarn.role.priority": "2",
      "yarn.component.instances": "3",
      "yarn.component.placement.policy": "1",
      "yarn.memory": "1500"
    }
  }
}

这个配置告诉slider,要启动多少个worker和coordinator,具体的yarn使用内存限制等。其中这里我只让presto中的worker 在yarn上运行,coordinator的配置我没有在这里制定(单独部署)。如果你想让coordinator也on yarn, 可以如下配置:

{
  "schema": "http://example.org/specification/v2.0.0",
  "metadata": {
  },
  "global": {
    "yarn.vcores": "1"
  },
  "components": {
    "slider-appmaster": {
    },
    "COORDINATOR": {
      "yarn.role.priority": "1",
      "yarn.component.instances": "1",
      "yarn.component.placement.policy": "1",
      "yarn.memory": "1500"
    },
    "WORKER": {
      "yarn.role.priority": "2",
      "yarn.component.instances": "3",
      "yarn.component.placement.policy": "1",
      "yarn.memory": "1500"
    }
  } 

详细的说明,可参考文档:https://prestodb.io/presto-yarn/installation-yarn-configuration-options.html#resources-json

至此,slider配置就此结束。

最后,我们还要回到presto-yarn的那个目录中,将之前解压的presto-yarn-package-1.6-SNAPSHOT-0.223.zip目录下的文件重新打成zip包

[root@test-32-201 presto-yarn-package-1.6-SNAPSHOT-0.223]# ll
appConfig-default.json    metainfo.xml  package  resources-default.json

[root@test-32-201 presto-yarn-package-1.6-SNAPSHOT-0.223]# zip -r presto-yarn-package-1.6-SNAPSHOT-0.223.zip ./*

将打好的zip包找一个地方存放即可。

三、启动slider

1.使用slider启动presto集群

step1: 首先键入命令:kinit -kt /etc/security/keytabs/hive.service.keytab hive/test-32-201.bd.com

进行kerberos登录认证。这里用哪个用户进行kerberos认证,是有要求的,按照你在appConfig-default.json 文件中配置的site.global.app_user 指定的用户进行认证登录。因为slider启动实际上会去读取这个项,拿这个用户对应的hdfs路径下的文件。

可以通过klist 查看当前登录的用户

这很重要,如果登录的用户和presto前面设置的启动用户不一样,会导致在hdfs上找不到对应的presto文件保存的目录,报空指针,与此同时,需要在hdfs中建立当前登录用户的目录。

例如:hive用户,则需要在hdfs上存在 /user/hive ,后续slider提交presto任务的时候,会将本地的presto所有相关的资源配置文件打包丢到这级目录的下面。

step2: 将之前presto-yarn目录下的打好的presto-yarn-package-1.6-SNAPSHOT-0.223.zip 包上传到hdfs, 通过slider提供的命令打包上传:

../bin/slider  package --install --name presto --package /opt/presto/presto-yarn/presto-yarn-package/target/presto-yarn-package-1.6-SNAPSHOT-0.223.zip --replacepkg

–replacepkg 表示每次重新上传的时候,替换掉旧的文件。

–name presto 表示在hdfs目录下存放presto-yarn-package-1.6-SNAPSHOT-0.223.zip包的目录名称。

–package 指向你前面放的presto-yarn-package-1.6-SNAPSHOT-0.223.zip的路径

step3: 通过slider启动presto集群(实际上是提交到yarn中,通过yarn启动)。

首先删除原先存在的slider提交工作目录:

hdfs dfs -rm -r /user/hive/.slider/cluster

注意这里每次使用slider提交presto触发任务的时候,都会去检测是否当前yarn集群上有正在运行的slider提交的presto任务,如果存在正在运行的presto集群,则结束,不会提交。

另外,每次通过slider提交presto任务的时候,需要删除对应目录下的.slider/cluster 文件,存在的话会提示路径存在,不能启动。

其次,通过slider命令创建slider工作目录,并将本地presto-yarn相关配置文件等打包上传到hdfs中。

../bin/slider create presto-query --template appConfig-default.json --resources resources-default.json

–template appConfig-default.json 定义了一些presto启动时的资源大小配置等。

–resources resources-default.json 定义了yarn需要启动的presto的worker和coordinate数量等。

经过上面3步,就可以通过slider将presto提交到yarn启动了,如果在这过程中有异常,可以查看日志,日志的位置在slider目录的conf目录中的log4j.propertieslog4j-server.properties 文件中定义,这两个日志文件有些许不同:

  1. log4j.properties : 此文件定义了你通过命令../bin/slider create xxx提交(还没在yarn运行) presto启动任务到yarn这之间的日志。

  2. log4j-server.properties : 此文件定义了再yarn上面,通过启动sliderAppMaster来启动presto的日志 。

    注意,这个日志不是记录presto的运行日志情况的,而是sliderAppMaster到启动presto这之间的日志情况。

presto的具体日志,可以到presto启动的机器上,通过之前在presto中node.properties文件指定的node.data-dir的路径。

当你启动成功的时候,你可以在yarn上看到这个界面:
在这里插入图片描述

由于隐私问题,这里不透露一些机器信息

从这个界面可以看到你实际启动有多少个节点,启动失败了多少次。当然,启动失败的次数可以设置的,一般默认每个节点重试5次。

上图中显示我启动了3个Worker,其中有失败过2次,对于失败的具体原因排查,可以看到下面的Exports的container_log_dirs,这里记载着对应启动worker的机器,以及yarn启动presto的日志记录(这个记录还不是prestoServer的,它的日志应该在上面prestoServer配置的node.properties指定目录中)。

2.关闭presto集群

 yarn application -list 

选择presto对应的id进行关闭

yarn application -kill application_1627625966286_7984

至此,presto-worker on yarn所有流程就介绍完了。下面开始部署coordinator

四、部署coordinator

我们挑一台机器跑coordinator,这里选择了测试hadoop集群的机器test-32-201.bd.com。

presto集成kerberos,只需要在coordinator上进行配置,worker和coordinator之间的通行还是采用之前的http方式,客户端(presto-cli,jdbc等)访问coordinator需要通过https并且需要进行kerberos认证;presto集群集成kerberos认证只需要在coordinator 节点上进行修改,worker节点保持不变,配置完后我们将用presto-cli的方式连接presto集群

前期工作

  1. 在coordinator节点上安装kerberos client
yum install krb5-libs.x86_64 krb5-workstation.x86_64 krb5

由于test-32-201.bd.com已经有kerberos环境,这里不做安装

修改/etc/krb5.conf,具体配置不展开,自行查阅。

test-32-201.bd.com已经有kerberos环境,用的是它之前配的krb5.conf,此处没变过。

  1. 生成kerberos凭证和keytab
kadmin -p root/admin -q "addprinc -randkey presto@bd.com"
kadmin -p root/admin -q "addprinc -randkey presto/test-32-201.bd.com@bd.com"
kadmin -p root/admin -q "ktadd -k /home/presto/presto.keytab presto@bd.com"
kadmin -p root/admin -q "ktadd -k /home/presto/presto.keytab presto/test-32-201.bd.com@bd.com"

3.生成keystore

需要注意的是alias需要和启动presto的用户名一样

[root@slave1 qun]# keytool  keytool -genkeypair -alias presto -keyalg RSA -keystore prestokeystore.jks

输入密钥库口令:  
再次输入新口令: 
您的名字与姓氏是什么? 
  [Unknown]:  test-32-201.bd.com
您的组织单位名称是什么?
  [Unknown]:  
您的组织名称是什么?
  [Unknown]:  
您所在的城市或区域名称是什么?
  [Unknown]:  
您所在的省/市/自治区名称是什么?
  [Unknown]:  
该单位的双字母国家/地区代码是什么?
  [Unknown]:  
CN=slave1, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown是否正确?
  []:  y

输入 <qun> 的密钥口令
	(如果和密钥库口令相同, 按回车):  
再次输入新口令:

上面唯一需要填的是名字与姓氏那块,填主机名就行。

  1. 配置jdk,Java Cryptography Extension Policy Files
wget https://files.cnblogs.com/files/zgngg/jce_policy-8.zip

将解压的jar放到如下目录中,主要是local_policy.jar和US_export_policy.jar

cp local_policy.jar US_export_policy.jar $JAVA_HOME/jre/lib/security/

如果你启动的jdk不是本机的,而是你放在presto里面的,将这两个jar同样放到你指定的jdk里面。

  1. 调整prestoServer的配置文件

修改config.properties

我们将上面presto-yarn中presto-yarn-package-1.6-SNAPSHOT-0.223.zip解压后的prestoServer拷贝到/opt/presto中解压。解压后进入到其etc目录下,修改node.properties:

coordinator=true
#注意这个配置是否让当前coordinator同时成为worker角色,尽量不要,除非单节点测试可以设置true
node-scheduler.include-coordinator=false
#启动的http端口
http-server.http.port=8999
query.max-memory=200MB
query.max-memory-per-node=400MB
query.max-total-memory-per-node=450MB
query.max-total-memory=600MB
#开启discovery服务
discovery-server.enabled=true
#暴露discovery端口,在worker指定同样的uri就可以和coordinator相连接了
discovery.uri=http://test-32-201.bd.com:8999

#下面是kerberos相关配置
http-server.authentication.type=KERBEROS
http.server.authentication.krb5.service-name=presto
# 上面生成的keytab位置
http.server.authentication.krb5.keytab=/home/presto/presto.keytab
http.authentication.krb5.config=/etc/krb5.conf
# 开启https
http-server.https.enabled=true
# https的端口,客户端连接coordinator的时候,需要走https的这个端口,然后进行kerberos认证。
http-server.https.port=18088
# 上面生成的keystore地址
http-server.https.keystore.path=/home/presto/prestokeystore.jks

#注:http-server.https.keystore.key值为创建keystore时输入的密码。
http-server.https.keystore.key=bd.com

修改jvm.config,内容如下

-server
-XX:CMSInitiatingOccupancyFraction=80
-XX:ConcGCThreads=2
-XX:+UseCMSCompactAtFullCollection
-XX:CMSFullGCsBeforeCompaction=3
-XX:+PrintGCDetails
-Xmx1024M
-Xms1024M
-Xmn600M
-Xnoclassgc
-XX:+UseParNewGC
-XX:+CMSParallelRemarkEnabled
-XX:+UseFastAccessorMethods
-XX:LargePageSizeInBytes=128M
-XX:+UseConcMarkSweepGC
-XX:+ExplicitGCInvokesConcurrent
-XX:+CMSClassUnloadingEnabled
-XX:+AggressiveOpts
-XX:+HeapDumpOnOutOfMemoryError
-XX:OnOutOfMemoryError=kill -9 %p
-XX:ReservedCodeCacheSize=150M
-Dsun.security.krb5.debug=true
-Dlog.enable-console=true
-Djava.security.krb5.conf=/etc/krb5.conf
-Dsun.security.krb5.debug=true
-Djava.security.auth.login.config=hdfs_jaas.conf

具体cms配置和说明,参考文章:https://www.cnblogs.com/hongdada/p/10277782.html

修改完后重启coordinator节点

我们可以通过prestoServer的bin目录中的launcher启动coordinator

[root@test-32-201 bin]# ls
launcher  launcher.properties  launcher.py  procname
[root@test-32-201 bin]# ./launcher start 

同样的,可以通过 ./launcher stop 关闭当前的coordinator

至此,coordinator整合kerberos就结束了。下面启动coordinator和用slider在yarn上提交启动worker ,让worker和coordinator连接,整个presto集群就搭建好了。

presto还提供了可视化的界面,查看当前sql执行情况,活跃的worker数等信息:

访问:http://test-32-201.bd.com:8999/ui/#

8999就是你上面指定的http端口

在这里插入图片描述

另外,presto还提供了一些http接口,查看更详细的节点状态情况:

例如下面命令,可以查看每个节点的具体信息:

 curl http://localhost:8999/v1/node
 
 {
    "uri":"http://10.209.57.156:8080",
    "recentRequests":25.181940555111073,
    "recentFailures":0.0,
    "recentSuccesses":25.195472984170983,
    "lastRequestTime":"2013-12-22T13:32:44.673-05:00",
    "lastResponseTime":"2013-12-22T13:32:44.677-05:00",
    "age":"14155.28ms",
    "recentFailureRatio":0.0,
    "recentFailuresByType":{}
}

各返回值的含义:
在这里插入图片描述
例如下面命令,可以查看集群的信息:

curl http://localhost:8999/v1/cluster

接下来,我讲下如何使用presto客户端工具连接基于kerberos的presto集群。

五、使用presto客户端工具连接presto集群
  • 下载presto-cli
wget https://repo1.maven.org/maven2/com/facebook/presto/presto-cli/0.223/presto-cli-0.223-executable.jar
cp presto-cli-0.223-executable.jar presto-cli
chmod +x presto-cli

我们也可以下载presto-0.223的源码,通过编译源码的方式,获取presto-cli的jar也可以,这种方式也允许我们修改源码,从而符合我们的需求。

注意,在使用presto-cli之前,确保jdk版本在1.8以上,否则会报错

Exception in thread “main” java.lang.UnsupportedClassVersionError: com/facebook/presto/cli/Presto : Unsupported major.minor version 52.0

  • 键入命令链接hive
./presto-cli --server https://test-32-201.bd.com:18088 --krb5-config-path /etc/krb5.conf --krb5-principal presto --krb5-keytab-path /home/presto/presto.keytab --krb5-remote-service-name presto  --keystore-path /home/presto/prestokeystore.jks --keystore-password bd.com --catalog hive --schema default
  • –server https://test-32-201.bd.com:18088 coordinator的ip和暴露的https端口

  • –krb5-principal 和 --krb5-keytab-path 对应principal和ketab

  • –catalog 指定presto-cli客户端启动之后使用的默认catalog,实际上就是你再prestoServer/etc/catalog目录中定义的那几个properties,这里使用的是hive.properties,连接器是hive-hadoop2来连接hive集群。

  • –schema default 连接hive集群后使用default数据库。

六、连接presto集群
6.1、JAVA连接presto集群
  • 下载presto-jdbc对应的版本:

https://repo1.maven.org/maven2/com/facebook/presto/presto-jdbc/0.223/presto-jdbc-0.223.jar
同样的,你也可以通过maven导入

<dependency>
    <groupId>com.facebook.presto</groupId>
    <artifactId>presto-jdbc</artifactId>
    <version>0.223</version>
</dependency>
  • 编写测试类

连接mysql

  public class PrestoTest {

    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //加载Driver类
        Class.forName("com.facebook.presto.jdbc.PrestoDriver");
        //获得连接,3个参数分别是url,presto的用户名和密码
        Connection connection = DriverManager.getConnection("jdbc:presto://test-32-201.bd.com:8999/mysql-dmp/test", "haizhang", "");
        //通过连接获得Statement
        Statement statement = connection.createStatement();
        //运行sql获得返回值
        ResultSet resultSet = statement.executeQuery("select FID from T_DMP_CROWD_INFO where FID>1000  ");
       //遍历
        while (resultSet.next()){
            System.out.println(resultSet.getString("FID"));
        }
    }
  }

其中上面的presto用户名和密码其实没什么用,presto内部并不会去检查,但是一定要有用户名和密码,因为presto会做判空检测。用户名的作用,目前我发现的只是在presto监控界面这里可以查看某条sql是谁执行的。

在这里插入图片描述
连接hive

    /**
     *  /opt/presto/prest-server/presto-server-0.223/jdk1.8.0_301/bin/java -jar presto-cli --server https://test-32-201.bd.com:18088 --krb5-config-path /etc/krb5.conf --krb5-principal presto --krb5-keytab-path /home/presto/presto.keytab --krb5-remote-service-name presto  --keystore-path /home/presto/prestokeystore.jks --keystore-password bd.com --catalog hive --schema default
     * @throws ClassNotFoundException
     * @throws SQLException
     */
    public static void connectHive() throws ClassNotFoundException, SQLException {
        // URL parameters
        String url = "jdbc:presto://test-32-201.bd.com:18088/hive/default";
        Properties properties = new Properties();
        properties.setProperty("user", "presto");
        properties.setProperty("password", "bd.com");
        properties.setProperty("SSL", "true");
        properties.setProperty("SSLKeyStorePath", "E:\\prestokeystore.jks");
        properties.setProperty("SSLKeyStorePassword","bd.com");
        properties.setProperty("KerberosRemoteServiceName","presto");
        properties.setProperty("KerberosPrincipal","presto");
        properties.setProperty("KerberosKeytabPath","E:\\presto.keytab");
        properties.setProperty("KerberosConfigPath","E:\\krb5.conf");
        Connection connection = DriverManager.getConnection(url, properties);
        Statement statement = connection.createStatement();
        ResultSet resultSet = statement.executeQuery("show tables");
        while (resultSet.next()){
            //todo 做后续的业务处理
        }
    }

对于上面的keytab等配置文件,需要和测试环境上面配置的一样。

更多的细节请参考官方文档:

https://prestodb.io/docs/current/installation/jdbc.html

6.2、Python连接presto集群

参考文章:https://zhuanlan.zhihu.com/p/145864930

  1. 准备好cacert.pem文件

首先找到你访问presto的jks文件,然后通过jks导出对应的pem文件。键入命令:

keytool -export -rfc -alias <alias-name> -file <output-file.pem> -keystore <keystorefile.jks> -storepass <storepass>

alias是定义在keystore里面的entry,可以使用如下命令,查看当前包含哪几个entry:

keytool --list -keystore <keystorefile.jks> -storepass <storepass>

例如:

[root@test-32-201 presto]# keytool --list -keystore prestokeystore.jks   -storepass bd.com

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

presto, Oct 12, 2021, PrivateKeyEntry, 
Certificate fingerprint (SHA1): C8:BE:91:96:5E:F4:BA:ED:E4:26:F9:68:5F:36:F1:B7:75:03:C8:D

这个JKS包含1个entry,这样在提取证书的时候可以知道alias值为presto

然后键入:

keytool -export -rfc -alias presto -file cacert.pem -keystore  prestokeystore.jks  -storepass bd.com
七、常见问题总结
7.1、连接时常见的问题
  1. javax.net.ssl.SSLPeerUnverifiedException

presto> show catalogs;
Error running command: javax.net.ssl.SSLPeerUnverifiedException: Hostname 192.168.1.116 not verified:
certificate: sha256/i+KNkzrrH/NHzUruc9R+f0a/P8Ql/OhOKh9n3JtL1qg=
DN: CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
subjectAltNames: []

这种问题由keystore生成的时候host指定错误造成的

您的名字与姓氏是什么?[Unknown]: hostname

hostname即是你的主机名。

  1. Authentication failed for token

情况一:

com.facebook.presto.server.security.SpnegoFilter  Authentication failed for token
  Encryption type AES256 CTS mode with HMAC SHA1-96 is not supported/enabled)

解决办法如下,下载JCE
http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
解压后替换$JAVA_HOME/jre/lib/security目录下的local_policy.jar,US_export_policy.jar

情况二:

问题异常:

2021-11-03T14:37:13.995+0800    INFO    http-worker-140 stdout  Looking for keys for: presto/yjd-presto-0-150@bd.com
2021-11-03T14:37:13.996+0800    INFO    http-worker-140 stdout  Looking for keys for: presto/yjd-presto-0-150@bd.com
2021-11-03T14:37:13.997+0800    DEBUG   http-worker-140 com.facebook.presto.server.security.KerberosAuthenticator       Authentication failed for token YIICdwYGKwYBBQUCoIICazCCAmegDTALBgkqhkiG9xIBAgKhBAMCAXaiggJOBIICSmCCAkYGCSqGSIb3EgECAgEAboICNTCCAjGgAwIBBaEDAgEOogcDBQAgAAAAo4IBSmGCAUYwggFCoAMCAQWhCxsJTUVJWlUuQ09Noi4wLKADAgEAoSUwIxsGcHJlc3RvGxl5amQtcHJlc3RvLTAtMTUwLm1laXp1Lm16o4H9MIH6oAMCARKhAwIBAaKB7QSB6pQuSlEDzzjpzCBizRKSM5214UxKF82cc1iAZzfREFfX+E7wjxI8ly4wwQlVHlb1xGfe0daT1VQqcN6dmgJbIMliocmSH1V+w2GZSMRWF0Je0di7wk8qYHZvcyfZqQeVRkm1ler8kQxGkfNWyjQ9GKIfeUGuViinkfZ+kTFkAX8i8qMgn0k/yhbPcoAN1qoKVUD+slmoZqOvgQdcs3x9okx2d+i6V7S2KrJDToMrOt7/wgAoAKhMmFI5yFUiMQLi7eIFeVYhPVmSucFSeLkVsqOkheKNaqAV5X5yH0Zb9aY6dn5eXjxBCuUMDaSBzTCByqADAgESooHCBIG/ig8Apm4UKfoAT+rv7EjmcMCFlzOTOYlK4lcmHu8KsbUe1wd8+LcS/6YbWyDMf2JWdI1Aacag1MSc+XxY0lL/g/cACsMcoB9ZQXwq/ANPNp2i47wlDXCiedxcd2YTqx8OwOSMHBhuITv0qPEYjD+d17fx9AZrqAgnVBOWMQEoGuQvr5BKiuKeQtUvknDjOpwzyo05l4jN6WOyZ2onGqq9v6sUTDSGJmfb486XwNFMq4S0PIKIBhbVafdP2HF8vnM=
GSSException: Failure unspecified at GSS-API level (Mechanism level: Invalid argument (400) - Cannot find key of appropriate type to decrypt AP REP - AES256 CTS mode with HMAC SHA1-96)
        at sun.security.jgss.krb5.Krb5Context.acceptSecContext(Krb5Context.java:858)
        at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:342)
        at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:285)

这种情况首先看一下你生成的keytab文件的内容,通过命令klist -ke xxx.keytab
在这里插入图片描述
发现只有presto@bd.com的加密信息,没有发现presto/yjd-presto-0-150@bd.com 的凭证信息,而异常中提示需要用到presto/yjd-presto-0-150@bd.com的凭证信息,这个时候就需要将presto/yjd-presto-0-150的凭证信息加入到presto.keytab中

kadmin -p root/admin -q "addprinc -randkey presto@bd.com"
kadmin -p root/admin -q "addprinc -randkey presto/yjd-presto-0-150@bd.com"
kadmin -p root/admin -q "ktadd -k /home/presto/presto.keytab presto@bd.com"
kadmin -p root/admin -q "ktadd -k /home/presto/presto.keytab presto/yjd-presto-0-150@bd.com"

此处就将presto@bd.com和presto/yjd-presto-0-150@bd.com的keytab信息存为一份keytab文件,你在用klist -ke查看生成的keytab文件结构,确认presto/yjd-presto-0-150@bd.com的凭证也在里面就可以了

  1. PKIX path building failed

具体异常

presto:default> show tbales;
Error running command: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

请检查你在连接的时候指定的--krb5-principal--krb5-keytab-path等是否正确,文件是否存在。 如果都正常,可能考虑是缺少安全证书相关的内容:可以参考博客https://blog.csdn.net/qq_34778576/article/details/108489662 解决。

  1. presto-cli 查询hive数据报错:Catalog ‘hive‘ does not exist

原因,在prestoServer/etc目录下,没有把hive.properties放入到catalog目录下。

7.2 presto集群搭建常见问题

集群搭建常见的问题,无非出现在slider提交presto任务到yarn过程、yarn调度起SliderAppMaster启动presto过程、presto服务实际运行过程。下面我逐一说下我在搭建过程遇到的问题和解决方案。

7.2.1、slider提交任务过程的问题

这里出现的问题比较少,无非是配置文件参数读取问题,比如yarn的地址不正确导致连不上,提交失败。

这里出现异常,可以直接定位到error log。 除此之外,由于slider也是java写的,我们可以通过debug方式去追溯问题的来源:

进入到slider安装目录的bin目录下面,找到slider.py, 修改:

DEFAULT_JVM_OPTS = "-Djava.net.preferIPv4Stack=true -Djava.awt.headless=true -Xmx256m -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000"

这里相当于开启了8000端口,当你进行slider提交的时候,就可以debug了。

7.2.2、yarn调起sliderAppMaster启动presto集群过程

这个阶段先看sliderAppMaster可能出现的问题:

  1. JAAS文件找不到

Exception: Entry “Client” not found; JAAS config = ; java.security.auth.login.config=(undefined)

对于这个异常,在hadoop-env.sh有这个配置

export HADOOP_ZKFC_OPTS="-Dzookeeper.sasl.client=true -Dzookeeper.sasl.client.username=zookeeper -Djava.security.auth.login.config=/etc/hadoop/secure/hdfs_jaas.conf -Dzookeeper.sasl.clientconfig=Client $HADOOP_ZKFC_OPTS"

其中有引用到hdfs_jaas.conf。slider会去校验当前的模式,如果hadoop集群开启了kerberos认证,则会去找这个jaas.conf文件,如果找不到,就会报上面的错误。

这里的解决方案是,修改slider安装目录下的conf目录的appConfig-default.json。

"components":{
        "slider-appmaster":{
            "jvm.heapsize":"256M",
            "jvm.opts":"-Djava.security.auth.login.config=/etc/hadoop/secure/hdfs_jaas.conf -Djava.awt.headless=true -Xmx256m -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8001 -DHADOOP_USER_NAME=hive"
        }
    }

主要加入jvm.opts并制定jaas文件的位置, slider在提交任务的时候会加载这个appConfig-default.json文件的所有配置项,通过这里告知slider具体的hdfs_jaas.conf的位置 。

  1. 在为presto往zk注册节点的时候出现ZKPath已存在的异常

这个异常通常是当某个节点出问题了,slider会重试,导致出现多次创建的情况,这个异常实际上可以忽略,因为不会影响程序后续运行。实际上更好的做法是判断是否存在这个path,而slider源码中并没有调用zk的exist方法判断路径,直接创建了一个持久节点(非临时)。这些zk的持久节点会在集群关闭的时候自动的删除。

  1. yarn集群连接不上的问题

这种情况先去检查下yarn集群的master节点是否存在,如果正常工作,可能考虑是不是yarn集群之前做了主备切换。slider实际上去链接yarn集群是通过slider-client.xml的下面两项配置信息获取机器地址的:


    <property>
      <name>yarn.resourcemanager.address</name>
      <value>test-32-36.bd.com:8050</value>
    </property>

    <property>
      <name>yarn.resourcemanager.scheduler.address</name>
      <value>test-32-36.bd.com:8030</value>
    </property>

可以先尝试用wget看看上面的ip端口是否ok,如果不ok,而yarn集群又正常,则说明有做过主备切换。对于这种情况,实际会继续重试连接下一个之前备份的节点。

  1. container重试启动次数超过上限

Unstable Application Instance : - failed with component WORKER failed ‘recently’ 6 times (6 in startup); threshold is 5

这种情况,最好先检查下日志,看看是否是运行container的机器上没有ssl环境,因为appmaster调起container通过https的方式操作的。例如:

ERROR 2022-04-13 19:28:44,045 NetUtil.py:54 - SSLError: Failed to connect. Please check openssl library versions.

slider输出的这个提示指明当前worker重试次数超出了阈值。这个阈值的设定,我们可以通过slider的源码的AppSate.checkFailureThreshold方法获取,其中会调用下面的getFailureThresholdForRole方法,获取当前角色定义的失败阈值:

 /**
   * Get the failure threshold for a specific role, falling back to
   * the global one if not
   * @param roleStatus role
   * @return the threshold for failures
   */
  private int getFailureThresholdForRole(RoleStatus roleStatus) {
    ConfTreeOperations resources =
        instanceDefinition.getResourceOperations();
    return resources.getComponentOptInt(roleStatus.getGroup(),
        CONTAINER_FAILURE_THRESHOLD,
        failureThreshold);
  }

role表示我们在slider/conf目录的 resources-default.json 文件中定义的WOKER\CONTAINER这些角色。而container的阈值获取来自于这个文件对应角色下的yarn.container.failure.threshold配置:

{
  "schema": "http://example.org/specification/v2.0.0",
  "metadata": {
  },
  "global": {
    "yarn.vcores": "1"
  },
  "components": {
    "slider-appmaster": {
    },
    "WORKER": {
      "yarn.role.priority": "2",
      "yarn.component.instances": "5",
      "yarn.component.placement.policy": "1",
      /** 增加此配置限制worker角色的重试启动次数 **/
      "yarn.container.failure.threshold": "20",
      "yarn.memory": "10240"
    }
  }
}
7.2.3、presto启动运行时出现问题
  1. Caused by: java.lang.IllegalArgumentException: keytab does not exist: /etc/security/keytabs/hive.service.keytab

异常很明显,我们必须要保证本地机器都有这个keytab,这个文件当时是在上面我们定义hive.prorperties中指定的。

  1. Service announcement failed after 95.99us

2021-10-08T15:14:08.666+0800 ERROR Announcer-2 io.airlift.discovery.client.Announcer Service announcement failed after 95.99us. Next request will happen within 1000.00ms

presto每隔1s会去检查和coordinator的连接,上面出现的异常,表示找不到服务发现服务。请检查你配置的discovery.uri是否和coordinator暴露出去的一致。需要注意的是,discovery.uri用的是http而不是https,因为worker和coordinator通信还是走http方式的。所以dicovery.uri指定的端口是http的端口。

另外,也有可能是coordinator挂了,去看下进程是否还在。也有可能因为网络不通,检查下防火墙等。

  1. Invalid memory configuration 内存设置

Error injecting constructor, java.lang.IllegalArgumentException: Invalid memory configuration. The sum of max total query memory per node (1048576000) and heap headroom (311387750) cannot be larger than the available heap memory (10
37959168)

这个报错就是内存设置的过大了,超出jvm可以使用的内存大小(xmx参数)。去jvm.config和config.properties中调整相应的内存参数设置。

具体内存相关配置,参考:http://armsword.com/2019/11/13/the-configuration-settings-of-presto-memory-management/#more

7.3 其余常见问题
  1. 我遇到的几个常见问题都在下面博客有记录,都是和连接数据源相关的问题:

https://blog.csdn.net/silentwolfyh/article/details/108600511

  1. coordinator和worker都正常启动,但是访问hive报Empty Mount table in config for viewfs://xxx/
Query 20211109_062401_00047_a62mq failed: Error opening Hive split viewfs://xxx/hive/warehouse/uxip.db/hive_table_test/pkg_name=com.alibaba/000001_0 (offset=0, length=33554432): ViewFs: Cannot initialize: Empty Mount table in config for viewfs://xxx/

这是你使用了viewfs治理hadoop集群搞的,而你的hive的catalog配置,缺少了viewfs对应的mountable相关的配置内容。 所以它找不到挂载表。报此问题。

解决办法就是,将hive的core-site.xml的配置路径,添加到presto的catalog的hive.properties中:

#加入这行
hive.config.resources=/opt/presto/hadoop/core-site.xml,/opt/presto/hadoop/hdfs-site.xml,/opt/presto/hive/core-site.xml

这个hive的core-site.xml有如下配置:

    <xi:include href="mountTable.xml">
    <xi:fallback></xi:fallback>
    </xi:include>

看到这里,它引入了一个mountTable.xml,viewFs就是要根据这个挂载表找到对应的namenode来处理请求,如果这表都没有,当然会报上面的错误。而这里的mountTable.xml确保要和core-site.xml处于同一级目录。当然,如果你的mountTable.xml在其他位置,可以修改href指向绝对路径就行。

presto在启动时,新建hiveConnector的时候,会去读取hive.config.resources并加载他所需要的配置。

如果你是presto on yarn的模式,你必须要保证hive.config.resources对应的这些xml必须得在最终woker运行的那些节点机器上存在!且配置应该要相同!

  1. 访问hive的时候报Failed to list directory

具体报错:

com.facebook.presto.spi.PrestoException: Failed to list directory: hdfs://hzcluster/user/hive/warehouse/t2

我们在presto控制台点击刚刚查询的记录

在这里插入图片描述
进入之后,会有详细的log

com.facebook.presto.spi.PrestoException: Failed to list directory: hdfs://hdfscluster/user/hive/warehouse/t2

Caused by: org.apache.hadoop.ipc.RemoteException: Unauthorized connection for super-user: hive/test-32-201.bd.com@HZ.COM from IP 10.111.3.22
	at org.apache.hadoop.ipc.Client.call(Client.java:1476)
	at org.apache.hadoop.ipc.Client.call(Client.java:1413)
	at org.apache.hadoop.ipc.ProtobufRpcEngine$Invoker.invoke(ProtobufRpcEngine.java:229)
	at com.sun.proxy.$Proxy199.getListing(Unknown Source)

看样子是没有权限访问hive,请检查当前机器的kerberos principal是否可以通过beeline的方式访问hive

  1. Unable to obtain password from user

Query 20220414_074427_00026_vcehr failed: Error opening Hive split viewfs://xxx/hive/a.db/atable/stat_date=20201115/000000_0 (offset=0, length=207): javax.security.auth.login.LoginException: Unable to obtain password from user

这个异常是在查询sql的时候出来的,在实际访问hdfs指定路径的表权限的时候,会进行认证当前访问用户是否有权限访问某个路径的文件。上面的提示说明无权访问,你得确认当前的worker的kerberos文件配置是否正确,请检查etc/catalog/下有关的hive配置文件

connector.name=hive-hadoop2
hive.metastore.uri=thrift://xxx.xxx.xxx:9083

hive.metastore.authentication.type=KERBEROS
hive.metastore.service.principal=hive/_HOST@XXX.COM
hive.metastore.client.principal=hive/_HOST@XXX.COM
hive.metastore.client.keytab=/etc/hive.service.keytab

hive.hdfs.authentication.type=KERBEROS
hive.hdfs.impersonation.enabled=true
hive.hdfs.presto.principal=hive/_HOST@XXX.COM
hive.hdfs.presto.keytab=/etc//hive.service.keytab

hive.config.resources=etc/catalog/config/hive/core-site.xml,etc/catalog/config/hive/hdfs-site.xml,etc/catalog/config/hive/mountTable.xml

请重点留意,你的keytab文件在worker运行机器上是否能找到,以及principal是否是_HOST 这很重要,不能写死主机名,我这个异常就是写死了某个主机名,导致principal和keytab不匹配报错。presto内部会替换掉_HOST为当前运行机器的主机名,

八、补充-Presto服务发现部署方案

这里的方案主要解决一个问题,当presto on yarn这种模式运行worker和coordinator的时候,由于你不知道coordinator究竟会运行到哪一台机器上,导致worker无法找到coordinator(更确切将,是无法找到presto服务发现注册中心对应的机器ip) ,因为presto的服务发现功能默认是集成于coordinator中的。 下面给出三个解决方案,处理这个问题。

方案一: coordinator不走on yarn ,单独部署

这种方案就是我上面部署流程采用的。这里不多讲

方案二:设置yarn label

这种方式下,worker和coordinator 还是on yarn的方式,通过yarn进行调起。通过给yarn集群打上label,前提是yarn集群启动label功能,这里可以找网上相关资料。然后,进入到slider安装目录下,找到resources-default.json ,在coordinator选项下面,设置:

"yarn.label.expression": "yarn的label"

这样,coordinator启动时,就会被yarn丢到对应label的机器上。

不过这种方式不推荐,主要是因为label会导致不设置这个标签值的机器调用不了,任务跑不到这台设置label的机器上。

方式三:将presto的服务发现框架抽离,单独部署

presto的服务发现采用的是Airlift Discovery ,我们可以将coordinator和worker的discovery.uri指向单独部署的Airlift所属的机器。

具体的搭建步骤请参考:

https://blog.csdn.net/anghiking20140716/article/details/101312055

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值