云计算与大数据第15章 分布式大数据处理平台Hadoop习题带答案

第15章 分布式大数据处理平台Hadoop习题

15.1 选择题

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

15.2 填空题

1、HDFS的基本数据存储单位是(  数据块  )。

2、MapReduce按照时间顺序可以分为输入分片、(  Map阶段  )、Combiner阶段、(  Shuffle阶段  )和(  Reduce阶段  )。

15.3 简答题

1、Hadoop主要有哪些优点?

答:

  1. 扩容能力强。Hadoop 能可靠存储和处理PB级的数据。
  2. 成本低。Hadoop 能通过普通机器组成的服务器集群来分发和处理数据,服务器集群规模可达数千个节点。
  3. 效率高。Hadoop 能通过分发数据,在数据所在的节点上并行地进行处理,使得处理非常快速。
  4. 可靠性。Hadoop 能自动维护数据的多份副本,并在任务失败后自动地重新部署计算任务。
  5. 高容错性。Hadoop能在不同的节点上维护多份副本,对于访问失败的节点,Hadoop会自动寻找副本所在的节点进行访问

2、请用描述HDFS读取文件的具体步骤。

答:

  1. 客户端用分布式文件系统的open()函数打开文件。
  2. 分布式文件系统远程调用RPC,获取元数据节点的文件数据块信息;对于返回的每一个数据块信息,元数据节点只返回保存数据块的数据节点的地址;接着分布式文件系统返回FSDataInputStream对象给客户端,其中封装了读取数据的方法。
  3. 客户端调用FSDataInputStream中的read()函数开始读取数据;FSDataInputStream封装了DFSInputStream对象中用于管理元数据节点和数据节点的I/O操作的方法,客户端调用read()函数后,使用DFSInputStream对象中的I/O操作;DFSInputStream连接一直保持,直到当前读取的文件中第一个数据块的最近数据节点中的数据读到客户端后,DFSInputStream会关闭和此数据节点的连接;然后连接此文件的下一个数据块的最近数据节点。若在读取数据的过程中,客户端与数据节点的通信出现错误,则尝试连接包含此数据块的下一个数据节点;失败的数据节点将被记录,以后不再连接。
  4. 当客户端读取完数据时,调用DFSInputStream的close()函数,结束读取过程。

3、请描述HDFS写文件的具体过程。

答:

  1. 客户端调用create()函数来创建文件。
  2. 分布式文件系统远程调用RPC,在元数据节点的命名空间中创建一个新的文件。元数据节点在确定文件不存在,并且客户端有创建文件的权限后,创建新文件。创建完成后,分布式文件系统返回DFSOutputStream对象给客户端,用于写数据。文件系统返回DFSOutputStream对象给客户端,用于写数据。
  3. 当客户端开始写数据时,调用DFSOutputStream中的方法将数据分成块并写入数据队列;数据队列由Data Streamer读取,并通知元数据节点分配数据节点,用来存储数据块(每个数据块均默认复制3份),分配的数据节点放在一个管道(Pipeline)里。其中,Data Streamer是在调用DFSOutputStream对象过程中开启的线程。
  4. Data Streamer将数据块写入管道涉及的第一个数据节点,第一个数据节点将数据块发送给第二个数据节点,第二个数据节点将数据发送给第三个数据节点。
  5. DFSOutputStream将发送出去的数据块信息保存在ack queue队列里。如果数据块传输成功的话,就会删除ack queue队列里对应的数据块;如果不成功的话就将ack queue里的数据块取出来放到数据队列的末尾,等待重新传输。
  6. 当客户端结束写入数据过程,则调用DFSOutputStream中的close()函数,此时客户端不再向管道中写入数据,并关闭管道。在等到所有的写入数据的成功应答后,通知元数据节点写入完毕。

        

15.4 解答题

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

1363157984040     13602846565  5C-0E-8B-8B-B6-00:CMCC  120.197.40.4  2052.flash2-http.qq.com 综合门户       15       12    1938       2910       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+"\t"+this.down+"\t"+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{

       @Override

       protected void map(LongWritable key, Text value,

                      Context context)

                     throws IOException, InterruptedException {

                      //拿一行数据

                            String line = value.toString();

                            //切分成各个字段

                            String[] fields = StringUtils.split(line, "\t");

                           

                            //拿到我们需要的字段

                            String phone = fields[1];

                            long  up= Long.parseLong(fields[8]);

                            long  down = Long.parseLong(fields[9]);

                            //封装数据为kv并输出       

                            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 {

    @Override

    protected void reduce(Text key, Iterable values,

                          Context context)

            throws IOException, InterruptedException {

        // 

        // 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

你可能感兴趣的:(hadoop,mapreduce,大数据)