[Hadoop in Action] 第1章 Hadoop简介

  • 编写可扩展、分布式的数据密集型程序和基础知识
  • 理解Hadoop和MapReduce
  • 编写和运行一个基本的MapReduce程序

1、什么是Hadoop

Hadoop是一个开源的框架,可编写和运行分布式应用处理大规模数据。

Hadoop与众不同之处在于以下几点:

  1. 方便——Hadoop运行在由一般商用机器构成的大型集群上,或者云计算服务之上;
  2. 健壮——Hadoop致力于在一般商用硬件上运行,其架构假设硬件会频繁地出现失效;
  3. 可扩展——Hadoop通过增加集群节点,可以线性地扩展以处理更大的数据集;
  4. 简单——Hadoop运行用户快速编写出高效的并行代码。

2、了解分布式系统和Hadoop


理解分布式系统(向外扩展)和大型单机服务器(向上扩展)之间的对比,考虑现有I/O技术的性价比。

理解Hadoop和其他分布式架构([email protected])的区别:

Hadoop设计理念是代码向数据迁移,而[email protected]设计理念是数据迁移。

要运行的程序在规模上比数据小几个数量级,更容易移动;此外,在网络上移动数据要比在其上加载代码更花时间,不如让数据不动而将可执行代码移动到数据所在机器上去。

3、比较SQL数据库和Hadoop

SQL(结构化查询语言)是针对结构化数据设计的,而Hadoop最初的许多应用针对的是文本这种非结构化数据。让我们从特定的视角将Hadoop与典型SQL数据库做更详细的比较:

  1. 用向外扩展代替向上扩展——扩展商用关系型数据库的代价会更加昂贵的
  2. 用键/值对代替关系表——Hadoop使用键/值对作为基本数据单元,可足够灵活地处理较少结构化的数据类型
  3. 用函数式编程(MapReduce)代替声明式查询(SQL)——在MapReduce中,实际的数据处理步骤是由你指定的,很类似于SQL引擎的一个执行计划
  4. 用离线处理代替在线处理——Hadoop是专为离线处理和大规模数据分析而设计的,并不适合那种对几个记录随机读写的在线事务处理模式

4、理解MapReduce

MapReduce是一种数据处理模型,最大的优点是容易扩展到多个计算节点上处理数据;

在MapReduce模型中,数据处理原语被称为mapper和reducer;

分解一个数据处理应用为mapper和reducer有时是繁琐的,但是一旦一MapReduce的形式写好了一个应用程序,仅需修改配置就可以将它扩展到集群中几百、几千,甚至几万台机器上运行。

[动手扩展一个简单程序]

少量文档处理方式:对于每个文档,使用分词过程逐个提取单词;对于每个单词,在多重集合wordcount中的相应项上加1;最后display()函数打印出wordcount中的所有条目。

大量文档处理方式:将工作分布到多台机器上,每台机器处理这些文档的不同部分,当所有机器都完成时,第二个处理阶段将合并这些结果。

一些细节可能会妨碍程序按预期工作,如文档读取过量导致中央存储服务器的带宽性能跟不上、多重集合wordcount条目过多超过计算机的内存容量。此外,第二阶段只有一个计算机处理wordcount任务,容易出现瓶颈,所以可以采用分布的方式运转,以某种方式将其分割到多台计算机上,使之能够独立运行,即需要在第一阶段后将wordcount分区,使得第二阶段的每台计算机仅需处理一个分区。

为了使它工作在一个分布式计算机集群上,需要添加以下功能:

  • 存储文件到许多计算机上(第一阶段)
  • 编写一个基于磁盘的散列表,使得处理不受内存容量限制
  • 划分来自第一阶段的中间数据(即wordcount)
  • 洗牌这些分区到第二阶段中合适的计算机上

MapReduce程序执行分为两个主要阶段,为mapping和reducing,每个阶段均定义为一个数据处理函数,分别称为mapper和reducer。在mapping阶段,MapReduce获取输入数据并将数据单元装入mapper;在reduce阶段,reducer处理来自mapper的所有输出,并给出最终结果。简而言之,mapper意味着将输入进行过滤与转换,使reducer可以完成聚合。

另外,为了扩展分布式的单词统计程序,不得不编写了partitioning和shuffling函数。

在MapReduce框架中编写应用程序就是定制化mapper和reducer的过程,以下是完整的数据流:

  1. 应用的输入必须组织为一个键/值对的列表list(<k1,v1>);
  2. 含有键/值对的列表被拆分,进而通过调用mapper的map函数对每个单独的键/值对<k1,v1>进行处理;
  3. 所有mapper的输出被聚合到一个包含<k2,v2>对的巨大列表中;
  4. 每个reducer分别处理每个被聚合起来的<k2,list(v2)>,并输出<k3,v3>。

5、用Hadoop统计单词——运行第一个程序

  • Linux操作系统
  • JDK1.6以上运行环境
  • Hadoop操作环境

Usage:hadoop [—config configdir] COMMAND

这里COMMAND为下列其中一个:

