Spark读取Hive的三种方式
- 直接读数据源
- HiveJDBC
- 配置文件
直接读数据源
因为hive只是起到映射的作用,所以最简单、直观的方式就是直接读取数据的存储组件(HDFS\HBASE)
HiveJDBC
spark读hive的jdbc没写过,不过应该和mysql的差不多,直接贴代码
val properties = new Properties()
properties.put("user",HIVE_USER)
properties.put("password",HIVE_PASSWORD)
properties.put("driver",HIVE_DRIVER)
spark.read.jdbc("jdbc:hive2://IP:10000/bigdata",sql,properties)
看起来毫无问题,拿mysql做实验也能准确读出数据,下面看读hive的输出:
+----+------+-----+------+--------+
|c.id|c.name|c.age|c.city|c.s_date|
+----+------+-----+------+--------+
|c.id|c.name|c.age|c.city|c.s_date|
|c.id|c.name|c.age|c.city|c.s_date|
|c.id|c.name|c.age|c.city|c.s_date|
|c.id|c.name|c.age|c.city|c.s_date|
+----+------+-----+------+--------+
看起来不太对劲,跟代码进去,看看执行了什么操作,于是:
select "c.id","c.name","c.age","c.city","c.s_date" from c
原来最后执行的sql张这个样子,怪不得查出来的都是字段名称的字符串。
分析问题应该是处理hive的转译符出错了,那继续跟代码看有什么地方可以设置。……最后悲剧的发现spark根本没添加HiveJDBC
registerDialect(MySQLDialect)
registerDialect(PostgresDialect)
registerDialect(DB2Dialect)
registerDialect(MsSqlServerDialect)
registerDialect(DerbyDialect)
registerDialect(OracleDialect)
不过没关系,经观察发现这些Dialect都继承了JdbcDialect类,并重写了canHandle和quoteIdentifier方法,直接上代码
private case object HiveSqlDialect extends JdbcDialect {
override def canHandle(url : String): Boolean = url.startsWith("jdbc:hive2")
override def quoteIdentifier(colName: String): String = {
s"转译符$colName转译符"
}
}
最后再把你写的Dialect添加到JdbcDialects中
static {
HiveSqlDialect hiveSqlDialect_ = new HiveSqlDialect();
JdbcDialects.registerDialect(hiveSqlDialect_);
}
之后就跟操作mysql一样没差别了
配置文件
这种方式是官方所提供的,并且在网上搜到的大部分链接方式都是这种需要在client端配置hive-site.xml文件的方式,linux环境下需要将该文件放入到resources文件夹下即可,如果想要在windows本地运行需要以下几步:
1:本机配置hadoop环境变量
在该地址下载hadoop对应版本,然后解压配置HADOOP_HOME
2:然后依次下载hadoop.dll、libwinutils.lib、winutils.exe,并放入到%HADOOP_HOME%\bin下,到此本机环境配置完毕
3:编写hive-site.xml文件并放到resources下面
<configuration>
<property>
<name>hive.metastore.local</name>
<value>false</value>
</property>
<property>
<name>hive.metastore.uris</name>
<value>thrift://IP:9083</value>
</property>
<property>
<name>hive.server2.thrift.port</name>
<value>10000</value>
</property>
<property>
<name>fs.defaultFS</name>
<value>hdfs://IP:8020</value>
</property>
<property>
<name>hive.metastore.warehouse.dir</name>
<value>HIVE所配置HDFS地址</value>
</property>
<property>
<name>beeline.hs2.connection.user</name>
<value>username</value>
</property>
<property>
<name>beeline.hs2.connection.password</name>
<value>password</value>
</property>
</configuration>
4:最后在创建Session的时候添加一个enableHiveSupport(),并设置一个系统变量hadoop.home.dir指向你本机的HADOOP_HOME即可
val spark: SparkSession = SparkSession
.builder()
.enableHiveSupport()
.appName("downloadSyncData")
.master("local[2]")
.getOrCreate()
System.setProperty("hadoop.home.dir","D:\\Program\\hadoop-2.7.6")
spark.sql("select * from bigdata.schema_test").show()