Hadoop简单入门和集群搭建

一、Hadoop是什么?

Hadoop是这样一个框架,它可以通过使用简单的编程模型来对跨计算机的集群中的大型数据集进行分布式的处理。它被设计成可以从单个服务器扩展到数千台机器,每个机器都提供本地的计算和存储。与依赖于硬件来保证高可用性不同,该库本身的设计目的是检测和处理应用程序层的故障,因此可以在众多计算机组成的集群的顶部提供一个高可用的服务,但是组成集群的每一个计算机都有可能出现故障。

上面是Hadoop官网对于Hadoop的一个介绍。简单来说,Hadoop就是一个大型数据集的分布式处理框架。

二、Hadoop的组成

Hadoop包含以下几个模块:

  • Hadoop Common: 支持其他Hadoop模块的公用程序。
  • Hadoop Distributed File System (HDFS™): 一个分布式文件系统,它提供对应用程序数据的高吞吐量访问。
  • Hadoop YARN:用于作业调度和集群资源管理的框架。
  • Hadoop MapReduce: 一个基于YARN的对大数据集进行并行处理的框架。

这个也是官网目前版本(3.0.0-alpha4)的介绍。其中YARN是Hadoop2新加的内容,用于作业的调度和集群资源的管理。其实HDFS、YARN、MapReduce这三个模块可以完全独立的,MapReduce也可以处理本地数据,不一定要是HDFS里面的数据,而且MapReduce也不一定非要依赖YARN,没有YARN也可以处理数据。只不过在正式环境中都会结合使用,因为这样更加方便和有利于管理,这也是框架本身给我们带来的好处。

三、 HDFS简介与原理

HDFS是一个分布式文件系统,被设计运行在商品硬件上。它与现有的分布式文件系统有许多相似之处,然而跟其他分布式文件系统的差异也是显著的。HDFS具有高度容错性,而且被设计用于低成本硬件上。HDFS提供对应用程序数据的高吞吐量访问,适用于具有大型数据集的应用程序。HDFS放宽了一些POSIX要求,以支持对文件系统数据的流式访问。HDFS最初是作为Apache Nutch web搜索引擎项目的基础设施构建的。

HDFS拥有一个主从结构。每一个HDFS集群都由一个NameNode和一系列的DataNode组成。NameNode就是master,它管理着文件系统的命名空间,并且控制着客户端对于文件系统中文件的访问。DataNode是真正存储文件的节点。一个文件会被切割成一个或者多个block块,这些block块会被存储在一系列的DataNode节点中。NameNode可以执行文件系统命名空间操作,比如打开、关闭、和重命名文件和目录。NameNode也决定了block块到对应的DataNode的一个映射。但是,对于文件系统客户端的读写请求的服务却是DataNode来提供的。DataNode还会通过NameNode的指令来执行块的创建、删除和复制。

以下是HDFS的结构图:

这里写图片描述

从图中可以看到,NameNode中会存储文件的元数据信息(即文件名称,复制的份数,存储在哪一台DataNode节点上等等)。DataNode则负责真正的文件数据的存储。客户端的文件会被分成块存储到一个或者多个的DataNode上,并且每一个块可能会在多个DataNode上存在备份(这个可以通过配置文件配置)。但是客户端对于文件系统文件的读写还是直接跟DataNode交互的,只要客户端通过NameNode找到了文件存储在哪些DataNode上。

值得一提的是:HDFS还有一个Secondary NameNode节点。那么这个节点是用来做什么的呢?

NameNode会将对文件系统的修改以日志的形式追加到一个静态的文件系统文件中。当NameNode启动的时候,它从fsimage镜像文件中读取HDFS的状态,然后会读取刚说的日志文件中的日志,把这些日志记录的操作应用到文件系统当中。再然后,将新的HDFS状态写入fsimage镜像,并使用一个空的可编辑文件来记录文件系统的新的操作日志。由于NameNode只在启动时合并fsimage和日志文件,所以在繁忙的集群中,编辑日志文件可能会变得非常大。这样产生的一个副作用就是NameNode启动会变得非常的慢。所以就产生了Secondary NameNode节点。

