Spark3.4.0入门-连接Hive读写数据(DataFrame)


title: Spark3.4.0入门-连接Hive读写数据(DataFrame)
date: 2024-03-11 23:25:49
description: 大数据spark学习
cover: https://elik-1307874295.cos.ap-guangzhou.myqcloud.com/images/md_picture/bigdata/large-895567_1280.webp?imageSlim
aside: true
sticky: 1
categories:

  • spark_learn
    tags:
  • spark

让Spark包含Hive支持

测试是否支持

为了让Spark能够访问Hive,必须为Spark添加Hive支持。Spark官方提供的预编译版本,通常是不包含Hive支持的,需要采用源码编译,编译得到一个包含Hive支持的Spark版本,然后采用我们之前在“Spark安装和使用”部分介绍的方法安装Spark。

测试一下电脑上已经安装的Spark版本是否支持Hive
现在让我们测试一下自己电脑上已经安装的Spark版本是否支持Hive。请请登录Linux系统,打开一个终端,然后,执行下面命令:

cd /usr/local/spark
./bin/spark-shell

这样就启动进入了spark-shell,然后在scala命令提示符下输入:
scala> import org.apache.spark.sql.hive.HiveContext
:25: error: object hive is not a member of package org.apache.spark.sql
import org.apache.spark.sql.hive.HiveContext
^
看到了吧,会返回错误信息,也就是spark无法识别org.apache.spark.sql.hive.HiveContext,这就说明你当前电脑上的Spark版本不包含Hive支持。

如果你当前电脑上的Spark版本包含Hive支持,那么应该显示下面的正确信息:

scala> import org.apache.spark.sql.hive.HiveContext
import org.apache.spark.sql.hive.HiveContext

实现支持hive的spark版本

