Hadoop安装与Benchmarking

2 Hadoop与基准测试

2.1 创建Hadoop用户

  • 增加一个Hadoop用户
      su              # 上述提到的以 root 用户登录
      useradd -m hadoop -s /bin/bash   # 创建新用户hadoop
      passwd hadoop

为 hadoop 用户增加管理员权限,方便部署

      visudo

在这里插入图片描述

2.2 安装与配置SSH

集群、单节点模式都需要用到 SSH 登陆(类似于远程登陆,你可以登录某台 Linux 主机,并且在上面运行命令),一般情况下,CentOS 默认已安装了 SSH client、SSH server,打开终端执行如下命令进行检验

    rpm -qa | grep ssh

在这里插入图片描述

执行如下命令测试一下 SSH 是否可用

    ssh localhost

此时会有如下提示(SSH首次登陆提示),输入 yes 。然后按提示输入密码 hadoop,这样就登陆到本机了

在这里插入图片描述

但这样登陆是需要每次输入密码的,我们需要配置成SSH无密码登陆比较方便。利用 ssh-keygen 生成密钥,并将密钥加入到授权中

    exit                           # 退出刚才的 ssh localhost
    cd ~/.ssh/         # 若没有该目录,请先执行一次ssh localhost
    ssh-keygen -t rsa              # 会有提示,都按回车就可以
    cat id_rsa.pub >> authorized_keys  # 加入授权
    chmod 600 ./authorized_keys    # 修改文件权限

此时再用 ssh localhost 命令,无需输入密码就可以直接登陆了,如下图所示

在这里插入图片描述

2.3 安装Java环境

  • Java版本选择
    Java 环境可选择 Oracle 的 JDK,或是 OpenJDK,现在一般 Linux 系统默认安装的基本是 OpenJDK,如 CentOS 6.4 就默认安装了 OpenJDK 1.7。按 http://wiki.apache.org/hadoop/HadoopJavaVersions 中说的,Hadoop 在 OpenJDK 1.7 下运行是Good。
    在这里插入图片描述

    为了开发方便,我们还是需要通过 yum 进行安装 JDK,安装过程中会让输入 [y/N],输入 y 即可

      sudo yum install java-1.7.0-openjdk java-1.7.0-openjdk-devel

接着需要配置一下 JAVA_HOME 环境变量,为方便,我们在 ~/.bashrc 中进行设置

      vim ~/.bashrc

在文件最后面添加如下单独一行(指向 JDK 的安装位置),并保存

      export JAVA_HOME=/usr/lib/jvm/java-1.7.0-openjdk

接着还需要让该环境变量生效,执行如下代码

      source ~/.bashrc    # 使变量设置生效

由于CentOS7默认安装Java1.8,我们需要将1.7设置为选中的Java版本

      alternatives --config java

在这里插入图片描述

设置好后我们来检验一下是否设置正确

      echo $JAVA_HOME     # 检验变量值
      java -version
      $JAVA_HOME/bin/java -version  # 与直接执行 java -version 一样

在这里插入图片描述

这样,Hadoop 所需的 Java 运行环境就安装好了。

2.4 安装Hadoop

  • Hadoop 2 可以通过 http://mirror.bit.edu.cn/apache/hadoop/common/ 或者 http://mirrors.cnnic.cn/apache/hadoop/common/ 下载,选择版本2.10.2
  • 将 Hadoop 安装至 /usr/local/ 中
      sudo tar -zxf ~/下载/hadoop-2.10.2.tar.gz -C /usr/local    # 解压到/usr/local中
      cd /usr/local/
      sudo mv ./hadoop-2.10.2/ ./hadoop            # 将文件夹名改为hadoop
      sudo chown -R hadoop:hadoop ./hadoop        # 修改文件权限

Hadoop 解压后即可使用。输入如下命令来检查 Hadoop 是否可用,成功则会显示 Hadoop 版本信息

      cd /usr/local/hadoop
      ./bin/hadoop version

2.5 Hadoop单机配置

Hadoop 默认模式为非分布式模式,无需进行其他配置即可运行。非分布式即单 Java 进程,方便进行调试。

