Spark SQL 3.0.1 与 CDH Hive 2.1.1结合

本文简单的介绍了 Spark SQL 3.0 与 Hive 2.1的结合,包括安装配置,spark-sql的使用,spark thriftserver的使用及 spark thriftserver 日志信息的查看。

文中通过简单的案例串联起来了 spark thriftserver 和 hive的结合,有较强的参考价值。

0.解压spark3.0.1的包

将编译好的spark-3.0.1-bin-hadoop-3.0.0-cdh6.1.0.tgz 的软件包解压的指定目录 /data/soft/spark_3.0.1

export SPARK_3_0_1_HOME=/data/soft/spark_3.0.1

tar -zxvf spark-3.0.1-bin-hadoop-3.0.0-cdh6.1.0.tgz

mv spark-3.0.1-bin-hadoop-3.0.0-cdh6.1.0 spark_3.0.1

1.添加CDH环境配置

链接hadoop/hive相关的配置文件到 conf目录下

cd $SPARK_3_0_1_HOME/conf

 

ln -s /etc/hive/conf/hdfs-site.xml hdfs-site.xml

ln -s /etc/hive/conf/mapred-site.xml mapred-site.xml

ln -s /etc/hive/conf/yarn-site.xml yarn-site.xml

ln -s /etc/hive/conf/core-site.xml core-site.xml

ln -s /etc/hive/conf/hive-env.sh hive-env.sh

ln -s /etc/hive/conf/hive-site.xml hive-site.xml

2.添加spark配置

cd $SPARK_3_0_1_HOME/conf

2.1 spark-defaults.conf

cp spark-defaults.conf.template spark-defaults.conf

vim spark-defaults.conf

在配置文件底部添加下面的配置

# hive metastore的版本设置为 2.1.1

spark.sql.hive.metastore.version=2.1.1

# 引用 hive2.1.1 相关的jar包