namenode -format                                             格式化DFS文件系统

secondarynamenode                                         运行DFS的第二个namenode

namenode                                                          运行DFS的namenode

datanode                                                            运行一个DFS的datanode

dfsadmin                                                            运行一个DFS的admin客户端

fsck                                                                    运行一个DFS文件系统的检查工具

fs                                                                        运行一个普通的文件系统用户客户端

balancer                                                             运行一个集群负载均衡工具

jobtracker                                                           运行MapReduce的jobtracker节点

pipes                                                                  运行一个pipes作业

tasktracker                                                         运行一个MapReduce的tasktracker节点

job                                                                      处理MapReduce作业

version                                                                打印版本

jar <jar>                                                              运行一个jar文件

distcp <srcurl> <desturl>                                   递归地复制文件或者目录

archive  -archiveName NAME <src>* <dest>    生成一个Hadoop档案

daemonlog                                                         获取或设置每个daemon的log级别

CLASSNAME                                                     运行名为CLASSNAME的类大多数命令会在使用w/o参数

时打出帮助信息。

运行单词统计示例程序的命令形式如下:

hadoop jar hadoop-*-examples.jar wordcount [-m <maps>] [-r reduces] input output

编译修改后的单词统计程序的命令形式如下:

javac -classpath hadoop-*-core.jar -d playground/classes playground/src/WordCount.java

jar -cvf playground/src/wordcount.jar -C playground/classes/

运行修改后的单词统计程序的命令形式如下:

hadoop jar playground/wordcount.jar org.apache.hadoop.examples.WordCount input output



代码清单 WordCount.java

package org.apache.hadoop.examples;
import java.io.IOException;
import java.util.StringTokenizer;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;
public class WordCount {
  public static class TokenizerMapper 
       extends Mapper<Object, Text, Text, IntWritable>{
    private final static IntWritable one = new IntWritable(1);
    private Text word = new Text();
    public void map(Object key, Text value, Context context
                    ) throws IOException, InterruptedException {
      StringTokenizer itr = new StringTokenizer(value.toString());   //(1)使用空格进行分词
      while (itr.hasMoreTokens()) {
        word.set(itr.nextToken());   //(2)把Token放入Text对象中
        context.write(word, one);
      }
    }
  }
  public static class IntSumReducer 
       extends Reducer<Text,IntWritable,Text,IntWritable> {
    private IntWritable result = new IntWritable();
    public void reduce(Text key, Iterable<IntWritable> values, 
                       Context context
                       ) throws IOException, InterruptedException {
      int sum = 0;
      for (IntWritable val : values) {
        sum += val.get();
      }
      result.set(sum);
      context.write(key, result);   //(3)输出每个Token的统计结果
    }
  }
  public static void main(String[] args) throws Exception {
    Configuration conf = new Configuration();
    String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
    if (otherArgs.length < 2) {
      System.err.println("Usage: wordcount <in> [<in>...] <out>");
      System.exit(2);
    }
    Job job = new Job(conf, "word count");
    job.setJarByClass(WordCount.class);
    job.setMapperClass(TokenizerMapper.class);
    job.setCombinerClass(IntSumReducer.class);
    job.setReducerClass(IntSumReducer.class);
    job.setOutputKeyClass(Text.class);
    job.setOutputValueClass(IntWritable.class);
    for (int i = 0; i < otherArgs.length - 1; ++i) {
      FileInputFormat.addInputPath(job, new Path(otherArgs[i]));
    }
    FileOutputFormat.setOutputPath(job,
      new Path(otherArgs[otherArgs.length - 1]));
    System.exit(job.waitForCompletion(true) ? 0 : 1);
  }
}

在(1)的位置上wordcount以默认配置使用了Java的StringTokenizer,这里仅基于空格来分词。为了在分词过程中忽略标准的标点符号,将它们加入到stringTokenizer的定界符列表中:

