1、分布式系统的特点不包括以下的( D )。
A. 分布性 B. 高可用性 C. 可扩展性 D.串行性
2、Hadoop平台中的( B )负责数据的存储。
A. Namenode B. Datanode C. JobTracker D. SecondaryNamenode
3、HDFS中block的默认副本数量是( A )。
A.3 B.2 C.1 D.4
4、下面与HDFS类似的框架是( C )。
A. NTFS B. FAT32 C. GFS D. EXT3
5、以下关于SecondaryNamenode的说法正确的是( B )。
A.是元数据节点出现故障时的备用节点
B.周期性地将元数据节点的命名空间镜像文件与修改日志进行合并
C.与元数据节点之间无需交互
D.对内存没有要求
6、下列关于MapReduce的说法不正确的是( C )。
A.MapRecuce可用于处理分布在几千台机器上的数据
B.MapReduce是一种处理大数据的分布式计算模式
C.MapReduce程序只能用C语言编写
D.MapReduce隐藏了并行计算的细节,方便使用
7、下面哪一个是一种编程模型,将大规模的数据处理工作拆分成互相独立的任务然后进行并行处理( A )。
A.MapReduce B.HDFS C.HBase D.Pig
8、HBase基于( A )存储底层数据。
A.HDFS B.Hadoop C.内存 D.MapReduce
9、下面关于HBase错误的是( A )。
A.不是开源的 B.面向列的 C.分布式的 D.NoSQL数据库
10、配置Hadoop时,JAVA_HOME包含在( B )配置文件中。
A.Hadoop-default.xml B.hadoop-env.sh
C.Hadoop-site.xml D.Configuration.xsl
1、HDFS的基本数据存储单位是( 数据块 )。
2、MapReduce按照时间顺序可以分为输入分片、( Map阶段 )、Combiner阶段、( Shuffle阶段 )和( Reduce阶段 )。
1、Hadoop主要有哪些优点?
答:
2、请用描述HDFS读取文件的具体步骤。
答:
3、请描述HDFS写文件的具体过程。
答:
1、根据用户手机上网的行为记录,基于 MapReduce编程模型设计程序统计不同手机号的用户使用的总流量。其中,数据记录的字段描述如下。
序号 字段 字段类型 描述 0 reportTime long 记录报告时间戳 1 msisdn String 手机号码 2 apmac String AP mac 3 acmac String AC mac 4 host String 访问的网址 5 siteType String 网址种类 6 upPackNum long 上行数据包数,单位:个 7 downPackNum long 下行数据包数,单位:个 8 upPayLoad long 上行总流量,要注意单位的转换:byte 9 downPayLoad long 下行总流量。要注意单位的转换:byte 10 httpStatus String HTTP Response数据文件具体内容如下。
1363157985066 13726230503 00-FD-07-A4-72-B8:CMCC 120.196.100.82 i02.c.aliimg.com 24 27 2481 24681 200
1363157995052 13826544101 5C-0E-8B-C7-F1-E0:CMCC 120.197.40.4 4 0 264 0 200
1363157991076 13926435656 20-10-7A-28-CC-0A:CMCC 120.196.100.99 2 4 132 1512 200
1363154400022 13926251106 5C-0E-8B-8B-B1-50:CMCC 120.197.40.4 4 0 240 0 200
1363157993044 18211575961 94-71-AC-CD-E6-18:CMCC-EASY 120.196.100.99 iface.qiyi.com 视频网站 15 12 1527 2106 200
1363157993055 13560439658 C4-17-FE-BA-DE-D9:CMCC 120.196.100.99 18 15 1116 954 200
1363157995033 15920133257 5C-0E-8B-C7-BA-20:CMCC 120.197.40.4 sug.so.360.cn 信息安全 20 20 3156 2936 200
1363157983019 13719199419 68-A1-B7-03-07-B1:CMCC-EASY 120.196.100.82 4 0 240 0 200
1363157984041 13660577991 5C-0E-8B-92-5C-20:CMCC-EASY 120.197.40.4 s19.cnzz.com 站点统计 24 9 6960 690 200
1363157973098 15013685858 5C-0E-8B-C7-F7-90:CMCC 120.197.40.4 rank.ie.sogou.com 搜索引擎 28 27 3659 3538 200
1363157986029 15989002119 E8-99-C4-4E-93-E0:CMCC-EASY 120.196.100.99 www.umeng.com 站点统计 3 3 1938 180 200
1363157992093 13560439658 C4-17-FE-BA-DE-D9:CMCC 120.196.100.99 15 9 918 4938 200
1363157986041 13480253104 5C-0E-8B-C7-FC-80:CMCC-EASY 120.197.40.4 3 3 180 180 200
1363157995093 13922314466 00-FD-07-A2-EC-BA:CMCC 120.196.100.82 img.qfc.cn 12 12 3008 3720 200
1363157982040 13502468823 5C-0A-5B-6A-0B-D4:CMCC-EASY 120.196.100.99 y0.ifengimg.com 综合门户 57 102 7335 110349 200
1363157986072 18320173382 84-25-DB-4F-10-1A:CMCC-EASY 120.196.100.99 input.shouji.sogou.com 搜索引擎 21 18 9531 2412 200
1363157990043 13925057413 00-1F-64-E1-E6-9A:CMCC 120.196.100.55 t3.baidu.com 搜索引擎 69 63 11058 48243 200
1363157988072 13760778710 00-FD-07-A4-7B-08:CMCC 120.196.100.82 2 2 120 120 200
1363157985079 13823070001 20-7C-8F-70-68-1F:CMCC 120.196.100.99 6 3 360 180 200
1363157985069 13600217502 00-1F-64-E2-E8-B1:CMCC 120.196.100.55 18 138 1080 186852 200
答:
我们需要从数据中统计出每个用户的所有请求的使用的总流量,即统计用户所有请求的上行流量(索引为8)、下行流量(索引为9)之和。得到结果后输出到单独的文件中。
编程环境搭建:
创建一个maven项目,并导入Hadoop的相关依赖。
集群环境准备:将题目中给定的数据文件上传到hdfs中。
Step1:将用户手机号、上行流量、下行流量、总流量封装到一个自定义的bean中,由于这个bean需要在Hadoop中进行传输,我们还需要让bean实现hadoop中的序列化接口。
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.apache.hadoop.io.Writable;
public class Flow implements Writable{
private String phone; //手机号
private long up; //上行流量
private long down; //下线流量
private long sum; //总流量
//无参构造函数
public Flow() {
}
//有参构造函数
public Flow(String phone, long up, long down) {
super();
this.phone = phone;
this.up = up;
this.down = down;
this.sum=this.up+this.down;
}
@Override
public void write(DataOutput out) throws IOException {
out.writeUTF(this.phone);
out.writeLong(this.up);
out.writeLong(this.down);
out.writeLong(this.sum);
}
@Override
public void readFields(DataInput in) throws IOException {
this.phone=in.readUTF();
this.up=in.readLong();
this.down=in.readLong();
this.sum=in.readLong();
}
@Override
public String toString() {
return this.up+" "+this.down+" "+this.sum;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public long getUp() {
return up;
}
public void setUp(long up) {
this.up = up;
}
public long getDown() {
return down;
}
public void setDown(long down) {
this.down = down;
}
public long getSum() {
return sum;
}
}
Step2:编写Map方法
import java.io.IOException;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.commons.lang.StringUtils;
public class FlowSumMapper extends Mapper<LongWritable, Text, Text, Flow>{
@Override
protected void map(LongWritable key, Text value,
Context context)
throws IOException, InterruptedException {
//拿一行数据
String line = value.toString();
//切分成各个字段
String[] fields = StringUtils.split(line, " ");
//拿到我们需要的字段
String phone = fields[1];
long up= Long.parseLong(fields[8]);
long down = Long.parseLong(fields[9]);
//封装数据为kv并输出 <phone:flow>
context.write(new Text(phone), new Flow(phone,up,down));
}
}
Step3:编写Reduce方法
import java.io.IOException;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
public class FlowSumReducer extends Reducer<Text, Flow, Text, Flow> {
@Override
protected void reduce(Text key, Iterable<Flow> values,
Context context)
throws IOException, InterruptedException {
// <phone:{flow,flow,flow,flow}>
// reduce中的业务逻辑就是遍历values,然后进行累加求和再输出
long up = 0;//
long down = 0;
for (Flow flow : values) {
up += flow.getUp();
down += flow.getDown();
}
context.write(key, new Flow(key.toString(), up, down));
}
}
Step4:编写方法入口函数
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
public class FlowSumRunner extends Configured implements Tool{
@Override
public int run(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = Job.getInstance(conf);
job.setJarByClass(FlowSumRunner.class);
job.setMapperClass(FlowSumMapper.class);
job.setReducerClass(FlowSumReducer.class);
//设置map程序的输出key、value
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(Flow.class);
//设置 输出 key、value
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Flow.class);
FileInputFormat.setInputPaths(job, new Path(args[0]));//输入数据路径 /flow/input
//检查一下参数所指定的输出路径是否存在,如果已存在,先删除
Path output = new Path(args[1]);
FileSystem fs = FileSystem.get(conf);
if(fs.exists(output)){
fs.delete(output, true);
}
FileOutputFormat.setOutputPath(job, new Path(args[1]));//输出数据路径 /flow/output
return job.waitForCompletion(true)?0:1;
}
public static void main(String[] args) throws Exception {
int status = ToolRunner.run(new Configuration(), new FlowSumRunner(), args);
System.exit(status);
}
}
Step4:至此,程序编写完毕,使用maven工具将程序打包成一个jar包,并提交到hadoop集群中进行运行。具体的命令如下。其中,{}中写FlowSumRunner的全限定类名。
hadoop jar flow.jar {FlowSumRunner} /flow/input/ /flow/output/
Step5:查看运行结果 hadoop fs -cat /flow/output/part-r-00000
13480253104 720 800 1520
13502468823 408 29340 29748
13560439658 23568 1600 25168
13600217502 747408 800 748208
13602846565 48 7752 7800
13660577991 36 27840 27876
13719199419 0 800 800
13726230503 9924 98724 108648
13760778710 480 800 1280
13823070001 720 800 1520
13826544101 0 800 800
13922314466 12032 14880 26912
13925057413 252 44232 44484
13926251106 56 6908 6964
13926435656 6048 800 6848
15013685858 108 14636 14744
15920133257 80 12624 12704
15989002119 12 7752 7764
18320173382 72 38124 38196