Hadoop的实现原理及基本使用方法

    网上有很多介绍Hadoop安装部署的资料,这篇文章不会向大家介绍Hadoop的安装及部署方法,我会重点向大家介绍Hadoop实现的基本原理,这样当我们今后学习Hadoop生态相关的知识时可以快速入门。

        

Hadoop是什么

    我们首先要知道Hadoop是什么,按照官方的解释,Hadoop是一个由Apache基金会开发的分布式系统基础架构,可提供高可用、高扩展、高效、低成本的服务

Hadoop提供的服务包括HDFS、MapReduce和YARN;其中HDFS用于海量数据的存储,MapReduce用于海量数据的分析和计算,YARN怎用于资源的管理和调度,

Hadoop的高可用、高扩展及低成本的特性就是通过以上三种服务实现的。Hadoop适用于处理海量数据,如果数据量不大则不建议使用Hadoop。

    Hadoop的生态圈包括以下常用的软件,其中HDFS、YARN、MapReduce是Hadoop提供的核心服务;其它的则是依赖Hadoop构建的应用。

image.png

HDFS介绍

    HDFS即Hadoop分布式文件系统(Hadoop Distribute File System),用于存储海量数据,HDFS维护了一套虚拟的文件系统用户管理保存的数据;HDFS使用普通的PC机即可,这也是使用Hadoop处理大数据成本相对较低的原因。文件保存在Hadoop上时,Hadoop会根据配置将文件保存多个副本,这样当有一台机器宕机时,获取文件不受任何影响,实现了高可用。

    HDFS主要提供了NameNode和DataNode两个服务,其中Name用于接收客户端的请求、保存元数据;DateNode是真正保存数据的地方。当我们HDFS启动成功后使用JPS命令可以看到实际上就是启动了NameNode服务和DataNode服务,如下图所示:

image.png          image.png

    NameNode中的元数据信息包括:HDFS文件的虚拟目录、文件副本数量、文件块名称、文件块所属机器,如元数据:/test/a.log, 2 ,{blk_1,blk_2}, [{blk_1:[10.2.200.1]},{blk_2:[10.2.200.2]}]表示,在Hadoop中的/test目录下存在a.log文件,且这个文件被切分成2块blk_1和blk_2,没有副本,blk_1在10.2.200.1机器上,blk_2在10.2.200.2,元文件保存在NameNode所在的机器上,文件名为fsimage_*,如下图所示:

image.png

    DataNode是真正保存文件数据的地方,DataNode接收客户端的请求,并完成文件的读或写,HDFS会将大文件切分保存,默认情况下块的大小为128M。

    HDFS处理客户端请求的大致流程如下图所示:

image.png

    向Hadoop上传文件的过程为(write):1、客户端向NameNode请求上传文件,NameNode维护虚拟目录信息,根据文件大小计算出需要切分成多少块,并分配DataNode节点,2、NameNode将分块信息、分配的DataNode节点信息返回给客户端,3、客户端根据获取的DataNode节点信息和DataNode节点通信,将文件上传至DataNode节点。DataNode节点保存文件的实际位置通过dfs.namenode.name.dir配置。

    从Hadoop下载文件的过程为(read):1、客户端向NameNode请求下载文件,2、NameNode根据提供的虚拟目录返回元数据信息,3、客户端根据返回的元数据信息到具体的DateNode上下载文件。


HDFS实现原理

    HDFS的服务是通过RPC调用的方式实现服务端和客户端的通信,具体来说就是DataNode和NameNode均开启了socket服务,客户端和服务端实现了相同的接口,客户端根据接口定义的方法,通过Java的动态代理调用相关的方法。(如果了解Dubbo,就能了解的比较具体,调用方式和Dubbo类似)。

    HDFS的RPC框架使用方式如下:

// 服务端开启服务
Builder builder = new RPC.Builder(new Configuration());

// 设置服务的地址、端口、协议、及服务的实现实例
builder.setBindAddress("hadoop").setPort(18080).setProtocol(ILogin.class).setInstance(new LoginImpl());

// 启动服务
Server server =builder.build();
server.start();


// 客户端调用方式
ILogin login = RPC.getProxy(ILogin.class,1L,new InetSocketAddress("192.168.1.1",18080), new Configuration());
String returnMsg = login.login("tom");

HDFS相关API和shell

    HDFS提供了Java相关的API,以便通过程序调用的方式操作HDFS,通过HDFS的API我们可以对HDFS上的文件实现上传、下载、删除、修改、压缩等操作。

// 下载文件
FSDataInputStream inputStream = fs.open(new Path("/test.txt"));
FileOutputStream fio = new FileOutputStream("/home/hadoop/hdfs.txt");
IOUtils.copy(inputStream, fio);

