hadoop集群搭建与测试编码

原创 2015年12月20日 14:46:15

说明

本文介绍hadoop小集群的搭建.

准备

十台装有linux的计算机.
这些计算机都装有jdk, 并且准确配置jdk.
这些计算机都装了ssh, 并且都能实现相互之间无密码访问.

配置

记录各台计算机的ip, 并将其中的一台作为master机, 其他计算机一次标号为slave1, slave2, slave3…slave9.
将ip对应标号的信息添加到/etc/hosts文件中, 格式为:

ip1     master
ip2     slave1
ip3     slave2
......
ip10    slave9

同时分别修改各台计算机对应的hostname, 使其对应hosts文件中的标号.

接着是配置hadoop了, hadoop的配置文件分为四个文件, 分别是core-site.xml, hdfs-site.xml, mapred-site.xml, yarn-site.xml.
这三个文件分别对应核心配置, hdfs配置, mapreduce配置和yarn配置.

接着介绍一下需要配置的属性:

1. fs.default.name

hdfs默认的服务器地址和端口.
位置在core-site.xml.
代码:

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

2. hadoop.tmp.dir

hadoop的临时目录存放位置. 这个属性必须设置, 不然hadoop会在/tmp/目录下创建一个目录作为临时目录, 但是当系统重启之后, /tmp/目录就会被清除, 从而启动hadoop时需要重新格式化文件系统.
同时, 要赋予启动hadoop的用户对设置目录的读写权限.
位置在core-site.xml.
代码:

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

3. dfs.replication

文件块存储的份数, 冗余存储, 提高系统的稳定性.
位置在hdfs-site.xml
代码:

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

4. dfs.datanode.balance.bandwidthPerSec

平衡器同步时使用的带宽, 这个值设置的高了会占用带宽影响运行效率.
位置在hdfs-site.xml
代码:

<property>
    <name>dfs.datanode.balance.bandwidthPerSec</name>
   <value>10485760</value>
</property>

5. mapreduce.framework.name

设置哪种mapreduce框架, 分为local, classic和yarn.
位置在mapred-site.xml
代码:

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

6. mapreduce.jobtracker.address

jobtracker的位置, 一般设置master机的位置. ip加端口号. 不需要协议
位置在mapred-site.xml
代码:

<property>
   <name>mapreduce.jobtracker.address</name>
   <value>master:9001</value>
</property>

7. mapreduce.job.maps

制定mapper的数量
位置在mapred-site.xml
代码:

<property>
   <name>mapreduce.job.maps</name>
   <value>2</value>
</property>

8. mapreduce.job.reduces

制定reducer的数量
位置在mapred-site.xml
代码:

<property>
   <name>mapreduce.job.reduces</name>
   <value>1</value>
</property>

9. mapreduce.tasktracker.map.tasks.maximum

制定mapper的最大数量
位置在mapred-site.xml
代码:

<property>
   <name>mapreduce.tasktracker.map.tasks.maximum</name>
   <value>4</value>
</property>

10. mapreduce.tasktracker.reduce.tasks.maximum

制定reducer的最大数量
位置在mapred-site.xml
代码:

<property>
   <name>mapreduce.tasktracker.reduce.tasks.maximum</name>
   <value>2</value>
</property>

11. mapreduce.reduce.shuffle.memory.limit.percent

设置shuffle阶段内存的大小. shuffle有两种方式, 一种是在磁盘上的, 另一种是在内从中进行.当单个文件的大小大于设置的阖值时, 将在磁盘进行操作.
如果小于, 就在内存中操作. 当单个文件小于这个阖值, 而文件数又很多时, 会造成内存不够用的情况, 从而导致程序崩溃现象. 解决方案, 将这个设置设置的很小,
始终在磁盘上进行.
位置在mapred-site.xml
代码:

<property>
    <name>mapreduce.reduce.shuffle.memory.limit.percent</name>
    <value>0.001</value>
</property>

12. mapreduce.output.fileoutputformat.compress

设置输出文件是否进行压缩. 文件压缩可以减小磁盘的使用率, 当作为中间产物进行传输时, 也节省了带宽.
hadopp支持集中压缩方式, 主要是Bzip2和Gzip. Bzip2压缩文件可以被分块, 即可以由多个map进行操作, 而且这种算法压缩效率较高, 但是这种算法压缩速度较慢.
对于Gzip, 这种算法在压缩速度和压缩效率上都不错, 但是这种压缩算法压缩后的文件不支持分块, 即只能由一个map进行操作.这种方案严重影响实际效率.
对于reduce个数较少可以将中间产物设置成Gzip, 而将最终结果设置成BZip2. 即提升了传输效率, 又有利于二次利用.
位置在mapred-site.xml
代码:

