网上有很多介绍Hadoop安装部署的资料,这篇文章不会向大家介绍Hadoop的安装及部署方法,我会重点向大家介绍Hadoop实现的基本原理,这样当我们今后学习Hadoop生态相关的知识时可以快速入门。
Hadoop是什么
我们首先要知道Hadoop是什么,按照官方的解释,Hadoop是一个由Apache基金会开发的分布式系统基础架构,可提供高可用、高扩展、高效、低成本的服务。
Hadoop提供的服务包括HDFS、MapReduce和YARN;其中HDFS用于海量数据的存储,MapReduce用于海量数据的分析和计算,YARN怎用于资源的管理和调度,
Hadoop的高可用、高扩展及低成本的特性就是通过以上三种服务实现的。Hadoop适用于处理海量数据,如果数据量不大则不建议使用Hadoop。
Hadoop的生态圈包括以下常用的软件,其中HDFS、YARN、MapReduce是Hadoop提供的核心服务;其它的则是依赖Hadoop构建的应用。
HDFS介绍
HDFS即Hadoop分布式文件系统(Hadoop Distribute File System),用于存储海量数据,HDFS维护了一套虚拟的文件系统用户管理保存的数据;HDFS使用普通的PC机即可,这也是使用Hadoop处理大数据成本相对较低的原因。文件保存在Hadoop上时,Hadoop会根据配置将文件保存多个副本,这样当有一台机器宕机时,获取文件不受任何影响,实现了高可用。
HDFS主要提供了NameNode和DataNode两个服务,其中Name用于接收客户端的请求、保存元数据;DateNode是真正保存数据的地方。当我们HDFS启动成功后使用JPS命令可以看到实际上就是启动了NameNode服务和DataNode服务,如下图所示:
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_*,如下图所示:
DataNode是真正保存文件数据的地方,DataNode接收客户端的请求,并完成文件的读或写,HDFS会将大文件切分保存,默认情况下块的大小为128M。
HDFS处理客户端请求的大致流程如下图所示:
向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的任务提交流程大致如下图所示:
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,示意图如下:
文章中相关API完整的源码信息可关注微信公众号 布衣暖 回复hadoop获取
原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/186263.html