们选择运行 grep 例子,我们将 input 文件夹中的所有文件作为输入,筛选当中符合正则表达式 dfs[a-z.]+ 的单词并统计出现的次数,最后输出结果到 output 文件夹中。

    cd /usr/local/hadoop
    mkdir ./input
    cp ./etc/hadoop/*.xml ./input   # 将配置文件作为输入文件
    ./bin/hadoop jar ./share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar grep ./input ./output 'dfs[a-z.]+'
    cat ./output/*          # 查看运行结果

执行成功的话会输出很多作业的相关信息,最后的输出信息如下图所示。作业的结果会输出在指定的 output 文件夹中,通过命令 cat ./output/* 查看结果,符合正则的单词 dfsadmin 出现了1次

在这里插入图片描述

2.6 Hadoop伪分布式配置

Hadoop 可以在单节点上以伪分布式的方式运行,Hadoop 进程以分离的 Java 进程来运行,节点既作为 NameNode 也作为 DataNode,同时,读取的是 HDFS 中的文件。

在设置 Hadoop 伪分布式配置前,我们还需要设置 HADOOP 环境变量,执行如下命令在 ~/.bashrc 中设置:

    gedit ~/.bashrc

在文件最后面增加如下内容

    # Hadoop Environment Variables
    export HADOOP_HOME=/usr/local/hadoop
    export HADOOP_INSTALL=$HADOOP_HOME
    export HADOOP_MAPRED_HOME=$HADOOP_HOME
    export HADOOP_COMMON_HOME=$HADOOP_HOME
    export HADOOP_HDFS_HOME=$HADOOP_HOME
    export YARN_HOME=$HADOOP_HOME
    export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_HOME/lib/native
    export PATH=$PATH:$HADOOP_HOME/sbin:$HADOOP_HOME/bin

保存后,不要忘记执行如下命令使配置生效:

    source ~/.bashrc

这些变量在启动 Hadoop 进程时需要用到,不设置的话可能会报错(这些变量也可以通过修改 ./etc/hadoop/hadoop-env.sh 实现)。

Hadoop 的配置文件位于 /usr/local/hadoop/etc/hadoop/ 中,伪分布式需要修改2个配置文件 core-site.xml 和 hdfs-site.xml 。Hadoop的配置文件是 xml 格式,每个配置以声明 property 的 name 和 value 的方式来实现。

    gedit ./etc/hadoop/core-site.xml

在这里插入图片描述

    gedit ./etc/hadoop/hdfs-site.xml

在这里插入图片描述

配置完成后,执行 NameNode 的格式化:

    ./bin/hdfs namenode -format

在这里插入图片描述

接着开启 NaneNode 和 DataNode 守护进程

    ./sbin/start-dfs.sh

    jps

在这里插入图片描述

启动hadoop集群后,查看进程发现名称节点的NameNode进程启动了,但是数据节点的DataNode进程没有启动的解决方法:

原因为多次格式化namenode导致的namenode与datanode之间的不一致导致。

  • 停止集群

    stop-all.sh

  • 删除datanode存放的路径的数据 可以在hdfs-site.xml中查看存放的路径,如下
    在这里插入图片描述

    # rm -rf /usr/local/hadoop/tmp/data #三个节点都操作

  • 重新格式化
    ./bin/hdfs namenode -format

  • 启动集群
    ./sbin/start-dfs.sh

  • 查看进程
    jps
    在这里插入图片描述

成功启动后,可以访问 Web 界面 http://localhost:50070 查看 NameNode 和 Datanode 信息,还可以在线查看 HDFS 中的文件

在这里插入图片描述

2.7 Hadoop性能测试

2.7.1 TestDFSIO(Distributed i/o benchmark)

分布式的I/O基准。

#2.7.1.1 向HDFS上传10个100MB的文件

在/usr/local/hadoop/share/hadoop/mapreduce路径下

    hadoop jar hadoop-mapreduce-client-jobclient-2.10.2-tests.jar TestDFSIO -write -nrFiles 10 -fileSize 100

测试结果

    22/10/09 11:19:12 INFO fs.TestDFSIO: ----- TestDFSIO ----- : write
    22/10/09 11:19:12 INFO fs.TestDFSIO:             Date & time: Sun Oct 09 11:19:12 CST 2022
    22/10/09 11:19:12 INFO fs.TestDFSIO:         Number of files: 10
    22/10/09 11:19:12 INFO fs.TestDFSIO:  Total MBytes processed: 1000
    22/10/09 11:19:12 INFO fs.TestDFSIO:       Throughput mb/sec: 158.15	#吞吐量
    22/10/09 11:19:12 INFO fs.TestDFSIO:  Average IO rate mb/sec: 165.33	#平均IO速率
    22/10/09 11:19:12 INFO fs.TestDFSIO:   IO rate std deviation: 38.93	 	#IO率STD偏差
    22/10/09 11:19:12 INFO fs.TestDFSIO:      Test exec time sec: 8.62		#测试执行时间秒
    22/10/09 11:19:12 INFO fs.TestDFSIO: 

在这里插入图片描述

2.7.1.2 向HDFS上传10个100MB的文件

    hadoop jar hadoop-mapreduce-client-jobclient-2.10.2-tests.jar TestDFSIO -read -nrFiles 10 -fileSize 100

测试结果:

    22/10/12 20:08:49 INFO fs.TestDFSIO: ----- TestDFSIO ----- : read
    22/10/12 20:08:49 INFO fs.TestDFSIO:             Date & time: Wed Oct 12 20:08:49 CST 2022
    22/10/12 20:08:49 INFO fs.TestDFSIO:         Number of files: 10
    22/10/12 20:08:49 INFO fs.TestDFSIO:  Total MBytes processed: 1000
    22/10/12 20:08:49 INFO fs.TestDFSIO:       Throughput mb/sec: 132.96
    22/10/12 20:08:49 INFO fs.TestDFSIO:  Average IO rate mb/sec: 157.49
    22/10/12 20:08:49 INFO fs.TestDFSIO:   IO rate std deviation: 65.87
    22/10/12 20:08:49 INFO fs.TestDFSIO:      Test exec time sec: 33.93
    22/10/12 20:08:49 INFO fs.TestDFSIO: 
2.7.1.3 测试结束之后删除测试数据
    hadoop jar hadoop-mapreduce-client-jobclient-2.10.2-tests.jar TestDFSIO -clean

2.7.2 nnberch

nnbench用于测试NameNode的负载,它会生成很多与HDFS相关的请求,给NameNode施加较大的压力。这个测试能在HDFS上模拟创建、读取、重命名和删除文件等操作。

使用12个mapper和6个reducer创建1000个文件

    hadoop jar hadoop-mapreduce-client-jobclient-2.10.2-tests.jar nnbench -operation create_write -maps 12 -reduces 6 -blockSize 1 -bytesToWrite 0 -numberOFiles 10 -replicationFactorPerFile 3 -readFileAfterOpen true -baseDir /benchmarks/NNBench-'hostname -s'

测试结果:

22/10/12 20:15:45 INFO hdfs.NNBench: -------------- NNBench -------------- : 
    22/10/12 20:15:45 INFO hdfs.NNBench:                                Version: NameNode Benchmark 0.4
    22/10/12 20:15:45 INFO hdfs.NNBench:                            Date & time: 2022-10-12 20:15:45,593
    22/10/12 20:15:45 INFO hdfs.NNBench: 
    22/10/12 20:15:45 INFO hdfs.NNBench:                         Test Operation: create_write
    22/10/12 20:15:45 INFO hdfs.NNBench:                             Start time: 2022-10-12 20:15:06,520
    22/10/12 20:15:45 INFO hdfs.NNBench:                            Maps to run: 12
    22/10/12 20:15:45 INFO hdfs.NNBench:                         Reduces to run: 6
    22/10/12 20:15:45 INFO hdfs.NNBench:                     Block Size (bytes): 1
    22/10/12 20:15:45 INFO hdfs.NNBench:                         Bytes to write: 0
    22/10/12 20:15:45 INFO hdfs.NNBench:                     Bytes per checksum: 1
    22/10/12 20:15:45 INFO hdfs.NNBench:                        Number of files: 1
    22/10/12 20:15:45 INFO hdfs.NNBench:                     Replication factor: 3
    22/10/12 20:15:45 INFO hdfs.NNBench:             Successful file operations: 0
    22/10/12 20:15:45 INFO hdfs.NNBench: 
    22/10/12 20:15:45 INFO hdfs.NNBench:         # maps that missed the barrier: 0
    22/10/12 20:15:45 INFO hdfs.NNBench:                           # exceptions: 12000
    22/10/12 20:15:45 INFO hdfs.NNBench: 
    22/10/12 20:15:45 INFO hdfs.NNBench:                TPS: Create/Write/Close: 0
    22/10/12 20:15:45 INFO hdfs.NNBench: Avg exec time (ms): Create/Write/Close: Infinity
    22/10/12 20:15:45 INFO hdfs.NNBench:             Avg Lat (ms): Create/Write: NaN
    22/10/12 20:15:45 INFO hdfs.NNBench:                    Avg Lat (ms): Close: NaN
    22/10/12 20:15:45 INFO hdfs.NNBench: 
    22/10/12 20:15:45 INFO hdfs.NNBench:                  RAW DATA: AL Total #1: 0
    22/10/12 20:15:45 INFO hdfs.NNBench:                  RAW DATA: AL Total #2: 0
    22/10/12 20:15:45 INFO hdfs.NNBench:               RAW DATA: TPS Total (ms): 81616
    22/10/12 20:15:45 INFO hdfs.NNBench:        RAW DATA: Longest Map Time (ms): 24683.0
    22/10/12 20:15:45 INFO hdfs.NNBench:                    RAW DATA: Late maps: 0
    22/10/12 20:15:45 INFO hdfs.NNBench:              RAW DATA: # of exceptions: 12000
    22/10/12 20:15:45 INFO hdfs.NNBench: 

2.7.3 mrbench

mrbench会多次重复执行一个小作业,用于检查在机群上小作业的运行是否可重复以及运行是否高效。

    hadoop jar hadoop-mapreduce-client-jobclient-2.10.2-tests.jar mrbench -numRuns 5

测试结果:

    DataLines	Maps	Reduces	AvgTime (milliseconds)
    1		2	1	22018
    #平均作业完成时间为22.018秒

2.8 MapReduce应用WordCount

2.8.1 WordCount执行流程

进入hadoop

    cd /usr/local/hadoop

在HDFS中创建input目录

    hadoop fs -mkdir /input

将LICENSE.txt放到input目录下

    hadoop fs -put LICENSE.txt /input 

执行wordcount程序

    hadoop jar /usr/local/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.10.2.jar wordcount /input /output

wordcount时间消耗


    time hadoop jar /usr/local/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.10.2.jar wordcount /input /output

mapreduce程序wordcount时间消耗情况

    real	0m1.720s	#实际时间 (real time): 从 command 命令行开始执行到运行终止的消逝时间
    user	0m1.642s	#用户 CPU 时间 (user CPU time): 命令执行完成花费的用户CPU时间,即命令在用户态中执行时间总和
    sys	0m0.804s	# 系统 CPU 时间 (system CPU time): 命令执行完成花费的系统CPU时间,即命令在核心态中执行时间总和。

查看wordcount执行结果(License.txt文档内容过大,之只展示部分wordcount结果)

    hadoop fs -cat /output/part-r-00000

在这里插入图片描述

2.8.2 WordCount程序的实现(map和reducer)

  • reducer
  import org.apache.hadoop.io.IntWritable;
    import org.apache.hadoop.mapreduce.Reducer;
     
    import javax.xml.soap.Text;
    import java.io.IOException;
     
    public class WordCountReducer extends Reducer<Text, IntWritable,Text,IntWritable> {
     
        @Override
        protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
            super.reduce(key, values, context);
            //在reduce里拿到的是mapper已经map好的数据
            //现在数据的形式是这样的:
            //atguigu(key),1(value)
            //atguigu(key),1(value)
     
            int sum=0;
            //累计求和
            for(IntWritable value: values)
            {
                sum+=value.get();//将intwrite对象转化为int对象
            }
            IntWritable v=new IntWritable();
            v.set(sum);
            //2.写出 atguigu 2
            context.write(key,v);
     
            //总结,这个程序看起来并没有起到分开不同单词,并对同一单词的value进行相加的作用啊
            //唯一的功能则是统计仅有一个单词的字符之和,这有啥用......
        }
    }

  • map
 //现在我们开始编写wordcount的示例
    public class WordcountMapper extends Mapper<LongWritable, Text,Text, IntWritable> {
    //mapper后面的参数:
        // 1.输入数据的key类型
        // 2.输入数据的value类型
        // 3.输出数据的key类型
        // 4.输出数据的value的类型
     
        protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
            //1.首先获取一行
            String line=value.toString();
            //2.将获取后的单词进行分割,按照空格进行分割
            String[] words=line.split(" ");
            //3.循环输出(不是输出到控制台上面,是输出到reducer里进行处理)
           for(String word:words)
           {
               Text k=new Text();//定义我们输出的类型,肯定是Text,和整个类extends的顺序对应
               k.set(word);
               IntWritable v=new IntWritable();
               v.set(1);//将value设置为1
               context.write(k,v);
           }
        }
    }
  • main
 import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.io.IntWritable;
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapreduce.Job;
    import org.apache.hadoop.fs.Path;
    import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
     
    public class wordcoundDriver {
        //将mapper和reducer进行启动的类
        //driver是完全格式固定的
        public static void main(String[] args) throws Exception {
            Configuration conf=new Configuration();
            //1.获取Job对象
            Job job=Job.getInstance(conf);
            //2.设置jar储存位置
            job.setJarByClass(wordcoundDriver.class);
            //3.关联map和reduce类
            job.setMapperClass(WordcountMapper.class);
            job.setReducerClass(WordCountReducer.class);
            //4.设置mapper阶段输出数据的key和value类型
            job.setMapOutputKeyClass(Text.class);
            job.setMapOutputValueClass(IntWritable.class);
            //5.设置最终数据输出的key和value类型
            job.setOutputKeyClass(Text.class);
            job.setOutputValueClass(IntWritable.class);
            //6.设置输入路径和输出路径
            FileInputFormat.setInputPaths(job,new Path(args[0]));
            FileInputFormat.setInputPaths(job,new Path(args[1]));
            //7.提交Job
            job.submit();
            job.waitForCompletion(true);
        }
    }

参考资料
[1]https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/Benchmarking.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哈士奇谭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值