spark.sql.hive.metastore.jars=/opt/cloudera/parcels/CDH/lib/hive/lib/*

# 设置 spark提交任务默认的 yarn 队列

spark.yarn.queue=root.analysis

2.2 spark-env.sh

cp spark-env.sh.template spark-env.sh

vim spark-env.sh

在配置文件底部添加下面的配置

export HADOOP_CONF_DIR=/etc/hadoop/conf # 添加 hadoop 配置文件的路径

export SPARK_HISTORY_OPTS="-Dspark.history.ui.port=18080 -Dspark.history.retainedApplications=3 -Dspark.history.fs.logDirectory=hdfs://nameservice1/user/history/done_intermediate/spark3.0.1/eventlogs" # 添加 spark job history 相关参数 包括 web ui的端口 / 缓存的spark作业日志数目 / 日志的hdfs路径

2.3 log4j.properties

cp log4j.properties.template log4j.properties  # 复制log4j模板, 添加 默认的log4j配置

若有其他需要,可以自行修改。

2.4 spark-sql命令

vim $SPARK_3_0_1_HOME/bin/spark-sql

在头部添加SPARK_HOME配置,以避免使用 CDH 集群的 spark jar包

SPARK_HOME=/data/soft/spark_3.0.1

3.分发spark软件包

将配置好的spark软件包分发到 CDH 集群的其他节点上,以备后续应用使用

scp -r spark_3.0.1 root@cdh-datanode02:/data/soft/.

scp -r spark_3.0.1 root@cdh-datanode03:/data/soft/.

...

4. spark-sql 命令使用

# 进入到 spark3.0.1 的 bin目录

cd $SPARK_3_0_1_HOME/bin

# 运行 spark-sql命令

./spark-sql --master yarn --name spark-sql-test

-- 示例测试 sql:

-- 查看hive中所有的 database

show databases;

 

 

-- 查看default库中所有的 table 信息

show tables;

 

 

 

-- 简单的逻辑运算

select 1 1;

 

-- 使用spark sql函数 current_date();

select current_date();

 

 

-- 创建测试表 default.foo

create table default.foo(id string, amount bigint);

 

 

-- 向测试表中插入4条数据

insert into table default.foo values('1',1)

,('2',2)

,('3',3)

,('4',2);

 

 

-- 查看测试表中的记录数

select count(1) as cnt from foo;

 

 

-- 根据amount字段进行汇总 并按照 amount数量顺序排列

select amount, count(1) from foo group by amount order by amount desc;

 

 

-- 退出 spark-sql命令

exit;

5. spark thriftserver 使用

启动spark thriftserver

注意需要添加启动端口号的配置

cd $SPARK_3_0_1_HOME/sbin

./start-thriftserver.sh \

--master yarn \

--executor-memory 2048m \

--hiveconf hive.server2.thrift.port=10005

使用spark3.0.1 自带的beeline进行连接

cd $SPARK_3_0_1_HOME/bin

./beeline

!connect jdbc:hive2://cdh-datanode1:10005/default

 

 

# 出现弹框提示输入账号密码信息,由于没有添加鉴权,直接按enter即可

 

-- 创建测试表 student_info

create table default.student_info(

    id bigint comment '学生id'

    , name string comment '学生姓名'

    , birthday string comment '出生日期 yyyy-MM-dd'

    , class string comment '班级名称 xxyy xx年级 yy班'

)

comment '学生信息表'

stored as parquet;

 

-- 初始化测算表数据

insert into default.student_info values(1,'黄小明','2002-01-09','0302')

,(2,'王小刚','2001-06-03','0305')

,(3,'董小梅','2002-07-03','0302')

,(4,'杨小宝','2002-05-03','0301')

,(5,'周小龙','2002-04-23','0302')

,(6,'周小龙','2002-06-28','0304')

,(7,'方小玉','2000-09-28','0204');

 

-- 查询插入进去的数据

select id, name, birthday, class from default.student_info;

0: jdbc:hive2://cdh-datanode1:10005/defaultselect id, name, birthday, class from default.student_info;

+-----+-------+-------------+--------+

id  | name  |  birthday   | class  |

+-----+-------+-------------+--------+

| 4   | 杨小宝   | 2002-05-03  | 0301   |

| 5   | 周小龙   | 2002-04-23  | 0302   |

| 6   | 周小龙   | 2002-06-28  | 0304   |

| 7   | 方小玉   | 2000-09-28  | 0204   |

| 1   | 黄小明   | 2002-01-09  | 0302   |

| 2   | 王小刚   | 2001-06-03  | 0305   |

| 3   | 董小梅   | 2002-07-03  | 0302   |

+-----+-------+-------------+--------+

7 rows selected (0.275 seconds)

 

-- 对测试表 student_info的一些操作

-- a.查看各个班级的人数

select class, count(1) from default.student_info group by class;

0: jdbc:hive2://cdh-datanode1:10005/defaultselect class, count(1) from default.student_info group by class;

+--------+-----------+

| class  | count(1)  |

+--------+-----------+

| 0204   | 1         |

| 0305   | 1         |

| 0304   | 1         |

| 0301   | 1         |

| 0302   | 3         |

+--------+-----------+

5 rows selected (0.816 seconds)

 

 

-- b.使用explain查看 a 的执行计划

explain select class, count(1) from default.student_info group by class;

 

 

0: jdbc:hive2://cdh-datanode1:10005/default> explain select class, count(1) from default.student_info group by class;

+----------------------------------------------------+

|                        plan                        |

+----------------------------------------------------+

| == Physical Plan ==

*(2) HashAggregate(keys=[class#9977], functions=[count(1)])

+- Exchange hashpartitioning(class#9977, 200), true, [id=#15603]

   +- *(1) HashAggregate(keys=[class#9977], functions=[partial_count(1)])

      +- *(1) ColumnarToRow

         +- FileScan parquet default.student_info[class#9977] Batched: true, DataFilters: [], Format: Parquet, Location: InMemoryFileIndex[hdfs://cdh-namenode1:8020/user/hive/warehouse/student_info], PartitionFilters: [], PushedFilters: [], ReadSchema: struct<class:string>

 

 |

+----------------------------------------------------+

1 row selected (0.087 seconds)

 

 

-- c.查询班级人数最多的班级名称

select 

    class

from default.student_info

group by class

order by count(1) desc

limit 1;

0: jdbc:hive2://cdh-datanode1:10005/defaultselect 

. . . . . . . . . . . . . . . . . . . . . .>     class

. . . . . . . . . . . . . . . . . . . . . .> from default.student_info

. . . . . . . . . . . . . . . . . . . . . .> group by class

. . . . . . . . . . . . . . . . . . . . . .> order by count(1) desc

. . . . . . . . . . . . . . . . . . . . . .> limit 1;

+--------+

| class  |

+--------+

| 0302   |

+--------+

1 row selected (0.757 seconds)

 

 

-- d.查看年龄最小的学生所在的班级

select

    class

from default.student_info

order by birthday

limit 1;

 

0: jdbc:hive2://cdh-datanode1:10005/defaultselect

. . . . . . . . . . . . . . . . . . . . . .>     class

. . . . . . . . . . . . . . . . . . . . . .> from default.student_info

. . . . . . . . . . . . . . . . . . . . . .> order by birthday

. . . . . . . . . . . . . . . . . . . . . .> limit 1;

+--------+

| class  |

+--------+

| 0204   |

+--------+

1 row selected (0.202 seconds)

 

 

-- e.查看各个年级的总人数

select

    count(1) as cnt

    , substr(class,1,2) as grade

from default.student_info

group by substr(class,1,2);

 

 

0: jdbc:hive2://cdh-datanode1:10005/defaultselect

. . . . . . . . . . . . . . . . . . . . . .>     count(1) as cnt

. . . . . . . . . . . . . . . . . . . . . .>     , substr(class,1,2) as grade

. . . . . . . . . . . . . . . . . . . . . .> from default.student_info

. . . . . . . . . . . . . . . . . . . . . .> group by substr(class,1,2);

+------+--------+

| cnt  | grade  |

+------+--------+

| 6    | 03     |

| 1    | 02     |

+------+--------+

2 rows selected (0.752 seconds)

 

 

-- f.在同一年级中,给每个学生根据出生年月从年纪小到大编号

select

    substr(class,1,2) as grade

    , name

    , birthday

    , row_number() over(partition by substr(class,1,2) order by birthday desc) as rn

from default.student_info;

 

 

0: jdbc:hive2://cdh-datanode1:10005/defaultselect

. . . . . . . . . . . . . . . . . . . . . .>     substr(class,1,2) as grade

. . . . . . . . . . . . . . . . . . . . . .>     , name

. . . . . . . . . . . . . . . . . . . . . .>     , birthday

. . . . . . . . . . . . . . . . . . . . . .>     , row_number() over(partition by substr(class,1,2) order by birthday desc) as rn

. . . . . . . . . . . . . . . . . . . . . .> from default.student_info;

+--------+-------+-------------+-----+

| grade  | name  |  birthday   | rn  |

+--------+-------+-------------+-----+

| 03     | 董小梅   | 2002-07-03  | 1   |

| 03     | 周小龙   | 2002-06-28  | 2   |

| 03     | 杨小宝   | 2002-05-03  | 3   |

| 03     | 周小龙   | 2002-04-23  | 4   |

| 03     | 黄小明   | 2002-01-09  | 5   |

| 03     | 王小刚   | 2001-06-03  | 6   |

| 02     | 方小玉   | 2000-09-28  | 1   |

+--------+-------+-------------+-----+

7 rows selected (1.166 seconds)

 

 

-- g.查询同一姓名学生的信息

select

    id

    , name

    , birthday

    , class

from (

    select

        id

        , name

        , birthday

        , class

        , count(1) over(partition by name) as cnt

    from default.student_info

) t

where t.cnt > 1

;

 

 

0: jdbc:hive2://cdh-datanode1:10005/defaultselect

. . . . . . . . . . . . . . . . . . . . . .>     id

. . . . . . . . . . . . . . . . . . . . . .>     , name

. . . . . . . . . . . . . . . . . . . . . .>     , birthday

. . . . . . . . . . . . . . . . . . . . . .>     , class

. . . . . . . . . . . . . . . . . . . . . .> from (

. . . . . . . . . . . . . . . . . . . . . .>     select

. . . . . . . . . . . . . . . . . . . . . .>         id

. . . . . . . . . . . . . . . . . . . . . .>         , name

. . . . . . . . . . . . . . . . . . . . . .>         , birthday

. . . . . . . . . . . . . . . . . . . . . .>         , class

. . . . . . . . . . . . . . . . . . . . . .>         , count(1) over(partition by name) as cnt

. . . . . . . . . . . . . . . . . . . . . .>     from default.student_info

. . . . . . . . . . . . . . . . . . . . . .> ) t

. . . . . . . . . . . . . . . . . . . . . .> where t.cnt > 1

. . . . . . . . . . . . . . . . . . . . . .> ;

+-----+-------+-------------+--------+

id  | name  |  birthday   | class  |

+-----+-------+-------------+--------+

| 5   | 周小龙   | 2002-04-23  | 0302   |

| 6   | 周小龙   | 2002-06-28  | 0304   |

+-----+-------+-------------+--------+

2 rows selected (3.426 seconds)

 

 

-- 退出beeline

!quit

6. spark thriftserver日志查看

6.1通过Yarn Scheduler的Tracking UI 查看 Spark Thriftserver的执行日志

a.搜索 JDBC,找到 Spark Thriftserver 的 application信息

b.点击 ApplicationMaster查看日志

Spark SQL 3.0.1 与 CDH Hive 2.1.1结合

 

6.2 spark thriftserver 执行 sql 任务的日志页面

Spark SQL 3.0.1 与 CDH Hive 2.1.1结合

主页显示了一些简单的统计信息,如启动spark thriftserver的 User(用户): root , Total Uptime(总共的启动时间): 26min, Scheduling Mode(任务调度的模式) FIFO, Completed Jobs(已经完成的作业) 8

从Completed Jobs列表中可以查看到

字段

字段说明

Job Id 作业id
Description 作业的描述信息,上面执行了sql语句,这里显示的就是sql信息, 点击 链接可以查看具体的作业日志信息。
Submitted 作业提交时间
Duration 作业持续时间

Stages:

Succeeded/Total

执行阶段统计:

成功的执行阶段数/总执行阶段数

Tasks(for all stages):

Succeeded/Total

任务数目统计(对于所有执行阶段)

成功执行的任务数/总任务数

6.3 作业详细信息

查看上面 job 7 的信息 

-- g.查询同一姓名学生的信息

select

    id

    , name

    , birthday

    class

from (

    select

        id

        , name

        , birthday

        class

        , count(1) over(partition by name) as cnt

    from default.student_info

) t

where t.cnt > 1

;

即 这个sql的详细的详细信息,页面中显示的信息有:

字段

字段说明

Status 作业状态信息
Associated SQL Query

相关从查询sql语句,点击可以查询到 具体的sql执行各阶段依赖的信息以及

Parsed Logical Plan 解析逻辑执行计划

Analyzed Logical Plan 分析逻辑执行计划

Optimized Logical Plan 优化逻辑执行计划

Physical Plan 物理执行计划

Job Group 作业所在组
Completed Stages 完成的执行阶段数目
Event Timeline 事件时间线
DAG Visualiazation 各个执行阶段的依赖关系图(简图,点击 Associated SQL Query可以查看更加详细的信息)

Spark SQL 3.0.1 与 CDH Hive 2.1.1结合

Completed Stages列表中显示的信息

字段

字段说明

Stage Id 执行阶段id
Description 执行阶段描述信息
Submitted 执行阶段提交时间
Duration 改执行阶段所持续的时间

Tasks:

Succeeded/Total

任务数目:

成功执行任务数/总任务数

Input 输入数据量统计
Output 输出数据量统计
Shuffle Read Shuffle阶段读数据量统计
Shuffle Write Shuffle阶段写数据量统计

6.4 Associated SQL Query 详细信息页面

这个页面包括的信息有

字段

字段说明

Submitted Time 作业提交时间
Duration 作业持续时间
Succeeded Jobs 成功的 job id
DAG Visualization 作业执行各个阶段的详细统计信息
Details 各个阶段的执行计划信息

Spark SQL 3.0.1 与 CDH Hive 2.1.1结合

 

 

Spark SQL 3.0.1 与 CDH Hive 2.1.1结合

7.总结

本文提供了 spark 3.0 与 CDH Hive 2.1 结合的实战信息,属于入门级别的内容,即把整个流程跑通了,若要运用到生产实践中还需要进行一系列的优化,如spark sql各种参数调优, spark sql日志具体日志的意义,spark thriftserver ha 配置, 与调度工具结合等。

我会继续的将spark 3.0系列的实践文章写出来,期望大家能够持续关注。

 

参考文章

[1]Spark3.0.1 结合CDH6.1.0 编译打包

[2]Distributed SQL Engine

[3]CDH 6成功启动spark-thrift服务(CDH 6.2.0)