背景
Apache Kyuubi是一个分布式和多租户的SQL网关,用于在 Lakehouse 上提供 Serverless SQL。
Kyuubi屏蔽了计算引擎连接方式的差异,可连接Spark、Flink、Hive等多种计算引擎。
本篇围绕Kyuubi的编译,配置,部署和Spark Engine的使用展开介绍。
环境信息
- Linux
- Kyuubi 1.9.2
- Spark 3.3
编译
注意:Kyuubi不支持scala 2.11。即要求Spark和Flink的Scala版本为2.12。链接:https://github.com/apache/incubator-kyuubi/issues/2903。
首先从GitHub clone项目到本地:
git clone https://github.com/apache/kyuubi.git
切换到需要编译的分支之后。执行:
build/dist --tgz --flink-provided --spark-provided --hive-provided -Pspark-3.3 -Pflink-1.17
开始编译和打包过程。编译完成后软件tar包会自动在源代码根目录生成。
注意:使用默认的Maven源下载比较缓慢。Kyuubi编译使用自带的maven,目录为
kyuubi/build/apache-maven-3.8.8
。可修改此目录中的conf/settings.xml
换源。
例如可修改为:
<mirror>
<id>alimaven</id>
<mirrorOf>*,!confluent</mirrorOf>
<name>aliyun maven</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
配置
全部配置项的官网介绍:https://kyuubi.readthedocs.io/en/v1.9.2/configuration/settings.html
需要注意的是,每次修改Kyuubi的配置,需要查看Kyuubi的HiveSQLEngine
或FlinkSQLEngine
是否在运行状态。如果是运行状态,在重启Kyuubi Server之前,需要先将这些Engine进程停止掉。否则新的配置不会生效。
查看XXXSQLEngine
是否在运行的方法:
[root@manager /]# jps -l | grep kyuubi
12738 org.apache.kyuubi.server.KyuubiServer
3849 org.apache.kyuubi.engine.flink.FlinkSQLEngine
kyuubi-defaults.conf 配置
该配置文件主要包含Kyuubi服务的端口,认证和Engine等相关配置。
Kyuubi Server IP端口配置
Kyuubi 1.7.x版本中的kyuubi.frontend.bind.port
已废弃,不建议使用。
Kyuubi 1.9.2版本配置端口建议使用如下配置项:
- kyuubi.frontend.thrift.binary.bind.port: Thrift服务端口,默认为10009。
- kyuubi.frontend.rest.bind.port: Rest端口,默认为10099。
- kyuubi.metrics.prometheus.port: 监控prometheus端口。默认为10019。如果同一个节点需要运行多个Kyuubi实例。除了修改上面两个端口之外,还不要忘了修改这个。
- kyuubi.frontend.protocols: 使用哪些通信协议。默认为THRIFT_BINARY,REST。
HA配置
Kyuubi Server支持高可用。我们可以使用Zookeeper提供Kyuubi的服务发现功能。
- kyuubi.ha.client.class: 使用Zookeeper需要配置org.apache.kyuubi.ha.client.zookeeper.ZookeeperDiscoveryClient
- kyuubi.ha.addresses: Zookeeper的地址
- kyuubi.ha.namespace: 如果一套Zookeeper集群维护了多个HA Kyuubi集群,需要配置不同的namespace加以区分。在Zookeeper中namespace对应Kyuubi server状态信息保存的根ZNode。默认为
kyuubi
。
注意:如果启用了Kerberos,需要增加如下配置:
- kyuubi.ha.zookeeper.auth.type: 配置为
KERBEROS
- kyuubi.ha.zookeeper.auth.principal: Zookeeper认证使用的principal
- kyuubi.ha.zookeeper.auth.keytab: Zookeeper认证使用的keytab
Kyuubi Server Kerberos认证配置
- kyuubi.authentication: 配置为
KERBEROS
- kyuubi.kinit.principal: Kyuubi使用的Kerberos principal
- kyuubi.kinit.keytab: Kyuubi使用的Kerberos principal对应的keytab
注意:
- 如果Kyuubi server使用的principal对应Hadoop的用户没有访问HDFS和提交Yarn作业的权限,则只能使用user impersonation。
- Kyuubi的Principal必须具有3段式命名,例如
kyuubi/host01@PAULTECH.COM
。否则会出现:Caused by: javax.security.auth.login.LoginException: Kerberos principal should have 3 parts: kyuubi-xxxx@PAULTECH.COM
- 如果kyuubi server日志出现
org.apache.zookeeper.KeeperException$InvalidACLException: KeeperErrorCode = InvalidACL for /kyuubi
。需要将kyuubi.ha.zookeeper.auth.principal
和kyuubi.ha.zookeeper.auth.keytab
配置为kyuubi对应的principal和keytab。
Spark Engine相关配置
本篇以Spark引擎为例讲解Kyuubi的使用方式。除此之外Kyuubi还支持Flink和Hive引擎。关于它们的使用方式作者另开一篇专门的文章展开介绍。
例如我们需要配置Spark引擎运行在Yarn集群上,使用default队列。可以按照如下方式配置:
spark.master yarn
spark.yarn.queue default
在Kyuubi中,配置参数分为如下三个级别:1.Kyuubi JDBC连接URL中的参数,2.kyuubi-defaults.conf中的参数,3.对应计算引擎配置文件中的参数。级别高的参数会覆盖掉级别低的参数。因此我们可以在JDBC URL中指定配置参数从而临时修改某些参数值。例如:jdbc:hive2://localhost:10009/default;#spark.sql.shuffle.partitions=2;spark.executor.memory=5g
Engine类型配置
- kyuubi.engine.type: 默认为
SPARK_SQL
。支持SPARK_SQL
,FLINK_SQL
,TRINO
,HIVE_SQL
和JDBC
。
引擎共享策略配置
对应配置项为:kyuubi.engine.share.level
。支持如下配置值:
- CONNECTION: Engine不共享,每个连接都会创建一个对应的engine为之服务。
- USER: 相同用户使用同一个Engine。此项为默认值。
- GROUP:属于同一组的用户使用同一个Engine。
- SERVER:所有用户共享同一个Engine。
kyuubi-env.sh 配置
kyuubi-env.sh
用来配置环境信息。例如JAVA_HOME,Spark/Flink安装目录,配置文件目录等。按照配置文件中注释补充需要的配置项即可。
使用Spark Engine的时候我们必须配置:
SPARK_HOME
HADOOP_CONF_DIR
YARN_CONF_DIR
使用Flink Engine的时候我们必须配置:
FLINK_HOME
FLINK_HADOOP_CLASSPATH
HADOOP_CLASSPATH
使用Hive Engine的时候我们必须配置:
HIVE_HOME
HIVE_CONF_DIR
HIVE_HADOOP_CLASSPATH
User impersonation 配置
例如启动Kyuubi server对应的Hadoop用户为kyuubi。编辑core-site.xml
。加入如下配置:
<property>
<name>hadoop.proxyuser.kyuubi.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.kyuubi.users</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.kyuubi.groups</name>
<value>*</value>
</property>
保存后重启HDFS和Yarn。
注意:这里配置值使用*
会导致可代理的用户范围过大,实际使用时酌情调整。
HA部署
由于生产模式多用HA,且单机模式较为简单,这里只介绍HA的配置方式。
HA模式部署需要将Kyuubi复制到各个节点上。
如果启用了Kerberos,需要创建出每个节点Kyuubi使用的principal。比如3节点集群:host1,host2和host3,需要在Kerberos中创建3个principal:
- kyuubi/host1@PAULTECH.COM
- kyuubi/host2@PAULTECH.COM
- kyuubi/host3@PAULTECH.COM
接下来使用Kerberos创建这3个principal对应的keytab文件,分别放置到对应节点的同一目录下,例如/etc/security/keytabs/kyuubi.service.keytab
。
然后在每个Kyuubi节点,分别修改它们的配置文件。需要关注的配置项如下:
kyuubi.frontend.bind.host xxx.xxx.xxx.xxx
kyuubi.ha.client.class org.apache.kyuubi.ha.client.zookeeper.ZookeeperDiscoveryClient
kyuubi.ha.addresses zk1:2181,zk2:2181,zk3:2181
kyuubi.ha.namespace kyuubi
kyuubi.ha.zookeeper.auth.type KERBEROS
kyuubi.ha.zookeeper.auth.principal kyuubi/_HOST@PAULTECH.COM
kyuubi.ha.zookeeper.auth.keytab /etc/security/keytabs/kyuubi.service.keytab
需要注意的是:
-
kyuubi.frontend.bind.host
不能配置0.0.0.0
,必须配置本机IP或者hostname。否则Zookeeper的/kyuubi
node的数据为:
[zk: zk1:2181(CONNECTED) 2] ls /kyuubi
[serviceUri=0.0.0.0:10009;version=1.9.2;sequence=0000000006, serviceUri=0.0.0.0:10009;version=1.9.2;sequence=0000000007, serviceri=0.0.0.0:10009;version=1.9.2;sequence=0000000008]
明显可以看出三个节点的serviceUri完全相同,这样HA是无法工作的。
-
kyuubi.ha.zookeeper.auth.principal
使用kyuubi/_HOST@PAULTECH.COM
。hostname部分使用_HOST
。
最后依次在各个节点的Kyuubi安装目录,执行bin/kyuubi start
,启动kyuubi。
权限配置
Kyuubi要求kyuubi
用户必须要有访问HDFS数据目录(表数据的存放目录)和home目录(/user/kyuubi
)的权限,以及提交任务到Yarn队列的权限。在启动Kyuubi服务之前需要通过Ranger配置kyuubi
具有上述权限。
启动服务
kyuubi服务启动/停止/重启:
bin/kyuubi start/stop/restart
如果启用了HA,可在多个节点使用相同配置启动多个Kyuubi Server实例。参见前面章节。
连接Kyuubi
连接Kerberos认证的集群前需要kinit:
kinit kyuubi/hostname@PAULTECH -kt /etc/security/keytabs/kyuubi.keytab
以下命令需要进入到Kyuubi安装目录的bin
目录执行。
非HA方式连接:
./beeline -u 'jdbc:hive2://kyuubi_server:10009/;principal=kyuubi/_HOST@PAULTECH'
HA方式连接:
./beeline -u 'jdbc:hive2://zk1:2181,zk2:2181,zk3:2181/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=kyuubi;principal=kyuubi/_HOST@PAULTECH'
注意,非Kerberos集群使用无需指定principal
参数。指定用户名使用-n 用户名方式
,如下所示:
./beeline -u 'jdbc:hive2://zk1:2181,zk2:2181,zk3:2181/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=kyuubi' -n kyuubi
连接URL参数解析:
- serviceDiscoveryMode:
zooKeeper
表示使用Zookeeper作为服务发现,配置HA的时候使用。 - zooKeeperNamespace: 对应
kyuubi-defaults.conf
中的kyuubi.ha.namespace
。zk命名空间。 - principal: 连接Kerberos集群的时候需要指定Kyuubi的principal。和
kyuubi-defaults.conf
中的kyuubi.kinit.principal
相同。否则会认证失败。
多租户
Kyuubi在设计上支持多租户。目前Spark Engine对多租户的支持最为完善。使用租户身份连接Kyuubi server有如下两种方法。
方法一
kinit Kyuubi Server启动用户对应的principal。连接URL中principal
配置Kyuubi Server用户对应的principal。然后在连接URL后增加hive.server2.proxy.user
参数,指定使用哪个租户。要求租户需要具有HDFS访问权限和Yarn队列提交任务权限。
例如租户为paul
时,我们执行:
./beeline -u 'jdbc:hive2://zk1:2181,zk2:2181,zk3:2181/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=kyuubi;principal=kyuubi/_HOST@PAULTECH;hive.server2.proxy.user=paul'
可以看到Kyuubi engine启动执行spark-submit
使用的--proxy-user
参数为paul
。
方法二
kinit租户对应的principal。连接URL中principal
配置Kyuubi Server用户对应的principal。
需要注意:如果租户访问(例如使用beeline)和Kyuubi Server在同一个节点时,不要和Kyuubi Server公用一个ticket cache。建议切换到其他Linux用户再执行kinit。
然后执行如下命令。不再需要添加hive.server2.proxy.user
参数。
./beeline -u 'jdbc:hive2://zk1:2181,zk2:2181,zk3:2181/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=kyuubi;principal=kyuubi/_HOST@PAULTECH'
使用JDBC方式连接
使用JDBC方式连接Kyuubi首先需要获取Kyuubi的JDBC驱动。可以在Maven中配置,从Maven中央仓库下载。例如:
<dependency>
<groupId>org.apache.kyuubi</groupId>
<artifactId>kyuubi-hive-jdbc-shaded</artifactId>
<version>1.9.2</version>
</dependency>
或者是使用自己编译出来的驱动。驱动编译输出的位置在kyuubi/kyuubi-hive-jdbc-shaded/target
中。
在pom.xml
中配置使用本地依赖包:
<dependency>
<groupId>org.apache.kyuubi</groupId>
<artifactId>kyuubi-hive-jdbc-shaded</artifactId>
<version>1.9.2</version>
<scope>system</scope>
<systemPath>/path/to/kyuubi-hive-jdbc-shaded-1.9.2.jar</systemPath>
</dependency>
一段示例程序如下。该程序连接Kyuubi集群,执行show databases
。
Class.forName("org.apache.kyuubi.jdbc.KyuubiHiveDriver");
Connection connection = DriverManager.getConnection("jdbc:hive2://zk1:2181,zk2:2181,zk3:2181/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=kyuubi;#kyuubi.engine.type=SPARK_SQL", "hdfs", "");
Statement statement = connection.createStatement();
statement.execute("show databases");
while (statement.getResultSet().next()) {
System.out.println(statement.getResultSet().getString(1));
}
statement.close();
connection.close();
参考链接:https://kyuubi.readthedocs.io/en/master/client/jdbc/kyuubi_jdbc.html
使用Zeppelin操作Kyuubi
Zeppelin可以通过JDBC interpreter连接到Kyuubi server。
登录Zeppelin后打开右上方的菜单,选择Interpreter。搜索到jdbc。然后修改如下配置。示例如下:
- default.url: jdbc:hive2://zk1:2181,zk2:2181,zk3:2181/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=kyuubi;#kyuubi.engine.type=SPARK_SQL
- default.user: hdfs
- default.driver: org.apache.kyuubi.jdbc.KyuubiHiveDriver
不要忘了在下方的Dependencies增加Kyuubi JDBC驱动在Maven仓库的GAV坐标,例如:
Artifact: org.apache.kyuubi:kyuubi-hive-jdbc-shaded:1.9.2
GAV信息可在该网站中查找:https://mvnrepository.com/artifact/org.apache.kyuubi/kyuubi-hive-jdbc-shaded/
保存之后新建一个note,选择使用jdbc解释器。就可以使用Zeppelin操作Kyuubi了。