采用源码编译方法得到支持Hive的Spark版本
经过上面测试,如果你当前电脑上的Spark版本包含Hive支持,那就可以不用进行下面的源码编译步骤。如果你当前电脑上的Spark版本不包含Hive支持,请根据下面教程编译一个包含Hive支持的Spark版本。
(备注:笔者已经把我电脑编译成功的spark-3.4.0-bin-h335hive.tgz文件上传到了百度云盘(文件大小170MB,下载地址:https://cloud.189.cn/t/M7r22uq6jeYz (访问码:4g68)),所以,你或者可以按照下面的方法自己编译,或者可以直接下载我们已经编译成功的版本)
请登录Linux系统,打开一个火狐(Firefox)浏览器。在Linux系统的火狐浏览器中,请点击这里访问Spark官网下载Spark源码版本(或者直接把下载地址复制到火狐浏览器中打开之前版本下载官网,下载地址是: {% btn ‘https://archive.apache.org/dist/spark/’,AnZhiYu,anzhiyufont anzhiyu-icon-circle-arrow-right %}
进入这个官网后,可以查找spark的旧版本下载,在这里我们找到spark3.4.0
下载好spark-3.4.0.tgz,解压缩到/home/hadoop/目录下

sudo tar -zxf ./spark-3.4.0.tgz -C /home/hadoop/

cd /home/hadoop
ls #这时可以看到解压得到的文件夹spark-3.4.0

{% emp 重点来了 %}
我们要进行源码编译,并且在编译命令中设置一些选项,从而让Spark支持Hive。
在编译时,需要给出你电脑上之前已经安装好的Hadoop的版本。如何查询Hadoop版本号呢?请使用下面命令查询:
hadoop version
运行上面命令后,就会显示Hadoop版本信息。笔者电脑上的Hadoop版本信息是3.3.5。

下面,就可以运行编译命令,对Spark源码进行编译,让它支持Hive,命令如下:

cd /home/hadoop/spark-3.4.0
./dev/make-distribution.sh --tgz --name h335hive -Pyarn -Phadoop-3.3 -Dhadoop.version=3.3.5 -Phive -Phive-thriftserver -DskipTests

其中,-Phadoop-3.3 -Dhadoop.version=3.3.5 指定安装spark时的hadoop版本,一定要对应,这个hadoop版本是你当前电脑上已经安装的Hadoop的版本。 -Phive -Phive-thriftserver这两个选项让其支持Hive。 -DskipTests能避免测试不通过时发生的错误。
这个是笔者编译后的结果

笔者打包程序耗费了1个小时,结果打包后保存在/hadoop/saprk3.4/spark-3-4-0-bin-h335hive
上面命令中“h335hive”只是我们给编译以后的文件的一个名称,最终编译成功后会得到文件名“spark-3.4.0-bin-h335hive.tgz”,这个就是包含Hive支持的Spark安装文件。
上述编译命令运行时间,根据电脑和网络情况,耗费的时间不一样,笔者电脑编译了1个多小时,中间{% u 如果编译过程还会发生网络故障导致编译失败,那就只能重新编译。 %}

安装支持Hive的Spark版本

我们在此前的Spark安装章节已经在电脑上安装了一个Spark版本(不支持Hive),当时的安装目录是“/usr/local/spark”。我们不需要卸载以前这个已经安装成功的Spark版本(不支持Hive),只需要把新的Spark版本(包含Hive支持)安装在另外一个名字为sparkwithhive的目录下即可。而且,安装成功以后,可以分别打开两个终端窗口,第一个终端窗口中启动spark-shell(不支持Hive),同时在第二个终端窗口中启动spark-shell(包含Hive支持),二者可以同时运行。
好的,下面就开始安装新的Spark版本(包含Hive支持),命令如下:

cd /home/hadoop/下载/
sudo tar -zxf ~/下载/spark-3.4.0-bin-h335hive.tgz -C /usr/local

#执行上面的解压缩命令时需要你输入当前登录用户的登录密码

cd /usr/local
sudo mv ./spark-3.4.0-bin-h335hive ./sparkwithhive
sudo chown -R hadoop:hadoop ./sparkwithhive
cd /usr/local/sparkwithhive/
cp ./conf/spark-env.sh.template ./conf/spark-env.sh
vim ./conf/spark-env.sh

上面用vim编辑器打开了spark-env.sh文件,请在这个文件的开头第一行增加一行如下内容:
export SPARK_DIST_CLASSPATH=$(/usr/local/hadoop/bin/hadoop classpath)
然后,保存文件,退出vim编辑器,继续执行下面命令:

cd /usr/local/spark
cd /usr/local/sparkwithhive

#下面运行一个样例程序,测试是否成功安装

bin/run-example SparkPi 2>&1 | grep "Pi is"
如果能够得到下面信息,就说明成功了。

Pi is roughly 3.146315731578658
为了让Spark能够访问Hive,需要把Hive的配置文件hive-site.xml拷贝到Spark的conf目录下,请在Shell命令提示符状态下操作:

cd /usr/local/sparkwithhive/conf
cp /usr/local/hive/conf/hive-site.xml .

然后,就可以启动进入spark-shell,命令如下:

cd /usr/local/sparkwithhive
./bin/spark-shell

这样就启动了spark-shell,进入了“scala>”命令提示符状态,请输入下面语句:

scala> import org.apache.spark.sql.hive.HiveContext
import org.apache.spark.sql.hive.HiveContext

看到上面的信息,说明你当前启动的Spark版本可以支持Hive,恭喜你,可以进行下面的Hive数据读写实验了。

实验

二、在Hive中创建数据库和表

首先、启动hadoop mysql hive

登录Linux系统(本教程统一采用hadoop用户名登录),打开一个终端,进入Shell命令提示符状态。因为需要借助于MySQL保存Hive的元数据,所以,请首先启动MySQL数据库:

service mysql start #可以在Linux的任何目录下执行该命令

由于Hive是基于Hadoop的数据仓库,使用HiveQL语言撰写的查询语句,最终都会被Hive自动解析成MapReduce任务由Hadoop去具体执行,因此,需要启动Hadoop,然后再启动Hive。
然后执行以下命令启动Hadoop:

cd /usr/local/hadoop
./sbin/start-all.sh

Hadoop启动成功以后,可以再启动Hive:

cd /usr/local/hive
./bin/hive  #由于已经配置了path环境变量,这里也可以直接使用hive,不加路径

通过上述过程,我们就完成了MySQL、Hadoop和Hive三者的启动。

其次、进入hive

下面我们进入Hive,新建一个数据库sparktest,并在这个数据库下面创建一个表student,并录入两条数据。
下面操作请在Hive命令提示符下操作:
hive> create database if not exists sparktest;//创建数据库sparktest
hive> show databases; //显示一下是否创建出了sparktest数据库
//下面在数据库sparktest中创建一个表student

hive> create table if not exists sparktest.student(
> id int,
> name string,
> gender string,
> age int);
hive> use sparktest; //切换到sparktest
hive> show tables; //显示sparktest数据库下面有哪些表
hive> insert into student values(1,'Xueqian','F',23); //插入一条记录
hive> insert into student values(2,'Weiliang','M',24); //再插入一条记录
hive> select * from student; //显示student表中的记录

通过上面操作,我们就在Hive中创建了sparktest.student表,这个表有两条数据。

其三、连接Hive读写数据

现在我们看如何使用Spark读写Hive中的数据。注意,操作到这里之前,你一定已经按照前面的各个操作步骤,启动了Hadoop、Hive、MySQL和spark-shell(包含Hive支持)。
在进行编程之前,我们需要做一些准备工作,我们需要修改“/usr/local/sparkwithhive/conf/spark-env.sh”这个配置文件:

cd /usr/local/sparkwithhive/conf/
vim spark-env.sh

这样就使用vim编辑器打开了spark-env.sh这个文件,这文件里面以前可能包含一些配置信息,全部删除,然后输入下面内容:

export SPARK_DIST_CLASSPATH=$(/usr/local/hadoop/bin/hadoop classpath)
export JAVA_HOME=/usr/lib/jvm/jdk1.8.0_371
export CLASSPATH=$CLASSPATH:/usr/local/hive/lib
export SCALA_HOME=/usr/local/scala
export HADOOP_CONF_DIR=/usr/local/hadoop/etc/hadoop
export HIVE_CONF_DIR=/usr/local/hive/conf
export SPARK_CLASSPATH=$SPARK_CLASSPATH:/usr/local/hive/lib/mysql-connector-java-8.0.13.jar

保存spark-env.sh这个文件,退出vim编辑器。

还有的是:把/hive/lib/mysql-connector-java-8.0.13.jar 拷贝到sparkwithhive/jars里面,使其有驱动支持

其四,操作

好了,经过了前面如此漫长的准备过程,现在终于可以编写调试Spark连接Hive读写数据的代码了。
下面,请在spark-shell(包含Hive支持)中执行以下命令从Hive中读取数据:

读取数据
Scala> import org.apache.spark.sql.Row
Scala> import org.apache.spark.sql.SparkSession
 
Scala> case class Record(key: Int, value: String)
 
// warehouseLocation points to the default location for managed databases and tables
Scala> val warehouseLocation = "spark-warehouse"
 
Scala> val spark = SparkSession.builder().appName("Spark Hive Example").config("spark.sql.warehouse.dir", warehouseLocation).enableHiveSupport().getOrCreate()
 
Scala> import spark.implicits._
Scala> import spark.sql
//下面是运行结果
scala> sql("SELECT * FROM sparktest.student").show()
+---+--------+------+---+
| id|    name|gender|age|
+---+--------+------+---+
|  1| Xueqian|     F| 23|
|  2|Weiliang|     M| 24|
+---+--------+------+---+

下面,请在spark-shell(包含Hive支持)中执行以下命令向Hive中写入数据。为了对比插入数据前后Hive中的数据变化,首先,请打开一个终端窗口,启动Hive:

cd /usr/local/hive
./bin/hive

启动后就进入了hive命令提示符状态,然后输入如下命令查看sparktest.student表中的数据:

hive> use sparktest;
OK
Time taken: 0.016 seconds

hive> select * from student;
OK
1 Xueqian F 23
2 Weiliang M 24
Time taken: 0.05 seconds, Fetched: 2 row(s)
hive

插入数据

下面,我们编写程序向Hive数据库的sparktest.student表中插入两条数据,请切换到spark-shell(含Hive支持)终端窗口,输入以下命令:
{% tabs test4 %}

scala> import java.util.Properties
scala> import org.apache.spark.sql.types._
scala> import org.apache.spark.sql.Row
 
//下面我们设置两条数据表示两个学生信息
scala> val studentRDD = spark.sparkContext.parallelize(Array("3 Rongcheng M 26","4 Guanhua M 27")).map(_.split(" "))
 
//下面要设置模式信息
scala> val schema = StructType(List(StructField("id", IntegerType, true),StructField("name", StringType, true),StructField("gender", StringType, true),StructField("age", IntegerType, true)))
 
//下面创建Row对象,每个Row对象都是rowRDD中的一行
scala> val rowRDD = studentRDD.map(p => Row(p(0).toInt, p(1).trim, p(2).trim, p(3).toInt))
 
//建立起Row对象和模式之间的对应关系,也就是把数据和模式对应起来
scala> val studentDF = spark.createDataFrame(rowRDD, schema)
 
//查看studentDF
scala> studentDF.show()
+---+---------+------+---+
| id|     name|gender|age|
+---+---------+------+---+
|  3|Rongcheng|     M| 26|
|  4|  Guanhua|     M| 27|
+---+---------+------+---+
//下面注册临时表
scala> studentDF.registerTempTable("tempTable")
 
scala> sql("insert into sparktest.student select * from tempTable")
scala
然后,请切换到刚才的hive终端窗口,输入以下命令查看Hive数据库内容的变化:

hive> select * from student;
OK
1   Xueqian F   23
2   Weiliang    M   24
3   Rongcheng   M   26
4   Guanhua M   27
Time taken: 0.049 seconds, Fetched: 4 row(s)

可以看到,插入数据操作执行成功了!

参考博客

博客, https://dblab.xmu.edu.cn/blog/1383/

  • 20
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Elik-hb

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值