Spark SQL还支持读取和写入存储在Apache Hive中的数据。然而,由于Hive有大量依赖项,这些依赖项不包括在默认的Spark发行版中,如果在classpath上配置了这些Hive依赖项,Spark就会自动加载它们。需要注意的是,这些Hive依赖项必须出现在所有Worker节点上,因为它们需要访问Hive序列化和反序列化库(SerDes),以便访问存储在Hive中的数据。
在使用Hive时,必须实例化一个支持Hive的SparkSession对象。若系统中没有部署Hive,则仍然可以启用Hive支持(Spark SQL充当Hive查询引擎)。Spark对Hive的支持包括连接到持久化的Hive元数据库、Hive SerDe、Hive用户定义函数、HiveQL等。如果没有配置hive-site.xml文件,Spark应用程序启动时,就会自动在当前目录中创建Derby元数据库metastore_db,并创建一个由spark.sql.warehouse.dir指定的数据仓库目录(若不指定,则默认启动Spark应用程序当前目录中的spark-warehouse目录)。需要注意的是,从Spark2.0.0版本开始,hive-site.xml中的hive.metastore.warehouse.dir属性不再使用了,代替的是使用spark.sql.warehouse.dir指定默认的数据仓库目录。
将Hive配置文件hive-site.xml拷贝到Spark配置目录,执行命令:cp $HIVE_HOME/conf/hive-site.xml $SPARK_HOME/conf
进入Spark配置目录,编辑Hive配置文件hive-site.xml
<property>
<name>spark.sql.warehouse.dir</name>
<value>/user/spark/warehouse</value>
</property>
执行命令:hive --service metastore &
注意:博主这里执行命令时,出现了大量的警告,这里就不解决了,不影响后续操作,警告如下:
执行命令:spark-shell --master spark://master:7077
这里的警告信息表明,连接 MySQL 数据库时未做身份验证,不建议这样做。
要解决这个问题,有以下两种方法:
显式地禁用 SSL:在连接 MySQL 数据库的时候添加 useSSL=false 参数。这种方式不安全,不建议使用,但是可以在测试环境下暂时解决问题。
启用 SSL 并提供正确的信任库:在连接 MySQL 数据库的时候设置 useSSL=true,并提供正确的信任库用于服务器证书验证。这种方式更加安全。你可以参考 MySQL 官方文档来设置信任库。在默认情况下,Java 会使用位于 $JAVA_HOME/jre/lib/security
目录下的 cacerts 文件作为信任库。你可以通过使用 keytool -list
命令来查看其中的证书。
执行命令:import org.apache.spark.sql.SparkSession
val spark = SparkSession.builder()
.appName("Spark Hive Demo")
.enableHiveSupport() // 开启Hive支持
.getOrCreate()
调用SparkSession对象的sql()方法可以传入需要执行的HiveQL语句。
创建一张Hive表student,并指定字段分隔符为半角逗号“,”,执行命令:spark.sql(“CREATE TABLE IF NOT EXISTS student(id INT, name STRING, gender STRING, age INT) ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘,’”)
查看本地文件/home/student.txt的内容
将该文件数据导入表student中,执行命令:spark.sql("LOAD DATA LOCAL INPATH '/home/student.txt' INTO TABLE student")
查询表student的数据并显示到控制台,执行命令:spark.sql(“SELECT * FROM student”).show()
按性别分组统计平均年龄,执行命令:spark.sql(“SELECT gender, AVG(age) FROM student GROUP BY gender”).show()
创建一个Hive表test,数据存储格式为Parquet(默认为普通文本格式),执行命令:spark.sql(“CREATE TABLE test (name STRING, age INT) STORED AS PARQUET”)
使用saveAsTable()方法可以将数据帧数据写入指定的Hive表中。
加载student表数据得到数据帧
导入SaveMode类,执行命令:import org.apache.spark.sql.SaveMode
将数据帧数据写入hive表,执行命令:studentDf.select(“name”, “age”).write.mode(SaveMode.Overwrite).saveAsTable(“test”)
查询test表数据,执行命令:spark.sql(“select * from test”).show()
查看HDFS文件/student/input/student.txt的内容
创建Hive表student1,执行命令:spark.sql(“CREATE TABLE IF NOT EXISTS student1 (id INT, name STRING, gender STRING, age INT) ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘,’”)
将该文件数据导入表student1中,执行命令:spark.sql(“LOAD DATA INPATH ‘hdfs://master:9000/student/input/student.txt’ INTO TABLE student1”)
查看表student1的内容,执行命令:spark.table(“student1”).show()
查看三张表:student,student1和test