Spark整合Hive
- 整合hive元数据metadata
- Hive 的 MetaStore 是一个 Hive 的组件
- 而 Hive 的 MetaStore 的运行模式有三种
- Hive开启元数据服务
- 如果没有添加下面这一段,启动spark会报错
- 启动hive元数据服务
- 同时需要加载其他配置,包括HDFS
- 测试
整合hive元数据metadata
- MetaStore, 元数据存储
SparkSQL 内置的有一个 MetaStore, 通过嵌入式数据库 Derby 保存元信息, 但是对于生产环境来说, 还是应该使用 Hive 的 MetaStore, 一是更成熟, 功能更强, 二是可以使用 Hive 的元信息 - 查询引擎
SparkSQL 内置了 HiveSQL 的支持, 所以无需整合
Hive 的 MetaStore 是一个 Hive 的组件
由上图可知道, 其实 Hive 中主要的组件就三个, HiveServer2 负责接受外部系统的查询请求, 例如 JDBC, HiveServer2 接收到查询请求后, 交给 Driver 处理, Driver 会首先去询问 MetaStore 表在哪存, 后 Driver 程序通过 MR 程序来访问 HDFS 从而获取结果返回给查询请求者
而 Hive 的 MetaStore 对 SparkSQL 的意义非常重大, 如果 SparkSQL 可以直接访问 Hive 的 MetaStore, 则理论上可以做到和 Hive 一样的事情, 例如通过 Hive 表查询数据
而 Hive 的 MetaStore 的运行模式有三种
- 内嵌 Derby 数据库模式
这种模式不必说了, 自然是在测试的时候使用, 生产环境不太可能使用嵌入式数据库, 一是不稳定, 二是这个 Derby 是单连接的, 不支持并发 - Local 模式
Local 和 Remote 都是访问 MySQL 数据库作为存储元数据的地方, 但是 Local 模式的 MetaStore 没有独立进程, 依附于 HiveServer2 的进程 - Remote 模式
和 Loca 模式一样, 访问 MySQL 数据库存放元数据, 但是 Remote 的 MetaStore 运行在独立的进程中
Hive开启元数据服务
[root@node01 apache-hive-2.1.1-bin]# cat conf/hive-site.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>123456</value>
</property>
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://node03:3306/hive?createDatabaseIfNotExist=true&useSSL=false</value>
</property>
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
</property>
<property>
<name>hive.metastore.schema.verification</name>
<value>false</value>
</property>
<property>
<name>datanucleus.schema.autoCreateAll</name>
<value>true</value>
</property>
<property>
<name>hive.cli.print.current.db</name>
<value>true</value>
</property>
<property>
<name>hive.cli.print.header</name>
<value>true</value>
</property>
<property>
<name>hive.server2.thrift.bind.host</name>
<value>node03</value>
</property>
<property>
<name>hive.metastore.uris</name>
<value>thrift://node03:9083</value>
</property>
<property>
<name>hive.metastore.client.socket.timeout</name>
<value>3600</value>
</property>
<!--这一段配置是重点,将元数据访问配置为remote模式-->
<property>
<name>hive.metastore.local</name>
<value>false</value>
</property>
</configuration>
如果没有添加下面这一段,启动spark会报错
<!--这一段配置是重点,将元数据访问配置为remote模式-->
<property>
<name>hive.metastore.local</name>
<value>false</value>
</property>
错误如下:
19/10/06 18:25:19 WARN hive.metastore: Failed to connect to the MetaStore Server...
19/10/06 18:25:20 WARN hive.metastore: Failed to connect to the MetaStore Server...
19/10/06 18:25:21 WARN hive.metastore: Failed to connect to the MetaStore Server...
19/10/06 18:25:22 WARN metadata.Hive: Failed to access metastore. This class should not accessed in runtime.
org.apache.hadoop.hive.ql.metadata.HiveException: java.lang.RuntimeException: Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient
Caused by: java.lang.reflect.InvocationTargetException: org.apache.hadoop.hive.metastore.api.MetaException: Could not connect to meta store using any of the URIs provided. Most recent failure: org.apache.thrift.transport.TTransportException: java.net.ConnectException: Connection refused (Connection refused)
启动hive元数据服务
- 前提是启动了mysql服务(存储元数据)
service mysqld start
nohup bin/hive --service metastore &
nohup bin/hive --service hiveserver2 &
同时需要加载其他配置,包括HDFS
即使不去整合 MetaStore, Spark 也有一个内置的 MateStore, 使用 Derby 嵌入式数据库保存数据, 但是这种方式不适合生产环境, 因为这种模式同一时间只能有一个 SparkSession 使用, 所以生产环境更推荐使用 Hive 的 MetaStore
SparkSQL 整合 Hive 的 MetaStore 主要思路就是要通过配置能够访问它, 并且能够使用 HDFS 保存 WareHouse, 这些配置信息一般存在于 Hadoop 和 HDFS 的配置文件中, 所以可以直接拷贝 Hadoop 和 Hive 的配置文件到 Spark 的配置目录
cd /export/servers/hadoop/etc/hadoop
cp hive-site.xml core-site.xml hdfs-site.xml /export/servers/spark/conf/
scp -r /export/servers/spark/conf node02:/export/servers/spark/conf
scp -r /export/servers/spark/conf node03:/export/servers/spark/conf
hive-site.xml : 要读取 Hive 的配置信息, 主要是元数据仓库的位置等信息
core-site.xml : 读取安全有关的配置
hdfs-site.xml: 有可能需要在 HDFS 中放置表文件, 所以需要 HDFS 的配置
测试
# 在hdfs中创建文件夹
hdfs dfs -mkdir -p /dataset
# 测试数据,要将该数据加载到创建的hive表中
vim stu
xjm 22 xjm
hhj 22 hhj
# 上传本地文件
hdfs dfs -put stu /dataset/
# 进入hive客户端创建hive表
bin/hive
CREATE DATABASE IF NOT EXISTS spark_integrition;
USE spark_integrition;
CREATE EXTERNAL TABLE student
(
name STRING,
age INT,
gpa string
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
LINES TERMINATED BY '\n'
STORED AS TEXTFILE
LOCATION '/dataset/hive';
LOAD DATA INPATH '/dataset/stu' OVERWRITE INTO TABLE student;
# 启动spark,进入spark中sbin目录
./start-all.sh
# 开启一个客户端,进入bin目录
./spark-shell
...
Type in expressions to have them evaluated.
Type :help for more information.
scala> spark.sql
sql sqlContext
scala> spark.sql
def sql(sqlText: String): org.apache.spark.sql.DataFrame
scala> spark.sql("use spark_integrition")
res0: org.apache.spark.sql.DataFrame = []
scala> val resDF = spark.sql("select * from student limit 10")
resDF: org.apache.spark.sql.DataFrame = [name: string, age: int ... 1 more field]
scala> resDF.show()
+----+---+---+
|name|age|gpa|
+----+---+---+
| xjm| 22|xjm|
| hhj| 22|hhj|
+----+---+---+