Secondary NameNode会定期的将simage和编辑日志文件合并,并将编辑日志大小保持在一个限制范围内。它通常需要跟NameNode运行在不同的机器上,因为它需要的内存是和NameNode一个级别的。

四、MapReduce简介与原理

上面介绍的HDFS解决了大量数据的一个存储的问题,而MapReduce则解决的是大量数据的计算问题。如果把PB级的数据文件使用一台计算机进行处理,这显然不是一件靠谱的事情。但是如果把PB级的数据文件拆分开来,拆分到足够小,放到多台计算机上,然后多台计算机并行的对本机的数据进行计算,然后再把计算结果汇总得到最终的计算结果,这就使PB级的数据的计算成为了可能。这也就是分治法的一个思想。

MapReduce顾名思义,分为两个阶段,一个阶段是Map,也就是计算阶段。另一个阶段是Reduce,也就是众多计算结果的一个汇总阶段。

如果MapReduce框架跟YARN框架结合使用的话,也可分为一个主节点ResourceManager和若干个从节点NodeManager。ResourceManager负责资源管理,而NodeManager负责真正的计算。这里指的注意的是,NodeManager应该跟它操作的数据很近,这样才能避免数据移动占用网络带宽,降低系统吞吐量。

五、YARN的简介与原理

前面介绍了YARN是一个集群作业调度与资源管理的框架。

YARN的一个基本思想是讲资源管理和作业调度/监视的功能分解为独立的守护进程。其思想是有一个全局的ResourceManager (RM) 和每一个应用的ApplicationMaster (AM)。一个应用可以是单个的job,也可以是一组有向无环图的job。

YARN框架由ResourceManager节点和NodeManager组成。ResourceManager具有着应用系统中资源分配的最终权威。NodeManager是每台机器的一个框架代理,它对containers负责,并且监控他们的资源使用情况(cpu、内存、磁盘、网络),同时上报给ResourceManager/Scheduler。

每一个应用的ApplicationMaster是一个框架特定的库,它的任务是向ResourceManager协调资源并与NodeManager一起执行监视任务。

一下是YARN框架的运行原理图。

这里写图片描述

从上图可以看出,客户端提交了一个任务,ResourceManager首先会在一个NodeManager为这个任务生成一个ApplicationMaster作为任务的管理者,ApplicationMaster向ResourceManager申请所需要的资源,ResourceManager会告诉NodeManager分配资源,NodeManager以container的形式分配资源,来供任务进行计算。这样可以实现资源隔离。NodeManager在不断的向ResourceManager汇报资源使用情况。这就是一个任务在YARN上运行的基本流程。

六、 Hadoop集群的搭建

主要是HDFS集群和YARN集群的搭建。

环境:macpro + virtualbox + 4台centos7虚拟机

集群主从信息:

地址节点
192.168.56.100master,NameNode,ResourceManager
192.168.56.101slave1, DataNode, NodeManager
192.168.56.102slave2, DataNode, NodeManager
192.168.56.103slave3, DataNode, NodeManager

1. 安装虚拟机

这里虚拟机请google自行安装,但是有一点需要注意,网络连接方式需要选择host-only。

2. 设置固定ip

进入装好的虚拟机,用下面的命令编辑设置ip。

vim /etc/sysconfig/network-scripts/ifcfg-enp0s3
TYPE=Ethernet
IPADDR=192.168.56.100
NETMASK=255.255.255.0

设置网关:

vim /etc/sysconfig/network
NETWORKING=yes
GATEWAY=192.168.56.1

设置主机名称:

set hostname master

重启网络服务:

systemctl restart network

设置本地域名hosts:

vim /etc/hosts
192.168.56.100 master
192.168.56.101 slave1
192.168.56.102 slave2
192.168.56.103 slave3

验证是否配置成功,ping本机:

ping 192.168.56.1

