Hive的hiveserver2和beeline的使用以及spark thritfserver的启动
- Hive 的hiveserver2介绍
- hiveserver2 的配置
- beeline连接hiveserver2
- 配置hiveserver2的界面
- spark thriftserver的配置
- beeline 连接spark thriftserver
- thriftserver和spark-sql对比
- spark sql 程序连接thriftserver
Hive 的hiveserver2介绍
HiveServer2 (HS2) 是一项使客户端能够针对 Hive 执行查询的服务。 HiveServer2 是已弃用的 HiveServer1 的继任者。 HS2 支持多客户端并发和认证。它旨在为开放 API 客户端(如 JDBC 和 ODBC)提供更好的支持。 HS2 是作为复合服务运行的单个进程,其中包括基于 Thrift 的 Hive 服务(TCP 或 HTTP)和用于 Web UI 的 Jetty Web 服务器。
hiveserver2 的配置
需要在
/hive/conf/hive-site.xml
中配置
hive.server2.thrift.min.worker.threads – 最小工作线程,默认 5.
hive.server2.thrift.max.worker.threads – 最大工作线程,默认 500.
hive.server2.thrift.port – 监听端口, 默认 10000.
hive.server2.thrift.bind.host – 绑定的地址.
比如
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<!-- hive 的元数据存储路径,使用mysql存储 -->
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://hadoop01:3306/hive?createDatabaseIfNotExist=true</value>
</property>
<!-- 数据库驱动 -->
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.cj.jdbc.Driver</value>
</property>
<!-- 数据库用户名 -->
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
</property>
<!-- 数据库密码 -->
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>123456</value>
</property>
<!-- 是否进行版本校验 -->
<property>
<name>hive.metastore.schema.verification</name>
<value>false</value>
</property>
<!-- 权限处理 -->
<property>
<name>hive.server2.enable.doAs</name>
<value>false</value>
</property>
<!-- 最小工作线程,默认5 -->
<property>
<name>hive.server2.thrift.min.worker.threads</name>
<value>2</value>
</property>
<!-- 最大工作线程,默认500 -->
<property>
<name>hive.server2.thrift.max.worker.threads</name>
<value>5</value>
</property>
<!-- 绑定端口,默认10000 -->
<property>
<name>hive.server2.thrift.port</name>
<value>10000</value>
</property>
<!-- 绑定地址,默认0.0.0.0 -->
<property>
<name>hive.server2.thrift.bind.host</name>
<value>0.0.0.0</value>
</property>
</configuration>
因为使用了mysql数据库存储hive的元数据,所以需要从网上下载mysql的驱动包
从Maven Repository: mysql » mysql-connector-java (mvnrepository.com)下载就行
8.0.23版本
下载地址https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.23/mysql-connector-java-8.0.23.jar
下载后拷贝到
/hive/lib
目录下

