全国职业院校技能大赛-大数据 离线数据处理模块-环境准备

本文详细介绍了如何在Maven项目中集成MySQL驱动和Spark,设置Hive配置,包括依赖引入、Hive-site.xml的管理,以及如何通过Scala编程操作Spark读写Hive数据。同时涉及HDFS、YARN和HiveServer2服务的启动以及权限管理。
摘要由CSDN通过智能技术生成

这部分不是很难,只需要创建一个基本的maven项目,引入对应的mysql驱动和spark依赖项之后,将hive的配置文件放到resources目录下就可以了

1. 首先使用idea创建一个maven项目

2. 引入mysql驱动 

在创建出来的maven项目中的pom文件中引入比赛环境对应的mysql数据库版本的驱动,这里使用5.7版本的mysql驱动作为示例

 对应的坐标如下

<!-- 这里的version需要根据比赛具体的环境而定,如果是mysql8.0的版本,则需要引入8.0.xx的驱动 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.27</version>
</dependency>

3. 引入spark-core, spark-spl, spark-hive依赖

需要注意的是,Spark3.1.3版本到Spark3.0.0版本的spark都是使用的Scala都是2.12版本的,因此这些版本的spark依赖后面携带的都是2.12

而version的版本号是根据比赛环境的Spark版本而定的,假如比赛环境的Spark版本不是3.1.1版本的,那么就需要更改为比赛环境具体的Spark版本

<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-core_2.12</artifactId>
    <version>3.1.1</version>
</dependency>
<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-sql_2.12</artifactId>
    <version>3.1.1</version>
</dependency>
<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-hive_2.12</artifactId>
    <version>3.1.1</version>
</dependency>

将这些依赖项引入完毕后刷新一下maven项目,等待加载依赖项完毕

4. 指定的目录下拿到hive-site.xml文件

示例:文件位于/opt/apache-hive-2.3.4-bin/conf/

将文件复制到本地,然后将文件复制到resources目录下

5. 为项目增加Scala框架支持

点击项目目录,然后双击SHIFT,在出现的对象框中输入ADD, 在出现的提示中选择 ADD Frameworks Support,然后选择添加Scala框架支持,点击OK

 可以看到此时已经可以创建Scala文件了

 测试Scala环境,测试代码正常输出,并且hive的配置文件也正常出现在了运行的结果之中,表示环境是OK的

 上面的配置为一个正常的maven项目,并且引入了Spark和MySQL的对应依赖,但是如果想要通过编写Scala代码使用Spark操作hive的方式处理离线数据,需要启动HDFS和YARN,并且需要启动Hive的metastore服务,如果想要使用jdbc的方式操作hive,则需要开启HiveServer2服务

下面是启动这些服务的示例Shell

启动HDFS和YARN的命令都需要在各自的Master节点上使用

# 启动HDFS
start-dfs.sh

# 启动YARN
start-yarn.sh

启动metastore服务

# 后台运行任务
nohup hive --service metastore >/dev/null 2>&1 &

启动HiveServer2服务

nohup hiveserver2 >/dev/null 2>&1 &

至此,所有的准备工作结束,这里我们编写一个测试程序

在刚刚创建出的maven项目中新建scala的object,编写下面的代码

package com.xi

import org.apache.spark.SparkConf
import org.apache.spark.sql.SparkSession

object Test01 {
  def main(args: Array[String]): Unit = {
    // 这里需要和hdfs的超级用户的用户名保持一致
    System.setProperty("HADOOP_USER_NAME", "root")

    // 创建Spark连接
    val conf = new SparkConf().setMaster("local[*]").setAppName("test01")
    val spark = SparkSession.builder().config(conf).enableHiveSupport().getOrCreate()
    spark.conf.set("hive.exec.dynamic.partition.mode", "nonstrict")
    spark.sparkContext.setLogLevel("OFF")

    // 读取mysql中的数据
    val context = spark.read
      .format("jdbc")
      .option("Driver", "com.mysql.jdbc.Driver")
      .option("url", "jdbc:mysql://192.168.88.102:3306/gmall") // 数据库的连接地址
      .option("user", "root") // 数据库的用户名
      .option("password", "000000") // 数据库的密码
      .option("dbtable", "order_info") // 要读取的表名
      .load()
    // 给获取到的表连接创建临时视图并起一个别名方便查询
    context.createTempView("order")

    // 测试查询
    spark.sql("select * from order").show()

    // 关闭spark连接
    spark.close()
  }
}