如果能ping通,则表示配置成功。ping通过后,就可以通过ssh客户端从本机连到虚拟机。

3. 安装虚拟机java环境

将事先下载好的jdk的rpm包上传到虚拟机,进行java环境的安装。

安装虚拟机的jdk:

rpm -ivh jdk-8u91-linux0x64.rpm

使用 java -version验证是否安装成功。

4. 虚拟机安装Hadoop

将事先下载好的Hadoop压缩包上传到虚拟机的/usr/local/目录下。进行解压:

tar -xvf hadoop-2.7.3.tar.gz

重命名

mv hadoop-2.7.3 hadoop

进入hadoop/ect/hadoop,编辑hadoop-env.sh:

vim hadoop-env.sh

配置JAVA_HOME:

export JAVA_HOME=/usr/java/jdk1.8.0_91

这是hadoop环境的最低配置,其他配置请参考http://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/ClusterSetup.html

编辑slaves,将slave节点配置进去:

vim slaves
slave1
slave2
slave3

编辑core-site.xml文件,配置hdfs的主节点信息:

    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://master:9000</value>
    </property>

配置本地数据存储相关的路径:默认路径在/tmp/目录下,机器重启存入的数据会被删除。

    <property>
        <name>hadoop.tmp.dir</name>
        <value>/var/hadoop</value>
    </property>

配置Hadoop的环境变量:

vim /etc/profile
export PATH=$PATH:/usr/local/hadoop/bin:/usr/local/hadoop/sbin

重新加载profile文件。

source /etc/profile

5. 复制slave的虚拟机

将原来的master虚拟机断电,完全复制三份,命名为slave1,slave2,slave3. 并按照前面的方法设置主机名为slave1,slave2,slave3,设置固定ip地址为192.168.56.101~103.

6. 配置四台虚拟机之间的免密登录

介绍下master到master以及slave1,2,3的免密登录。其他的跟这个类似。

在master机器上生成密钥,进入~/.ssh/目录,运行以下命令:

ssh-keygen -t rsa -P ""

将生成的密钥拷贝到自己本机以及其他的机器,完成免密登录。

ssh-copy-id master
ssh-copy-id slave1
ssh-copy-id slave2
ssh-copy-id slave3

验证下,从master上ssh到其他三台机器,看看是否需要输入密码,如果不需要输入密码,则表示配置免密成功。

7. 配置hdfs集群

编辑hdfs-site.xml文件,
文件在hdfs里面复制三份:

<property>
    <name>dfs.replication</name>
    <value>3</value>
</property>

关闭权限校验,本地测试用:

<property>
    <name>dfs.permissions.enabled</name>
    <value>false</value>
</property>

没10秒进行心跳检测:

<property>
    <name>dfs.namenode.heartbeat.recheck-interval</name>
    <value>10000</value>
</property>

保存退出。简单的hdfs集群就配置好了。

输入命令启动:

start-dfs.sh

等待启动完成。
在四台机器分别输入jps命令查看运行的java进程,如果master上运行了NameNode和SecondaryNameNode,slave上运行了DataNode进程,则说明hdfs集群启动成功了。

8. 本地代码操作hdfs集群文件

Maven需要的引入的jar

    <dependency>
      <groupId>org.apache.hadoop</groupId>
      <artifactId>hadoop-common</artifactId>
      <version>2.7.3</version>
    </dependency>
    <dependency>
      <groupId>org.apache.hadoop</groupId>
      <artifactId>hadoop-hdfs</artifactId>
      <version>2.7.3</version>
    </dependency>
public static void main(String[] args) throws Exception {


        Configuration configuration = new Configuration();
        configuration.set("fs.defaultFS", "hdfs://192.168.56.100:9000");
        FileSystem fileSystem = FileSystem.get(configuration);

        // 创建目录
        boolean success = fileSystem.mkdirs(new Path("/zhouwen"));
        System.out.println(success);

        //判断文件是否存在
        success = fileSystem.exists(new Path("/hello.txt"));
        System.out.println(success);

        // 删除目录
        success = fileSystem.delete(new Path("/zhouwen"), true);
        System.out.println(success);

        // 遍历根目录
        FileStatus[] statuses = fileSystem.listStatus(new Path("/"));
        for (FileStatus status : statuses) {
            System.out.println(status.getPath());
            System.out.println(status.getPermission());
            System.out.println(status.getReplication());
        }
    }

