发现有问题评论区留言~~
课堂测试1
一、环境要求
sandbox-hdp 2.6.4 或同等版本自建的 Hadoop+Hive+Spark+HBase 开发环境。
二、提交结果要求
1.必须提交源码或对应分析语句,如不提交则不得分。
2.带有分析结果的功能,请分析结果的截图与代码一同提交。
三、数据描述
这是一份来自于某在线考试系统的学员答题批改日志,日志中记录了日志生成时间,题目难度系数,题目所属的知识点 ID,做题的学生 ID,题目 ID 以及作答批改结果。日志的结构如下:
四、功能要求
1.数据准备(10 分)
请在 HDFS 中创建目录/app/data/exam,并将 answer_question.log 传到该目录。
2.在 Spark-Shell 中,加载 HDFS 文件系统 answer_question.log 文件,并使用 RDD 完成以下分析,也可使用 Spark 的其他方法完成数据分析。(20 分)
①提取日志中的知识点 ID,学生 ID,题目 ID,作答结果 4 个字段的值
②将提取后的知识点ID,学生ID,题目 ID,作答结果字段的值以文件的形式保存到HDFS的/app/data/result 目录下。一行保留一条数据,字段间以“\t”分割。文件格式如下所示。
(提示:元组可使用 tuple.productIterator.mkString("\t")组合字符串,使用其他方法处理数据只要结果正确也给分)
34434481 8195023659599 1018 0
34434425 8195023659599 7385 1
34434457 8195023659596 7346 1
34434498 8195023659597 6672 0
34434449 8195023659594 4809 1
34434489 8195023659596 7998 0.5
34434492 8195023659595 9406 0
34434485 8195023659597 8710 1
3.创建 HBase 数据表(10 分)
在 HBase 中创建命名空间(namespace)exam,在该命名空间下创建 analysis 表,使用学生 ID 作为 RowKey。
该表下有 2 个列族 accuracy、question。accuracy 列族用于保存学员答题正确率统计数据:
( 总分 accuracy:total_score , 答题的试题数 accuracy:question_count,正确率 accuracy:accuracy)
question 列族用于分类保存学员正确, 错误和半对的题目 id ( 正确 question:right , 错误 question:error , 半对question:half)
4.请在 Hive 中创建数据库 exam ,在该数据库中:
创建外部表 ex_exam_record 指向/app/data/result 下Spark 处理后的日志数据 ;
创建外部表ex_exam_anlysis 映射至HBase中的 analysis 表的 accuracy 列族;
创建外部表 ex_exam_question 映射至 HBase 中的analysis 表的 question 列族(20 分)
ex_exam_record 表结构如下:
字段名称 字段类型 字段含义
topic_id string 知识点 ID
student_id string 学生 ID
question_id string 题目 ID
score float 作答结果
ex_exam_anlysis 表结构如下:
字段名称 字段类型 字段含义
student_id string 学生 ID
total_score float 总分
question_count int 答题的试题数
accuracy float 正确率
ex_exam_question 表结构如下:
字段名称 字段类型 字段含义
student_id string 学生 ID
right string 所有作对的题目的 ID 列表
half string 所有半对的题目的 ID 列表
error string 所有做错的题目的 ID 列表
5.使用 ex_exam_record 表中的数据统计每个学员总分、答题的试题数和正确率,并保存到 ex_exam_anlysis 表中,其中正确率的计算方法如下:正确率=总分/答题的试题数(20 分)
6.使用 ex_exam_record 表中的数据统计每个作对,做错,半对的题目列表。
①题目 id 以逗号分割,并保存到 ex_exam_question 表中。(10 分)
②完成统计后,在 HBase Shell 中遍历 exam:analysis 表并只显示 question 列族中的数据, 如下图所示(10 分)
数据示例:
2019-06-16 14:24:34 INFO com.noriental.praxissvr.answer.util.PraxisSsdbUtil:45 [SimpleAsyncTaskExecutor-1] [020765925160] req: set se0_34434412_8195023659593_8080r 1,resp: ok 14
2019-06-16 14:24:34 INFO com.noriental.praxissvr.answer.util.PraxisSsdbUtil:45 [SimpleAsyncTaskExecutor-1] [020765925160] req: set se2_34434459_8195023659592_3762r 0,resp: ok 14
2019-06-16 14:24:34 INFO com.noriental.praxissvr.answer.util.PraxisSsdbUtil:45 [SimpleAsyncTaskExecutor-1] [020765925160] req: set se0_3443449_8195023659591_1736r 0,resp: ok 14
2019-06-16 14:24:34 INFO com.noriental.praxissvr.answer.util.PraxisSsdbUtil:45 [SimpleAsyncTaskExecutor-1] [020765925160] req: set se2_34434473_8195023659591_7982r 0,resp: ok 14
2019-06-16 14:24:34 INFO com.noriental.praxissvr.answer.util.PraxisSsdbUtil:45 [SimpleAsyncTaskExecutor-1] [020765925160] req: set se1_34434444_8195023659595_4753r 0,resp: ok 14
1.数据准备(10 分)
请在 HDFS 中创建目录/app/data/exam,并将 answer_question.log 传到该目录。
1.启动Hadoop start-all.sh
2.创建目录 hdfs dfs -mkdir -p /app/data/exam
3.上传文件 hdfs dfs -put answer_question.log /app/data/exam
2.在 Spark-Shell 中,加载 HDFS 文件系统 answer_question.log 文件,并使用 RDD 完成
以下分析,也可使用 Spark 的其他方法完成数据分析。(20 分)
①提取日志中的知识点 ID,学生 ID,题目 ID,作答结果 4 个字段的值
②将提取后的知识点 ID,学生 ID,题目 ID,作答结果字段的值以文件的形式保存到 HDFS的/app/data/result 目录下。一行保留一条数据,字段间以“\t”分割。文件格式如下所示。
(提示:元组可使用 tuple.productIterator.mkString("\t")组合字符串,使用其他方法处理数据只要结果正确也给分)
34434481 8195023659599 1018 0
34434425 8195023659599 7385 1
34434457 8195023659596 7346 1
34434498 8195023659597 6672 0
34434449 8195023659594 4809 1
34434489 8195023659596 7998 0.5
34434492 8195023659595 9406 0
34434485 8195023659597 8710 1
1.启动spark-shell spark-shell --master local[4]
2.加载 HDFS 文件系统 answer_question.log 文件
scala> val log = sc.textFile("hdfs://hadoop100:9000/app/data/exam/answer_question.log")
3.先查看一下文件的部分数据格式:
scala> log.take(2).foreach(println)
2019-06-16 14:24:34 INFO com.noriental.praxissvr.answer.util.PraxisSsdbUtil:45 [SimpleAsyncTaskExecutor-1] [020765925160] req: set se0_34434412_8195023659593_8080r 1,resp: ok 14
2019-06-16 14:24:34 INFO com.noriental.praxissvr.answer.util.PraxisSsdbUtil:45 [SimpleAsyncTaskExecutor-1] [020765925160] req: set se2_34434459_8195023659592_3762r 0,resp: ok 14
// set se2_34434459_8195023659592_3762r 0,resp: ok 14
// """.*se\d_(\d+)_(\d+)_(\d+)r (.*),.*""".r
4.提取日志中的知识点 ID,学生 ID,题目 ID,作答结果 4 个字段的值
val regex = """.*se\d_(\d+)_(\d+)_(\d+)r (.*),.*""".r
val log_2= log.map(x=>x match {
case regex(str0,str1,str2,str3) => (str0,str1,str2,str3)
})
----------------等价的第二种写法-------------------------
val log_2=log.map(row=>row.split("\\s+")).map(x=>(x(8).split("_"),x(9).split(",")(0))).map(x=>(x._1(1),x._1(2),x._1(3).dropRight(1),x._2))
----------------等价的第三种写法-------------------------
val log_2=log.map(_.replace("r ","_").replace(",","_")).map(x=>x.split("_")).map(x=>(x(1),x(2),x(3),x(4)))
--------------------------------------------------------
log_2.collect.foreach(println)
5.储存到HDFS (要求目标文件夹必须不存在)
log_2.map(tuple => tuple.productIterator.mkString("\t")).saveAsTextFile("hdfs://hadoop100:9000/app/data/result")
3.创建 HBase 数据表(10 分)
在 HBase 中创建命名空间(namespace)exam,在该命名空间下创建 analysis 表,使用学生 ID 作为 RowKey,该表下有 2 个列族 accuracy、question。accuracy 列族用于保存学员答题正确率统计数据(总分 accuracy:total_score ,答题的试题数 accuracy:question_count,正确率 accuracy:accuracy);question 列族用于分类保存学员正确,错误和半对的题目 id
(正确 question:right,错误 question:error,半对 question:half)
1.启动zookeeper: zkServer.sh start
2.启动hbase: start-hbase.sh
3.启动hive metastore元数据服务 hive --service metastore &
4.进入hbase shell: hbase shell
5.在 HBase 中创建命名空间(namespace)exam create_namespace 'exam'
6.在该命名空间下创建 analysis 表,该表下有 2 个列族 accuracy、question
hbase(main):011:0> create 'exam:analysis', 'accuracy' , 'question'
4.请在 Hive 中创建数据库 exam
创建外部表 ex_exam_record 指向/app/data/result 下 Spark 处理后的日志数据
创建外部表 ex_exam_anlysis 映射至 HBase中的 analysis 表的 accuracy 列族
创建外部表 ex_exam_question 映射至 HBase 中的 analysis 表的 question 列族(20 分)
1.启动hive hive
2.创建数据库 hive> create database exam;
3.创建外部表 ex_exam_record 指向/app/data/result 下 Spark 处理后的日志数据
create external table exam.ex_exam_record(
topic_id string,
student_id string,
question_id string,
score float)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
STORED AS TEXTFILE
LOCATION '/app/data/result';
4.创建外部表 ex_exam_anlysis 映射至 HBase中的 analysis 表的 accuracy 列族
总分 accuracy:total_score,答题的试题数accuracy:question_count,正确率 accuracy:accuracy
create external table exam.ex_exam_anlysis(
student_id string,
total_score float,
question_count int,
accuracy float)
stored by 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
with serdeproperties('hbase.columns.mapping'=':key,
accuracy:total_score,
accuracy:question_count,
accuracy:accuracy')
tblproperties('hbase.table.name'='exam:analysis');
5.创建外部表 ex_exam_question 映射至 HBase 中的 analysis 表的 question 列族(20 分)
正确 question:right,错误 question:error,半对 question:half
create external table exam.ex_exam_question(
student_id string,
right string,
half string,
error string)
stored by 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
with serdeproperties('hbase.columns.mapping'=':key,
question:right,
question:half,
question:error')
tblproperties('hbase.table.name'='exam:analysis');
5.使用 ex_exam_record 表中的数据统计每个学员总分、答题的试题数和正确率,并保存
到 ex_exam_anlysis 表中,其中正确率的计算方法如下:
正确率=总分/答题的试题数 (20 分)
insert into ex_exam_anlysis
select student_id,
sum(score),
count(question_id),
sum(score)/count(question_id) rate
from ex_exam_record
group by student_id
6.使用 ex_exam_record 表中的数据统计每个作对,做错,半对的题目列表。
①题目 id 以逗号分割,并保存到 ex_exam_question 表中。(10 分)
②完成统计后,在 HBase Shell 中遍历 exam:analysis 表并只显示 question 列族中的数据,如下图所示(10 分)
insert into exam.ex_exam_question
select a.student_id,right,half,error
from (
select student_id,
concat_ws(',',collect_set(question_id)) right
from exam.ex_exam_record
where score=1
group by student_id
) a
full join (
select student_id,
concat_ws(',',collect_set(question_id)) half
from exam.ex_exam_record
where score=0.5
group by student_id
) b on a.student_id=b.student_id
full join (
select student_id,
concat_ws(',',collect_set(question_id)) error
from exam.ex_exam_record
where score=0
group by student_id
) c on a.student_id=c.student_id;
----------------等价的第二种写法(*)-------------------------
select
student_id,
concat_ws(",",collect_set(if(score=1,question_id,NULL))) right,
concat_ws(",",collect_set(if(score=0.5,question_id,NULL))) half,
concat_ws(",",collect_set(if(score=0,question_id,NULL))) error
from ex_exam_record
group by student_id;
----------------使用case when的写法(*)-------------------------
select
student_id,
concat_ws(",",collect_set(case when score=1 then question_id end)) right,
concat_ws(",",collect_set(case when score=0.5 then question_id end)) half,
concat_ws(",",collect_set(case when score=0 then question_id end)) error
from ex_exam_record
group by student_id;
关注点:case when 不可以写在select语句中,原因是先做group by,再做select查找,这个时候group by的字段中需要出现score,但是如果这样 结果就会出现 right half error 列 分别为 question_id null null 这样的情况,还要再做表连接达到期望的效果。
②完成统计后,在 HBase Shell 中遍历 exam:analysis 表并只显示 question 列族中的数据,
如下图所示(10 分)
scan 'exam:analysis'
flush 'exam:analysis'
8195023659590 column=question:half, timestamp=1610611490284, value=7050,874,7142,153,5237,7667,8387,8440,566,6411,2949,4004,787,6700,2
612,3165,2797,6506,2298,5295,4569,3218,1881,5467,3538,3921,14,3765,3936,9892,5041,2300,3918,4414,9439,7742,4489,967,8030,
6725,1567,2780,3051,5808,4890,3812,5158,3544,1379,3688,8610,2005,6226,5439,3604,5054,9571,5940,5243,2963,2220,8310,695,46
69,8421,2409,1656,3460,5828,9137,5739,3423,5701,4769,8080,7406,88,8307,1705,9399,8270,3727,5722,6958,8839,3941,9474,6624,
2425,5298,3410,3967,2651,7747,1578,6927,4276,4301,6371,9925,120,169,6057,6260,9095,3387,2036,1409,1107,70,4006,5271,374,2
983,5954,8504,6255,1473,3399,6366,5276,7025,592,9224,283,7415,9234,7960,4854,6768,8711,2176,2224,1895,377,7596,3558,8571,
9002,8941,6478,5007,5577,5105,2549,9587,2009,9567,4738,7619,6950,2150,8154,5294,6369,8371,5972,6937,8623,6362,5155,2933,4
683,3249,7726,4351,8710
8195023659590 column=question:error, timestamp=1610611490284, value=4863,167,6153,9822,6340,2676,9538,793,2528,7442,5763,8515,3298,9905,
7785,3485,625,6804,1343,1613,5913,5776,4097,8654,9045,9218,5390,8787,4122,7057,3513,4847,4087,1469,2782,9393,8308,3575,74
74,6301,8839,7706,7653,249,1983,7545,9602,1781,3660,8402,4404,1739,9377,3880,6856,8082,9032,1917,3464,1839,4957,9756,4323
,5900,1233,6229,2336,9101,6541,2564,8196,7976,3989,1997,8478,1275,4466,4178,2505,6595,6611,3270,4975,2711,322,9773,7210,6
860,1462,1307,4414,5843,2461,7776,6360,3718,2024,4774,2404,3274,3769,958,8085,6205,2692,5143,4568,2821,3642,6141,6691,942
,3894,9592,1094,4281,1203,3366,8134,828,3676,4760,3451,1354,4038,250,8227,6864,6435,4349,6344,4305,1205,1004,6099,3824,19
36,3913,585,438,5881,7644,6733,9214,9347,1070,9026,9205,4142,5580,4862,415,7988,2998,8669,7191,8759,9077,1278,7258,219,41
11,4726,5287,224,5992,4549,8601,9635,823,2343,4242,1147,8946,6160
8195023659590 column=question:right, timestamp=1610611490284, value=5282,4644,401,8400,4151,6639,7159,5100,1495,9980,5651,3066,9086,709
8,8698,7868,9907,7857,7235,5009,3355,3408,8312,3644,2125,8385,2044,7463,9551,9494,9485,2977,5524,7313,5560,9000,9228,4453
,7860,2119,1123,5863,3391,9300,381,5212,4267,6645,9812,2363,5947,7263,6735,7808,1180,4458,9374,420,954,4802,4841,5210,389
6,5801,6968,9955,3710,8945,8642,1659,7831,3720,2456,773,6069,2909,9686,5582,8099,3806,7629,6188,794,1147,9937,104,8635,19
78,3908,455,6694,4842,6450,4459,1783,8725,4139,8658,3707,8423,4230,7421,4147,9415,4729,2982,5001,1845,998,7529,4652,8993,
2369,4988,7390,5390,4210,6322,4770,6085,1831,5033,4331,6529,6389,7749,3702,2560,1822,9389,3484,7693,1834,515,5746,2855,21
42,3165,7975,6725,5775,912,200,3583,1015,2508,9392,5514,4266,61,6549,7525,3461,621,4559,9387,7652,2374,3549,6175,7653,410
,9579,583,5523,8359,7771,3801,3016
enmmmmm就是第一套试卷 此贴终结
截图 windows+shift+s