分布式计算基础试卷
一、 单选题(本题共15题,每题1分,共15分,答案填写在下表中)
- 以下哪一项不属于Hadoop可以运行的模式( )。
A. 单机(本地)模式 B. 伪分布式模式
C. 互联模式 D. 分布式模式
- 下列哪项通常是集群的最主要瓶颈 ( )。
A. CPU B. 网络
C. 磁盘 IO D. 内存
- 在 Hadoop 2.x 及以上版本中,HDFS默认的 Block Size 是( )。
A. 32M B. 128M
C. 64M D. 256M
- 下面与HDFS类似的文件存储系统是( )。
A. NTFS B. FAT32 C. EXT3 D. GFS
- Client在HDFS上进行文件写入时,NameNode根据文件大小和配置情况,返回部分DataNode信息, 负责将文件划分为多个Block,根据DataNode的地址信息,按顺序写入到每一个DataNode块。 ( )
A. Client B. NameNode C. DataNode D. Secondary NameNode
- HDFS 是基于流数据模式访问和处理超大文件的需求而开发的,具有高容错、高可靠性、高可扩展性、高吞吐率等特征,适合的读写任务是 ( )。
A.一次写入,少次读 B.一次写入,多次读
C.多次写入,少次读 D.多次写入,多次读
- 关于 Secondary NameNode 下面哪项是正确的 ( )。
A. 它是 NameNode 的热备
B. 它对内存没有要求
C. Secondary NameNode 应与 NameNode 部署到一个节点
D. 它的目的是帮助 NameNode 合并编辑日志,减少 NameNode 工作压力和启动时间
- HDFS的 NameNode负责管理文件系统的命名空间,将所有的文件和文件夹的元数据保存在一个文件系统树中,这些信息也会在硬盘上保存成以下文件:( )。
A. 日志(即edits)
B. 命名空间镜像(即fsimage)
C. 两者都是
D. 两者都不是
- hadoop fs 中的 -get 和 -put 命令操作对象是 ( )。
A. 文件 B. 目录
C. 两者都是 D. 两者都不是
- 下列关于 MapReduce说法不正确的是 ( )。
A. MapReduce 是一种计算框架
B. MapReduce 来源于 Google 的学术论文
C. MapReduce 隐藏了并行计算的细节,方便使用
D. MapReduce 程序只能用 Java 语言编写
- HBase 依靠 存储底层数据。 ( )
A. HDFS B. Hive
C. Memory D. MapReduce
- 下面哪一个不是 Hadoop 中的启动命令 ( )。
A. start-all.sh B. start-dfs.sh
C. start-yarn.sh D. start-hadoop.sh
- 下列关于 Hadoop API 的说法错误的是 ( )。
A. Hadoop 的文件 API 不是通用的,只用于 HDFS文件系统,不能用于本地文件系统
B. Configuration 类的默认实例化方法是以 HDFS系统的资源配置为基础的
C. FileStatus 对象存储文件和目录的元数据
D. FSDataInputStream 是 java.io.DataInputStream 的子类
- 在Hadoop 2.x 版本中,在 HDFS 上存放一个大小为 130M 的文件,现在使用 MapReduce 做词频统计,存储该文件的时候采用的 Block 大小为默认大小,其他的 minSplitSize 与 maxSplitSize 大小均为默认值,那么 MapReduce 程序执行的时候切片的大小为 ,读取该文件会制作 个切片。 ( )
A. 130M,1 B. 128M,1
C. 130M,2 D. 128M,2
- 下面对HBase的描述哪项是错误的 ( )。
A. 不是开源的
B. 是面向列的
C. 是分布式的
D. 是一种非关系型数据库
二、 填空题(本题共15空,每空1分,共15分)
-
Hadoop 2.x 架构中包含四大组件,分别为 Common 、 HDFS 、 Yarn 、 MapReduce 。
-
Hive 的三种搭建模式分别为: 内嵌模式 、 本地模式(独立模式) 、 远程模式 。
-
启动 Hive元数据服务的命令为: hive --service metastore 。
-
启动 Yarn 的脚本名称为: start-yarn.sh 。
-
启动 HBase的脚本名称为: start-hbase.sh 。
-
显示 HDFS 根路径下的文件列表的命令为: hadoop fs -ls / 。
-
MapReduce 将一个 Job 分成若干个 Task 执行,其中包括 MapTask 和 ReduceTask 。
-
Namenode 默认的 WEBUI 的访问端口号为: 50070 。
三、 简答题 (共37分)
- 简述 MapReduce 任务的执行流程(文字说明或画图均可)。(8分)
-
MapTask收集我们的map()方法输出的kv对,放到环形缓冲区中
-
从内存缓冲区不断溢出本地磁盘文件,可能会溢出多个文件
-
多个溢出文件会被合并成大的溢出文件
-
在溢出过程及合并的过程中,都要调用Partitioner进行分区和针对key进行排序
-
ReduceTask根据自己的分区号,去各个MapTask机器上抓取相应的结果分区数据
-
ReduceTask会取到同一个分区的来自不同MapTask的结果文件,ReduceTask会将这些文件再进行合并(归并排序)
-
合并成大文件后,Shuffle的过程也就结束了
后面进入ReduceTask的逻辑运算过程(从文件中取出一个一个的键值对Group,调用用户自定义的reduce()方法)
-
最后一个ReduceTask输出到一个文件中
- 写出在 Hive 中内部表与外部表的区别。(4分)
- 数据管理
内部表数据由Hive管理;
外部表数据由HDFS管理;
- 存储位置
内部表数据存储位置为Hive配置文件制定的位置;
外部表数据存储位置由用户自定义;
- 表删除
删除内部表会直接删除元数据和存储数据;
删除外部表仅仅删除元数据,HDFS上的文件不会删除;
- 简述Hive中order by,sort by,distribute by,cluster by的区别(8分)
-
order by数据做全局排序。无论设定多少个Reducer,最终都只有一个输出
-
sort by不是全局排序,是区内排序。会根据设定的Reducer的个数对数据进行分区,保证区内有序
-
distribute by是控制数据根据哪个字段进行MR分区。主要结合sort by 共同使用
-
cluster by除了具有distribute by的功能外还兼具sort by的功能。当MR分区字段与排序字段一样的时候,就可以使用cluster by。但是只能是倒叙排序,不能指定排序规则为ASC或者DESC。
- 传统关系型数据库与HBase数据库的区别(6分)
- 数据类型
HBase只有简单的字符类型,所有的类型都是交由用户自己处理,它只保存字符串。
而关系数据库有丰富的类型和存储方式。
- 数据操作
HBase只有很简单的插入、查询、删除、清空等操作,表和表之间是分离的,没有复杂的表和表之间的关系。
而传统数据库通常有各式各样的函数和连接操作。
- 存储模式
HBase是基于列存储的,每个列族都由几个文件保存,不同的列族的文件是分离的。
而传统的关系型数据库是基于表格结构和行模式保存的
- 数据维护
HBase的更新操作不应该叫更新,它实际上是插入了新的数据
而传统数据库是替换修改
- 可伸缩性
HBase这类分布式数据库就是为了这个目的而开发出来的,所以它能够轻松增加或减少硬件的数量,并且对错误的兼容性比较高。
而传统数据库通常需要增加中间层才能实现类似的功能
- 简述 HDFS 写数据的流程(文字说明或画图均可)。(6分)
-
客户端向NameNode发送写数据的请求,NamNode响应可以上传文件
-
客户端向NameNode请求上传第一个Block块
-
NameNode向客户端返回第一个Block可以存放的DataNode节点信息
-
客户端向指定的存储副本的DataNode节点发送请求建立连接通道
-
如果连接通道建立成功则开始上传数据,反之重新向NameNode发送请求DN节点信息
-
当第一个Block块上传成功后,客户端会请求上传第二个Block,以此类推
- 简述大数据的特征(5分)
-
容量(Volume)大
-
种类(Variety):数据类型的多样
-
速度(Velocity):指获得数据的速度快
-
真实性(Veracity):数据的质量。数据真实性低。
-
价值(Value):价值密度低
四、 HQL 设计题(共15分)
1、在 Hive 仓库中存在4个表,创建表的HQL语句如下:
-- 创建学生表
create table if not exists student(
sno int, -- 学生的学号
sname string, -- 学生姓名
sage int, -- 学生的年龄
ssex boolean -- 学生的性别:true表示男,false表示女
)
row format delimited fields terminated by '\t';
-- 创建教师表
create table if not exists teacher(
tno int, -- 教师编号
tname string -- 教师名字
)
row format delimited fields terminated by '\t';
-- 创建课程表
create table if not exists course(
cno int, -- 课程编号
cname string, -- 课程名称
tno int -- 任教教师编号
)
row format delimited fields terminated by '\t';
-- 创建成绩表
create table if not exists score(
sno int, -- 学生学号
cno int, -- 课程编号
score int -- 分数
)
row format delimited fields terminated by '\t';
2、请写出以下需求的HQL 语句。
- 求每个学生的平均成绩,返回学生学号和平均成绩即可。(3分)
select s.sno, avg(s.score) avg_score from score s group by s.sno;
- 查询学生表的所有数据。(2分)
select * from student;
3.统计老师的姓名以“zhang”开头的老师的个数(3分)
select count(1) from teacher where tname like 'zhang%';
- 把成绩按照从高到底排序(3分)
select a.sno as 学号, b.sname as 姓名, sum(a.score) as 总成绩 from
score a, student b
where a.sno = b.sno
group by a.sno;
五、 程序设计题(每空2分,共18分)
程序需求如下:
该程序要完成文本数据中的单词个数的统计。输入路径为 HDFS 中的目录 /wc/in,其中有10个文件,分别为 text1,text2,text3,…,text10。所有文件中的单词均以空格分隔。将统计结果分别输出到5个文件中。为了提高统计效率,请增加相关MapReduce程序阶段。
package cn.edu.zut.bigdata.mr.wc;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.*;
import java.io.IOException;
public class WordCount {
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
//创建 Job 对象,给 Job 起名为 WordCount
Job job = Job.*getInstance*(conf, **"WordCount"**);
job.setMapperClass(MyMapper.class);
job.setReducerClass(MyReducer.class);
//加快 MR 执行的效率,设置Job的其他参数
job.setCombinerClass(MyReducer.**class**);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class);
job.setOutputKeyClass(Text.class); job.setOutputValueClass( IntWritable.**class** );
//设置 Reducer的任务数
job.setNumReduceTasks(5);
//设置输入路径
FileInputFormat.setInputPaths(job, new Path("/wc/in"));
//设置输出路径
FileOutputFormat.setOutputPath(job, new Path("/wc/out/"));
job.waitForCompletion(true);
}
}
class MyMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
@Override
protected void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
//对数据做切分
String[] strs = value.toString().split(**" "**) ;
for(String str:strs) {
context.write(**new** Text(str), **new** IntWritable(1)) ;
}
}
}
class MyReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
@Override
protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
int sum = 0;
for(IntWritable v:values) {
//计算单词的个数
sum+=v.get();
}
context.write(key, new IntWritable(sum));
}
}