• 1. Hadoop介绍1.概括介绍 2.框架介绍 2.1 HDFS 2.2 I/O操作 2.3 MapReduce
  • 2. 概要介绍1. Hadoop就是一个分布式系统基础架构。用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力高速运算和存储 。 2. Hadoop是项目的总称,主要是由Hdfs、MapReduce组成 。 3. Hadoop就是一个类包,我们使用的一般是java写的类包,程序中导入该包就可以使用它封装的各种类来写Hadoop程序 4. 运行Hadoop程序目前只能在Linux系统上,window上运行需要安装其他插件,实习公司的Hadoop程序是在window下开发(编写程序),在3台ubuntu系统上测试(测试程序正确性)。
  • 3. 5. 个人的观点:Hadoop中存在很多命令行,就像Linux 中的命令行一样,所以一定要学好linux;Hadoop中存在上千个参数,运行特定的程序,要想取得很好的效果,正确的设置参数是一个很重要的方面。 例如:参数dfs.block.size(Hdfs中block的大小)。 6. 学好Hadoop,首先必须懂的它的总体框架,然后是它封装的各种类的用法,最后是对源码进行解读。
  • 4. HDFS概要介绍 储存基本单元 基本框架
  • 5. 概要介绍 1.Hadoop中的抽象类fs.FileSystem封装文件系统的一般特 性,它有很多种应用不同领域的文件系统格式,例如, Local、FTP,等等。而Hdfs是为使用Map-Reduce实现高 效而设计的。 2.HDFS(分布式文件系统),为以流式数据访问模式存储超 大文件而设计的文件系统。我们把它当做一个专门储存 MapReduce数据的磁盘就可以了。 3.Hdfs的路径格式:hdfs://localhost/user/tom
  • 6. 储存基本单元 Block(块)。HDFS基本储存单元,是个逻辑单元,和os中 的页类似。 一个文件有可能包含多个块,一个块有可以包含多个文 件,由文件的大小和块大小的参数决定。 dfs.block.size参数。Hdfs中Block的大小,默认64MB, 如果设置大,就会有可能导致Map运行慢,设置小,有可能 导致Map个数多,所有一定要设置适当。
  • 7. Hdfs集群框架图:
  • 8. NameNode记录着每个文件的元数据。每个文件在那个块中,每个数据节点包含哪些块。(不储存原始文件) DataNode是文件的工作者,它们存储文件并提供定位块的服务,并且定时向名称节点发送它们的存储块的列表。 (储存原始文件) 3. 重要参数 dfs.replication.min参数。最小为1,表示每个块在HDFS中的副本个数。 。
  • 9. I/O操作 Writable接口 Writable接口的子类
  • 10. Writable接口 1. 序列化:指的是将结构化对象转换为字节流以便网络进行传输或者写入存储的过程。 反序列化:指的是将字节流转为一系列结构化对象的过程。 2. 在hadoop中,常规JAVA数据结构是不能表示Hdfs的数据类型的,例如hdfs中的字符串不是string类表示,而是Text类,这些数据类型都必须实现一个writable接口 。 3. Writable是Hadoop的核心(MapReduce程序使用他来序列化键/值对): void write(DataOutput out) throws IOException; void readFields(DataInput in) throws IOException; 分别实现对数据的序列化和反序列化。
  • 11. Writable接口的子类 1.对Java中的int型进行封装那么就是hadoop中的IntWritable类 在写程序时可以把IntWritable可以看着是int 类型,它实现 了WritableComparable接口。 WritableComparable又是Writable、java.lang.comparable接口的子接口。 2.Writable类对所有的Java基本类型进行封装: 如:boolean -> BooleanWritable;Byte -> ByteWritable 3. 我们可以自定义Writable接口,来编写更复杂的结构的类。 核心:hadoop有自己一套的I/O机制。I/O类都必须实现Writable接口。
  • 12. MapReduceMapReduce数据流 MapReduce的工作原理 MapReduce实例
  • 13. MapReduce数据流 1. Mapreduce是 Hadoop程序的体现。框架极其简单:首先是对Mapreduce程序运行前的参数配置,然后编写map类(实现Map方法),最后是reduce类(实现Reduce方法)。 Mapreduce程序的每个细节都与设置的参数有很大的关系,参数设置的好,程序的效率肯定得到提高。 Map方法:Map(k1,v1) ->list(k2,v2) ,并行应用于每一个输入的数据集,每一次调用都会产生一个(k2,v2)的队列 。 Reduce方法:Reduce(k2,list(v2)) -> list(k3,v3)。收集map端输出队列list(k2,v2)中有相同key的数据对,把它们聚集在一起,输出时形成目的数据 list(k3,v3)。
  • 14. 2. MapReduce的数据流: 2.1 根据输入数据的大小和参数的设置把数据分成splits, 每个split对于一个map线程。
  • 15. 2.2 Split中的数据作为Map的输入, Map的输出一定在Map端。 2.3 Map的输出到Reduce的输入的过程(shuffle过程): 第一阶段:在map端完成 内存->排序->写入磁盘->复制 分区->排序->分区合并->合并后分区->复制 第二阶段:在reduce端完成 映射到reduce端分区->合并->排序 2.4 Reduce的输入到Reduce的输出 最后排好序的key/value作为Reduce的输入,输出不一定 是在reduce端。
  • 16. MapReduce的工作原理 MapReduce 程序1:run jobJobClient客户端JVMJobTrackerTaskTrackerChildMapTask或者 ReduceTaskJobtracker节点子JVMTasktracker 节点HDFS2:get new job ID3:copy Job rescouce4:submit job5:initialize job6:retrieve Input splits7:returns task8:retrieve job resources10:run9:launch客户端:提交MapReduce作业,即一个job。 jobTracker:协调作业的运行。 taskTracker:作业划分后的任务 (一个job对应多个task,一个task对应一个 或者多个MapReduce线程)。
  • 17. 作业运行说明: 2. 检查作业的输出说明。 3. 计算作业的输入划分。 4. 向jobTracker提交作业需要的资源(作业的jar包,配置文件等等) 6. 创建运行列表,jobTracker从共享文件中获取JobClient 以计算好的输入划分信息。 8. 将应用程序所需要的全部文件从分布式缓存复制到本地磁盘,然后,为任务新建一个本地工作目录,并把jar文件中的内容解压到这个文件夹中。 9. 启动一个新的Java虚拟机。
  • 18. Map个数选择: Map个数不能确定,它与很多参数有关系。 我们设置的Map个数它只是一个参考值,它与输入的数据的大小,dfs.block.size参数,还有split块的上下界的参数共同决定split的个数,而split的个数就是map的个数。 Reduce个数选择 设置的Reduce个数即为运行的Reduce个数。 最优的Reduce个数取决于集群中可用的 reduce任务槽的数目。这个数目是集群节点数据与节点数目最大的reduce task参数的乘积。 我们在程序中设置这个Reduce个数就可以了。
  • 19. 实例写MapReduce程序的步骤: 1.把问题转化为MapReduce模型 2.设置运行的参数 3.写map类 4.写reduce类 例子:统计单词个数 My name is li lei What is your nameMy 1 name 2 is 2 What 1 your 1 li 1 lei 1
  • 20. MapReduce模型 1.Map端 一行行读文件,程序转化为中间Key/Value. My name is li lei ->My 1,name 1, is 1, li 1, lei 1 What is your name ->What 1, is 1, your 1 name 1 2.Reduce端 相同的key肯定会在一起。经过Reduce方法处理后, 形成最终的key/Value. name 1,name 1->name 2;
  • 21. 设置运行的参数 JobConf conf = new JobConf(getConf(), WordCount.class); //获得对job的配置类 conf.setJobName("wordcount"); //给job取个名字 conf.setOutputKeyClass(Text.class); conf.setOutputValueClass(IntWritable.class); // 设置输入key/value的类型 conf.setMapperClass(MapClass.class); conf.setReducerClass(Reduce.class); //设置运行的MapReduce conf.setInputPath(new Path(args[0])); //设置输入的路径名 conf.setOutputPath(tempDir); //设置输出的路径名 JobClient.runJob(conf); //提交作业
  • 22. 写Map类 public static class MapClass extends MapReduceBase implements Mapper{ //以上为写map类的固定格式 private final static IntWritable one = new IntWritable(1); private Text word = new Text(); public void map(LongWritable key, Text value, OutputCollector output, Reporter reporter) throws IOException { // //以上为写map方法的固定格式 String line = value.toString(); StringTokenizer itr = new StringTokenizer(line); //把一行字符串安装空格键分开 while (itr.hasMoreTokens()) { //遍历一行的所有单词 word.set(itr.nextToken()); output.collect(word, one);//收集key/value给reduce作为输入 } } }
  • 23. 写Reduce类 public static class Reduce extends MapReduceBase implements Reducer { public void reduce(Text key, Iterator values, OutputCollector output, Reporter reporter) throws IOException) { int sum = 0; while (values.hasNext()) { sum += values.next().get(); //相同的key的value累加。 } output.collect(key, new IntWritable(sum)); //收集最终的key/value. } }