可以在master运行hdfs命令来操作。具体的可以参考:http://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/FileSystemShell.html

9. YARN集群配置

配置yarn-site.xml。

<property>
    <name>yarn.resourcemanager.hostname</name>
    <value>master</value>
</property>


<property>  
    <name>yarn.nodemanager.aux-services</name>  
    <value>mapreduce_shuffle</value>  
</property>  

<property>
    <name>yarn.nodemanager.auxservices.mapreduce.shuffle.class</name>
    <value>org.apache.hadoop.mapred.ShuffleHandler</value>
</property>

如果要使MapReduce能在YARN上运行,还需要配置mapred-site.xml:

<property>
    <name>mapreduce.framework.name</name>
    <value>yarn</value>
</property>

配置完成之后,就可以启动YARN。运行下面的命令:

start-yarn.sh 

如果jps能在master上看到ResourceManager,在slave上看到NodeManager,则说明YARN启动成功了。

10. 编写MapReduce代码在YARN上运行

依赖jar:

    <dependency>
      <groupId>org.apache.hadoop</groupId>
      <artifactId>hadoop-common</artifactId>
      <version>2.7.3</version>
    </dependency>
    <dependency>
      <groupId>org.apache.hadoop</groupId>
      <artifactId>hadoop-hdfs</artifactId>
      <version>2.7.3</version>
    </dependency>
    <dependency>
      <groupId>org.apache.hadoop</groupId>
      <artifactId>hadoop-client</artifactId>
      <version>2.7.3</version>
    </dependency>

配置log4j.properties,方便查看运行日志,放到src/main/resources目录下:

log4j.rootCategory=INFO, stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender   
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout   
log4j.appender.stdout.layout.ConversionPattern=[QC] %p [%t] %C.%M(%L) | %m%n

统计单词个数的MapReduce程序:

public class WordMapper extends Mapper<LongWritable, Text, Text, IntWritable> {

    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        final IntWritable ONE = new IntWritable(1);

        String s = value.toString();
        String[] words = s.split(" ");
        for (String word : words) {
            context.write(new Text(word), ONE);
        }
    }


}
public class WordReducer extends Reducer<Text, IntWritable, Text, LongWritable> {

    @Override
    protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
        long count = 0;
        for (IntWritable v : values) {
            count += v.get();
        }

        context.write(key, new LongWritable(count));
    }
}
public static void main(String[] args) throws Exception {
        Configuration conf = new Configuration();

        conf.set("fs.defaultFS", "hdfs://192.168.56.100:9000/");

        conf.set("mapreduce.job.jar", "/Users/zhouwen/IdeaProjects/hadoop/target/hadoop.jar");
        conf.set("mapreduce.framework.name", "yarn");
        conf.set("yarn.resourcemanager.hostname", "master");
        conf.set("mapreduce.app-submission.cross-platform", "true");

        Job job = Job.getInstance(conf);

        job.setMapperClass(WordMapper.class);
        job.setReducerClass(WordReducer.class);

        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);

        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(LongWritable.class);

        FileInputFormat.setInputPaths(job, "/input/");
        FileOutputFormat.setOutputPath(job, new Path("/output4/"));

        job.waitForCompletion(true);
    }

上面的代码意思是从hdfs的/input/目录读取文件,进行单词统计,并把结果输出到hdfs的/output4/目录下。
注意既然是在YARN上运行,那么需要把运行的代码传到服务器上,

conf.set("mapreduce.job.jar", "/Users/zhouwen/IdeaProjects/hadoop/target/hadoop.jar");

也就是这行代码。把代码打包成jar的形式,传到服务端去执行。后面的路径也就是打的jar包的路径。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值