StringTokenizer itr = new StringTokenizer(value.toString(),” \t\n\r\f,.:;?![]’");

因为希望单词统计忽略大小写,把它们转换为Text对象前先将所有的单词都变成小写:

word.set(itr.nextToken().toLowerCase());

希望仅仅显示出现次数大于4次的单词:

if (sum > 4) context.write(key, result);



6、hadoop历史

创始人:Doug Cutting

2004年左右——Google发表了两篇论文来论述Google文件系统(GFS)和MapReduce框架。

2006年1月——雅虎聘用Doug,让他和一个专项团队一起改进Hadoop,并将其作为一个开源项目。

时间: 2024-10-23 10:03:45

[Hadoop in Action] 第1章 Hadoop简介的相关文章

[hadoop in Action] 第3章 Hadoop组件

管理HDFS中的文件 分析MapReduce框架中的组件 读写输入输出数据 1.HDFS文件操作 [命令行方式] Hadoop的文件命令采取的形式为: hadoop fs -cmd <args> 其中,cmd是具体的文件命令,而<args>是一组数目可变的参数. (1)添加文件和目录 HDFS有一个默认的工作目录/user/$USER,其中$USER是你的登录用户名.不过这个目录不会自动建立,让我们用mkdir命令创建它.Hadoop的mkdir命令会自动创建父目录,类似于UNIX

[Hadoop in Action] 第6章 编程实践

Hadoop程序开发的独门绝技 在本地,伪分布和全分布模式下调试程序 程序输出的完整性检查和回归测试 日志和监控 性能调优 1.开发MapReduce程序 [本地模式] 本地模式下的hadoop将所有的运行都放在一个单独的Java虚拟机中完成,并且使用的是本地文件系统(非HDFS).在本地模式中运行的程序将所有的日志和错误信息都输出到控制台,最后它会给出所处理数据的总量. 对程序进行正确性检查: 完整性检查 回归测试 考虑使用long而非int [伪分布模式] 本地模式不具备生产型hadoop集

[hadoop读书笔记] 第四章 Hadoop I/O操作

P92 压缩 P102 序列化 序列化:将结构化对象转为字节流便于在网上传输或写到磁盘进行永久性存储的过程 用于进程之间的通信或者数据的永久存储 反序列化:将字节流转为结构化对象的逆过程 Hadoop中的序列化:在Hadoop中,系统中多个节点上进程间的通信是通过远程过程传输RPC来实现的. RPC协议将消息序列化成二进制流后发送到远程节点,远程节点接着将二进制流反序列化成原始信息. Avro:一个独立于编程语言,并基于 IDL的序列化框架,非常适合用于Hadoop的大规模数据处理

[Hadoop in Action] 第2章 初识Hadoop

Hadoop的结构组成 安装Hadoop及其3种工作模式:单机.伪分布和全分布 用于监控Hadoop安装的Web工具 1.Hadoop的构造模块 (1)NameNode(名字节点) Hadoop在分布式计算和分布式存储中都采用了主/从结构.NameNode位于HDFS的主端,它指导从端的DataNode执行底层的I/O任务.NameNode是HDFS的书记员,它跟踪文件如何被分割成文件块,而这些块又被哪些节点存储,以及分布式文件系统的整体运行状态是否正常. 运行NameNode消耗大量的内存和I

Solr In Action 中文版 第一章 (二)

Solr到底是什么? 在本节中,我们通过从头设计一个搜索应用来介绍Solr的关键组件.这个过程将有助于你理解Solr的功能,以及设计这些功能的初衷.不过在我们开始介绍Solr的功能特性之前,还是要先澄清一下Solr并不具有的一些性质: 1)  Solr并不是一个像Google或是Bing那样的web搜索引擎 2)  Solr和网站优化中经常提到的搜索引擎SEO优化没有任何关系 好了,现在假设我们准备为潜在的购房客户设计一个不动产搜索的网络应用.该应用的核心用例场景是通过网页浏览器来搜索全美国范围

Solr In Action 中文版 第一章(一)

1.1我到底需要一个搜索引擎吗? 第一章           Solr 简介 本章速览: ·搜索引擎处理的数据特性 ·常见搜索引擎用例 ·Solr核心模块介绍 ·选择Solr的理由 ·功能概述 伴随着社交媒体.云计算.移动互联网和大数据等技术的高速发展,我们正迎来一个令人激动的计算时代.软件架构师们开始面对的主要挑战之一,便是如何处理全球巨大的用户基数所产生及使用的海量数据.此外,用户们开始期待在线软件应用永远都是稳定可用的,并且能够一直保持响应,这对应用就提出了更高的可扩展性和稳定性需求.为了

《Hadoop高级编程》之为Hadoop实现构建企业级安全解决方案

本章内容提要 ●    理解企业级应用的安全顾虑 ●    理解Hadoop尚未为企业级应用提供的安全机制 ●    考察用于构建企业级安全解决方案的方法 第10章讨论了Hadoop安全性以及Hadoop中用于提供安全控制的机制.当构建企业级安全解决方案(它可能会围绕着与Hadoop数据集交互的许多应用程序和企业级服务)时,保证Hadoop自身的安全仅仅是安全解决方案的一个方面.各种组织努力对数据采用一致的安全机制,而数据是从采用了不同安全策略的异构数据源中提取的.当这些组织从多个源获取数据,接

hadoop搭建杂记:Linux下hadoop的安装配置

VirtualBox搭建伪分布式模式:hadoop的下载与配置 VirtualBox搭建伪分布式模式:hadoop的下载与配置 由于个人机子略渣,无法部署XWindow环境,直接用的Shell来操作,想要用鼠标点击操作的出门转左不送- 1.hadoop的下载与解压 wget http://mirror.bit.edu.cn/apache/hadoop/common/stable2/hadoop-2.7.1.tar.gzmkdir /usr/hadooptar -xzvf hadoop-2.7.1

用java运行Hadoop程序报错:org.apache.hadoop.fs.LocalFileSystem cannot be cast to org.apache.

用java运行Hadoop例程报错:org.apache.hadoop.fs.LocalFileSystem cannot be cast to org.apache.所写代码如下: package com.pcitc.hadoop; import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.h