<property>
    <name>mapreduce.output.fileoutputformat.compress</name>
    <value>true</value>
</property>

13. mapreduce.map.output.compress

设置map之后的产物是否进行压缩
位置在mapred-site.xml
代码:

<property>
    <name>mapreduce.map.output.compress</name>
    <value>true</value>
</property>

14. mapreduce.output.fileoutputformat.compress.codec

设置输出文件的压缩算法
位置在mapred-site.xml
代码:

<property>
    <name>mapreduce.output.fileoutputformat.compress.codec</name>
    <value>org.apache.hadoop.io.compress.BZip2Codec</value>
</property>

15. mapreduce.map.output.compress.codec

设置map阶段结果的压缩算法
位置在mapred-site.xml
代码:

<property>
    <name>mapreduce.map.output.compress.codec</name>
    <value>org.apache.hadoop.io.compress.GzipCodec</value>
</property>

将配置好的hadoop目录打包, 分别发送到各个奴隶机上, 解压,并防止在同一个目录, 同时设置, HADOOP_HOME.

测试

在master机上执行下面命令用于格式化文件系统:

hadoop namenode -format

格式化, 在master机的/opt/hadoop/目录下,执行下面的命令, 启动hadoop集群:

sbin/start-all.sh

可以使用jps命令检查一下是否正常运行, 在master机下执行jps命令, 显示的结果如下:

XXXXX NameNode
XXXXX Jps   
XXXXX SecondaryNameNode
XXXXX ResourceManager

在slave机上执行jps, 显示结果如下:

XXXXX NodeManager
XXXXX Jps
XXXXX DataNode

接着是创建用户目录:

hadoop fs -mkdir /user
hadoop fs -mkdir /user/phantom9999
hadoop fs -mkdir /user/phantom9999/logs
hadoop fs -mkdir /user/phantom9999/logs/input/
hadoop fs -mkdir /user/phantom9999/logs/output/

接着是把日志文件上传到hadoop集群中, 使用下面的命令:

hadoop fs -put ./nginx.log.bz2 /user/phantom9999/logs/input/

接着是运行程序了, 将写好的程序上传到集群上, 使用下面的命令进行运行:

hadoop jar countIP.jar input countIP

编码

下面讲述一下上面运行的代码.
这个代码统计了一下nginx日志文件中, 各个IP出现的次数, 并根据出现的次数进行排序.
其中排序操作是在map阶段, 将ip出现的次数作为键名, 将ip作为键值. 在reduce阶段,
交换两者的位置.

具体代码如下:

package com.company;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
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.jobcontrol.JobControl;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Main {

    public static class DoMapper extends Mapper<Object, Text, Text, IntWritable> {

        public static int ipLength = "255.255.255.255,".length();

        public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
            String line = value.toString();
            String[] fields = line.split("\t");
            context.write(new Text(fields[1]), new IntWritable(1));
        }
    }

    public static class DoReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
        public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
            int sum = 0;
            for (IntWritable item: values) {
                sum += item.get();
            }

            context.write(key, new IntWritable(sum));
        }
    }

    public static class SortMapper extends Mapper<Object, Text, IntWritable, Text> {

        public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
            String line = value.toString();
            String[] fields = line.split("\t");
            if (fields.length == 2) {
                context.write(new IntWritable(Integer.parseInt(fields[1])), new Text(fields[0]));
            }

        }
    }

    public static class SortReducer extends Reducer<IntWritable, Text, Text, IntWritable> {

        public void reduce(IntWritable key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
            for (Text item: values) {
                context.write(item, key);
            }
        }
    }




    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
        Configuration conf = new Configuration();
        String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
        if (otherArgs.length < 2) {
            System.out.println("参数不够");
            System.exit(0);
        }

        SimpleDateFormat df = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
        String tmpDirPath = df.format(new Date());
        //tmpDirPath = "2015_09_20_21_31_46";
        Path inputPath = new Path("/user/phantom/logs/" + otherArgs[0]);
        Path outputPath = new Path("/user/phantom/logs/output/" + otherArgs[1]);
        Path middlePath = new Path("/user/phantom/logs/output/" + tmpDirPath);



        Job job = Job.getInstance(conf, "log");
        job.setJarByClass(Main.class);
        job.setMapperClass(DoMapper.class);
        job.setCombinerClass(DoReducer.class);
        job.setReducerClass(DoReducer.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);
        FileInputFormat.addInputPath(job, inputPath);
        FileOutputFormat.setOutputPath(job, middlePath);
        job.waitForCompletion(true);

        Configuration conf2 = new Configuration();
        Job sortJob = Job.getInstance(conf2, "sort");
        sortJob.setJarByClass(Main.class);
        sortJob.setMapperClass(SortMapper.class);
        sortJob.setReducerClass(SortReducer.class);


        sortJob.setMapOutputKeyClass(IntWritable.class);
        sortJob.setMapOutputValueClass(Text.class);
        sortJob.setOutputKeyClass(Text.class);
        sortJob.setOutputValueClass(IntWritable.class);

        FileInputFormat.addInputPath(sortJob, middlePath);
        FileOutputFormat.setOutputPath(sortJob, outputPath);


        boolean result = sortJob.waitForCompletion(true);

        FileSystem fs = FileSystem.get(conf2);
        fs.deleteOnExit(middlePath);

        System.exit(result ? 0 : 1);
    }
}