接着启动mysql
接着启动hdfs
启动spark集群
启动spark-history
启动hiveserver2
也可以使用
nohup ./hiveserver2 &
在后台启动hiveserver2,将输出写入nohup文件
可以使用
jps -m
查看运行的hiveserver2进程
beeline连接hiveserver2
当启动hiveserver2之后,就可以使用beeline进行连接了。
hiveserver2是服务端,而beeline是hive自带的一个客户端,除了使用beeline,还可以使用代码连接hiveserver2服务端。
使用beeline连接需要指定连接url
jdbc:hive2://hadoop01:10000
比如使用如下命令连接
beeline -u jdbc:hive2://hadoop01:10000 -n hadoop01
其中
-u
指定连接url,
-n
指定客户端的用户名
查询
和使用mysql非常类似
输入
help
查看帮助
可以看到beeline的命令都是以
!
开头的。
配置hiveserver2的界面
可以在
/hive/conf/hive-site.xml
中配置和webUI相关的配置
<!-- hive 界面绑定地址 -->
<property>
<name>hive.server2.webui.host</name>
<value>0.0.0.0</value>
</property>
<!-- hive 界面端口 -->
<property>
<name>hive.server2.webui.port</name>
<value>8085</value>
</property>
<!-- hive 界面最大线程 -->
<property>
<name>hive.server2.webui.max.threads</name>
<value>5</value>
</property>
然后重新启动hiveserver2
需要先杀掉原来启动的hiveserver2,然后重新启动
接着就能访问hive的界面了
启动一个beeline连接,使用用户名hadoop01
在启动beeline连接hiveserver2的时候,可以像jdbc的连接url一样,指定database
比如
beeline -u jdbc:hive2://hadoop01:10000/test_column -n hadoop01
而且在连接url中指定database后,连接了就会自动切换到指定的database上的。
查看界面
还可以启动更多的beeline,在同一个机器上也可以的
在同一个机器上启动两个beeline,使用
-n
参数区分
每个beeline上查询,然后查看界面
spark thriftserver的配置
使用spark-submit和spark-sql,每次执行一个sql,实际上都会产生一个spark application用于执行spark任务,如果执行的比较多的sql,就会频繁的创建spark application,这样就会在一定程度上耗费资源。为了实现spark application的复用,spark基本上把hive的hiveserver2照搬了过来,产生了 spark thriftserver,在使用thriftserver的时候,就能够复用spark application。
不过生产环境中每个查询因为数据量巨大,而且基本处于独立的查询操作,所以是不会使用thriftserver和hiveserver2的,这在开发中可能用的比较多。
简单点说,spark thriftserver和hiveserver2是一样的。
只需要把
/hive/conf/hive-site.xml
拷贝到
/spark/conf
目录下即可
然后启动spark thriftserver即可
在spark的官网文档中(spark-sql模块下)说明spark-thriftserver的脚本
start-thriftserver.sh
接受和spark-submit一样的参数
通过上面这句话,就基本上可以猜测出来启动thriftserver需要哪些参数了,当然也可以通过help查看
所以可以使用如下命令启动thriftserver
./start-thriftserver.sh --master spark://hadoop01:4040 --jars /hive/lib/mysql-connector-java-8.0.27.jar --driver-class-path /hive/lib/mysql-connector-java-8.0.27.jar
启动后需要手动查看日志
启动出现了异常,提示地址已经被使用了,说白了就是端口冲突,因为hiveserver2还是启动,hiveserver2绑定了10000端口,而spark thriftserver启动也需要绑定10000端口,就冲突了。
所以修改spark thriftserver的端口为10001
当然thriftserver的界面集成到了spark的界面中了,这里的8084应该是无效的
重新启动
启动日志无报错后刷新spark集群的界面
进入application的界面后会多出来两个tab
访问8084界面无响应,说明在
/spark/conf/hive-site.xml
中配置的界面端口无效
beeline 连接spark thriftserver
使用beeline连接spark thriftserver和使用beeline连接hiveserver2完全相同
使用
beeline -u jdbc:hive2://hadoop01:10001/test_column -n sparkbeeline
连接
thriftserver和spark-sql对比
thriftserver和spark-sql都能直接执行sql语句,区别在于多个beeline连接同一个thriftserver,共用一个application,而启动多个spark-sql就会启动多个application
比如首先在beeline连接的thriftserver中执行两次sql
刷新spark界面,并没有增加完成的application
停止thriftserver,因为thriftserver占用了全部集群中的两个核心(实际是我分配的核心太少了),thriftserver会自动占用每个driver的一个核心,我配置每个worker只启动一个driver,每个driver只有一个核心,所以thriftserver就占用了全部的核心。
接着启动spar-sql,占用一个核心
使用
spark-sql --num-executors 1 --master spark://hadoop01:4040 --jars /hive/lib/mysql-connector-java-8.0.27.jar --driver-class-path /hive/lib/mysql-connector-java-8.0.27.jar
启动spark-sql,要求只占用一个executor
可惜的是,即使指定了
--num-executors
也没有生效,spark-sql又占用了全部核心
接着执行一个sql
执行发现,好像和预期的不一样,也是所有的sql使用同一个application
在启动一个spark-sql
此时查看spark界面,发现是两个application
证明了每个spark-sql实例对应一个application(没有分配到资源请忽略)
接着启动thriftserver
接着启动一个beeline
启动了两个beeline,连接同一个thriftserver,但是却只有一个application
这就是spark-sql与thriftserver最大的区别
spark sql 程序连接thriftserver
使用spark-submit和spark-sql,每次执行一个sql,实际上都会产生一个spark application用于执行spark任务,如果执行的比较多的sql,就会频繁的创建spark application,这样就会在一定程度上耗费资源。为了实现spark application的复用,spark基本上把hive的hiveserver2照搬了过来,产生了 spark thriftserver,在使用thriftserver的时候,就能够复用spark application。
不过生产环境中每个查询因为数据量巨大,而且基本处于独立的查询操作,所以是不会使用thriftserver和hiveserver2的,这在开发中可能用的比较多。
要使用thriftserver就需要在依赖中加入hive-jdbc的依赖(前面说了,spark的thriftserver就是照搬hiveserver2的)
Maven Repository: org.apache.hive » hive-jdbc » 3.1.2 (mvnrepository.com)
直接增加会因为无法下载
jdk-tools:jdk-toos.jar:1.6
报错,无法下载
在实际测试中,这个确实比较恶心,网上有一种解决方案是自己下载依赖,然后使用maven本地安装,然后在加载依赖,经过测试,没用。
我自己的解决方案是不管他,报红就使用排除
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-jdbc</artifactId>
<version>${hive.jdbc.version}</version>
<exclusions>
<exclusion>
<groupId>jdk.tools</groupId>
<artifactId>jdk.tools</artifactId>
</exclusion>
</exclusions>
</dependency>
然后在根目录下使用maven命令下载依赖
mvn dependency:sources
下载源码和依赖,然后重新加载maven项目,此时会把除了jdk.tools之外的依赖加入到项目中
接着就可以开始编码了
import java.sql.DriverManager
object SparkThriftServerApp {
def main(args: Array[String]): Unit = {
// 1. 加载驱动
Class.forName("org.apache.hive.jdbc.HiveDriver")
// 2. 获取连接,用户名密码如果没有随便写,这里和beeline连接thriftserver是一样的
val coon = DriverManager getConnection("jdbc:hive2://hadoop01:10000/test_column", "root", "")
// 3. 编写查询sql
val pstmt = coon prepareStatement "select * from columns limit 10"
// 4. 查询
val rs = pstmt executeQuery()
// 5. 获取返回结果的元数据信息 --- 表头
val metaData = rs getMetaData()
// 6. 使用可变列表存储表头
var columsArray = List[String]()
// 7. 循环打印表头,切记从 1 开始,不是从 0 开始
for(i <- Range(1, metaData getColumnCount) inclusive) {
columsArray = columsArray :+ (metaData getColumnName i)
print(s"${metaData getColumnName i}\t")
}
println
// 8. 循环读取数据,也是从 1 开始,不是从 0 开始
while (rs next()) {
for (i <- Range(1, columsArray length) inclusive) {
print(s"${rs getString(i)}\t")
}
println
}
// 9. 关闭连接
rs close()
pstmt close()
coon close()
}
}
执行结果如下
也可以在thriftserver的监控界面查看执行的sql