// 上传文件
FSDataOutputStream os = fs.create(new Path("/test.txt"));
FileInputStream is = new FileInputStream("/home/hadoop/hdfs.txt");
IOUtils.copy(is, os);

// 删除文件
fs.delete(new Path("/testHadoop"), true);

HDFS中经常使用的Shell包括

hadoop fs -ls /hadoop   查看HDFS目录列表

hadoop fs -mkdir /test  创建目录test

hadoop fs -put ./test.txt /test 或 hadoop fs -copyFromLocal ./test.txt /test 上传文件至HDFS

hadoop fs -get /test/test.txt 或 hadoop fs -getToLocal /test/test.txt  从HDFS上下载文件

hadoop fs -cp /test/test.txt /test1 拷贝文件

hadoop fs -rm /test1/test.txt 删除文件

hadoop fs -mv /test/test.txt /test1  修改文件名


MapReduce介绍

    Hadoop中HDFS用于存储数据,MapReduce用于处理数据,MapReduce程序的运行依赖于YARN分配资源;MapReduce程序主要有两个阶段构成:Map和Reduce,客户端只要分别实现map()函数和reduce()函数,即可实现分布式计算。

    map任务的处理过程为:读取文件中每一行的内容,根据具体的业务逻辑处理行数据,并将处理结果生成键值对输出

    reduce任务的处理过程为:在做reduce操作之前,会有一个shuffle的操作,该操作主要是对map的处理结果进行合并、排序,然后对map输出的键值对进行处理,得到处理结果后,同样以键值对的形式保存到文件。

    MapReduce的任务提交流程大致如下图所示:

image.png


MapReduce Java API

    MapReduce提供了Java相关的API,我们可以根据提供的API实现MapReduce程序,这样我们就可以根据实际的业务需求完成对大数据的处理,API示例如下:

// map函数处理过程
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
    // 将该行内容转换为字符串
    String strValue = value.toString();
    String[] words = StringUtils.split(strValue, ' ');

    // 遍历数组,并将数据输出(key-value形式)
    for(String word : words) {
        context.write(new Text(word), new LongWritable(1));
    }
}

// reduce函数处理过程
@Override
protected void reduce(Text key, Iterable<LongWritable> values, Context context) throws IOException, InterruptedException {
    int count = 0;

    for(LongWritable value : values) {
        count += value.get();
    }

    context.write(key, new LongWritable(count));
}

// 调用Map和Reduce
// job使用的mapper和reducer
job.setMapperClass(WordCountMapper.class);
job.setReducerClass(WordCountReduce.class);

// 设置reducer的输入输出类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(LongWritable.class);

// 设置mapper的输入输出类型
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(LongWritable.class);

// 设置map处理数据所在的路径
FileInputFormat.setInputPaths(job, new Path("/upload/"));

// 设置reducer处理数据的输出路径(注:wordcount文件夹不能创建,程序会自动创建,如果自己创建会报错)
FileOutputFormat.setOutputPath(job, new Path("/wordcount/"));

job.waitForCompletion(true);

Hive简介

    通过上面的介绍我们知道对大数据的处理和运算需要通过编写MapReduce程序来实现,这就对大数据处理人员提出了编码要求,为了简化大数据处理的实现,Hive出现了,Hive的本质就是实现了对MapReduce的封装,Hive通过解析SQL语句,将SQL语句中的相关内容作为MapReduce程序的入参,调用预先实现好的MapReduce任务,从而完成大数据的处理任务。通过编写SQL进而实现数据处理,避免了开发人员亲自编码实现MapReduce,从而大大降低了数据处理的难度,提高了开发效率。

    Hive建库就是在HDFS上创建文件夹,建表就是在库对应的文件夹下创建子文件夹,表名即文件夹名,分区表就是在表下创建子文件夹,分桶表就是将一个大文件按照一定的规则划分为几个小文件,执行Hive SQL的过程就是处理相关表对应的文件夹下文件的过程。

    额外说明下,Hive处理数据实际上就是执行MapReduce的过程,而执行MapReduce会有大量读写磁盘的操作,因此Hive处理大数据的过程会比较慢;Spark的出现解决了这个问题,Spark处理数据的原理和MapReduce总体相似,但是Spark处理数据和磁盘交互比较少,大部分都是在内存中计算数据,所以Spark处理数据的效率要比MapReduce高的多。

HBase简介

    HBase可以理解为构建在HDFS上的NoSql数据库,Hbase通过key、value的方式保存海量数据,Hbase的数据文件保存在HDFS上,Hbase的Tabel在行的方向上分割为多个HRegion,每个Region由[startKey,EndKey]表示,Region分布在RegionServer,示意图如下:

image.png

文章中相关API完整的源码信息可关注微信公众号 布衣暖 回复hadoop获取

buyinuan.jpg


猜你喜欢

转载自blog.51cto.com/2342615/2345700