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
这个配置文件配置当前节点的角色、节点查询使用的内存限制、服务发现节点地址
其中:
- coordinator=false:是否为coordinator,false表示是worker。
- http-server.http.port: prestoServer启动的端口
- 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等配置的地址。
-
创建
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的类型,其值参考如下:
由于这里是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
-
创建
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参数
-
将之前解压的presto-yarn-package-1.6-SNAPSHOT-0.223.zip目录下的appConfig-default.json,resources-default.json文件,拷贝到
slider-0.91.0-incubating/conf
目录中 -
可以参考官方配置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这些文件值运行。
- site.global.app_user:默认是yarn,该用户是以后执行slider命令的,并且执行完slider会在hdfs上创建presto的数据工作空间。需要在hdfs上首先存在
详细的参数说明可参考文档:https://prestodb.io/presto-yarn/installation-yarn-configuration-options.html#appconfig-json
- 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.properties
和 log4j-server.properties
文件中定义,这两个日志文件有些许不同:
-
log4j.properties : 此文件定义了你通过命令
../bin/slider create xxx
提交(还没在yarn运行) presto启动任务到yarn这之间的日志。 -
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集群
前期工作
- 在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,此处没变过。
- 生成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> 的密钥口令
(如果和密钥库口令相同, 按回车):
再次输入新口令:
上面唯一需要填的是名字与姓氏那块,填主机名就行。
- 配置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里面。
- 调整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
- 准备好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、连接时常见的问题
- 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即是你的主机名。
- 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的凭证也在里面就可以了
- 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 解决。
- 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可能出现的问题:
- 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的位置 。
- 在为presto往zk注册节点的时候出现ZKPath已存在的异常
这个异常通常是当某个节点出问题了,slider会重试,导致出现多次创建的情况,这个异常实际上可以忽略,因为不会影响程序后续运行。实际上更好的做法是判断是否存在这个path,而slider源码中并没有调用zk的exist方法判断路径,直接创建了一个持久节点(非临时)。这些zk的持久节点会在集群关闭的时候自动的删除。
- 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集群又正常,则说明有做过主备切换。对于这种情况,实际会继续重试连接下一个之前备份的节点。
- 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启动运行时出现问题
- Caused by: java.lang.IllegalArgumentException: keytab does not exist: /etc/security/keytabs/hive.service.keytab
异常很明显,我们必须要保证本地机器都有这个keytab,这个文件当时是在上面我们定义hive.prorperties中指定的。
- 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挂了,去看下进程是否还在。也有可能因为网络不通,检查下防火墙等。
- 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 其余常见问题
- 我遇到的几个常见问题都在下面博客有记录,都是和连接数据源相关的问题:
https://blog.csdn.net/silentwolfyh/article/details/108600511
- 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运行的那些节点机器上存在!且配置应该要相同!
- 访问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
- 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