Apache配置——支持JBoss集群

一、为Apache Web服务器安装mod_cluster插件 1安装文件 JBoss官方提供了mod_cluster的下载地址: http://mod-cluster.jboss.or...
  • zollty
  • zollty
  • 2016年12月31日 21:58
  • 589

logstash 配置使用

logstash 配置使用
  • wyqlxy
  • wyqlxy
  • 2016年09月21日 10:10
  • 9384

MySQL集群搭建步骤详解

本文将搭建一个最简化的MySQL Cluster系统,配置方法中的所有命令都是以root账户运行。这个MySQL Cluster包含一个管理结点、两个数据结点、两个SQL结点,这五个结点会分别安装在五...
  • lifuxiangcaohui
  • lifuxiangcaohui
  • 2015年05月05日 14:12
  • 1124

windows+mysql集群搭建-三分钟搞定集群

在上一篇博客(mysql集群搭建基础篇)里介绍了mysql集群的基本知识,这篇博客讲解如何在windows环境下搭建mysql集群,这段时间在我们架构师的带领下搭建了mysql集群,让我受益很多,下面...
  • u013086062
  • u013086062
  • 2016年03月11日 16:14
  • 9975

Solr集群搭建指南(上)

由于这次在处理umcsyslog的时候用到solr, 而集团目前还没有solr线上和线下集群,于时自己动搭建了一套solr集群; 在搭建的时候查看了网上不少资料,也碰到过很多问题,最终经过一路的波折...
  • tiandesheng111
  • tiandesheng111
  • 2016年06月13日 17:45
  • 2995

redis为什么要集群

我的看法是:Redis是一个内存数据库,也就是说存储数据的容量不能超过主机内存大小。普通主机服务器的内存一般几十G,但是我们需要存储大容量的数据(比如上百G的数据)怎么办?  在3.0版本之前,...
  • shenjianxz
  • shenjianxz
  • 2017年03月03日 00:02
  • 2662

zookeeper单机伪集群配置

1.配置 .zookeeper下载地址:http://apache.mirrors.lucidnetworks.net/zookeeper/ 可以选择需要的版本,我下载的是zookeeper-...
  • tanyujing
  • tanyujing
  • 2013年01月15日 10:48
  • 17870

架构师之路--服务器集群搭建、管理、与快速部署

今天的目标是有4台Linux的服务器架设一个小规模的集群 1、我们可以随时的扩展我们的服务器集群,就像牲口干活一样,一匹马拉不动,可以由多匹马来拉 2、在Linux中有一个hosts 文...
  • caopeng26
  • caopeng26
  • 2016年08月11日 21:33
  • 6950

数据库集群浅谈(一)

现在,随着上网人数的激增,一些大型的网站开始使用数据库集群来提高数据库的可靠性和数据库的性能。那么在介绍数据库集群之前首先需要弄清楚几个问题。 1.为什么要用数据库集群         (1)通过使用...
  • zhangzijiejiayou
  • zhangzijiejiayou
  • 2016年02月16日 15:25
  • 5092

java集群技术

序言 越来越多的关键应用运行在J2EE(Java 2, Enterprise Edition)中,这些诸如银行系统和账单处理系统需要高的可用性(High Availability, HA),同时...
  • cdh1213
  • cdh1213
  • 2014年03月18日 09:44
  • 24613
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:hadoop集群搭建与测试编码
举报原因:
原因补充:

(最多只允许输入30个字)