这里可以看到,可以查询出结果, 证明从mysql环境中读取数据是没有问题的

 下面测试向hive中写数据

在刚才的代码的基础上添加向hive中写入数据的代码,具体如下

import org.apache.spark.SparkConf
import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.functions.{current_date, date_format, date_sub}

object Test01 {
  def main(args: Array[String]): Unit = {
    // 这里需要和hdfs的超级用户的用户名保持一致
    System.setProperty("HADOOP_USER_NAME", "root")

    // 创建Spark连接
    val conf = new SparkConf().setMaster("local[*]").setAppName("test01")
    val spark = SparkSession.builder().config(conf).enableHiveSupport().getOrCreate()
    spark.conf.set("hive.exec.dynamic.partition.mode", "nonstrict")
    spark.sparkContext.setLogLevel("OFF")

    // 读取mysql中的数据
    val context = spark.read
      .format("jdbc")
      .option("Driver", "com.mysql.jdbc.Driver")
      .option("url", "jdbc:mysql://192.168.88.102:3306/gmall") // 数据库的连接地址
      .option("user", "root") // 数据库的用户名
      .option("password", "000000") // 数据库的密码
      .option("dbtable", "order_info") // 要读取的表名
      .load()
    // 给获取到的表连接创建临时视图并起一个别名方便查询
    context.createTempView("order")

    // 测试查询
    val querySelect = spark.sql("select * from order")

    querySelect.show()

    // 添加测试分区字段
    val result = querySelect
      .withColumn("etldate", date_format(date_sub(current_date(), 1), "yyyyMMdd"))

    result.show()

    // 测试将结果写出到test库中的order_info表
    result
      .write // 写出数据
      .format("hive") // 由于是从mysql中读取的数据,因此需要将这些数据的格式转化为hive的格式
      .mode("append")
      .partitionBy("etldate")
      .saveAsTable("test.order_info")

    spark.sql("show partitions test.order_info").show()

    // 关闭spark连接
    spark.close()
  }
}

这里需要注意,由于HDFS的写入操作是需要权限的,并且这个用户和本地的Linu系统的用户可能并不一样,如果在第一行下面这段代码中设置的用户没有对HDFS中写入数据的权限,代码可能会报错,出现没有权限的错误

System.setProperty("HADOOP_USER_NAME", "root") 

以下是因为没有写入文件的权限二导致的错误

可以看到,上面的结果中,查询操作是正常的,而写出操作出现了错误,具体的错误日志为

Exception in thread "main" org.apache.spark.sql.AnalysisException: org.apache.hadoop.hive.ql.metadata.HiveException: MetaException(message:Got exception: org.apache.hadoop.security.AccessControlException Permission denied: user=root, access=WRITE, inode="/user/hive/warehouse/test.db":atguigu:supergroup:drwxr-xr-x

因为root用户没有对/user/hive/warehouse/test.db中写出文件的权限,atguigu用户拥有对这个文件夹写出数据的权限,因此需要将上面的代码进行修改

System.setProperty("HADOOP_USER_NAME", "atguigu")

可以看到代码运行成功,现在到HDFS上对应的位置是否出现了分区

 可以看到hdfs上已经有了对应的分区文件

使用Hive Cli查询写出的表的分区信息

 查询表中的数据的根据total_amount字段倒序排序,查询前五行

 查询成功,环境测试完毕,比赛时,这部分肯定不会测试的态度,这一段测试已经是数据抽取的内容了,比赛之前作为练习就可以了

还有几天就要比赛了,希望能拿个比较好的名次,加油!

  • 18
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值