Hadoop的安装、测试、以及为伪分布式下矩阵乘法的实现

Hadoop的安装、测试、以及为伪分布式下矩阵乘法的实现

1  Hadoop的安装

(1)运行环境:

      Linux环境:Ubuntu13.04

      Hadoop安装包:hadoop-1.1.2.tar

(2)安装主要分为以下几个步骤:( 以root登录linux )

      ①安装SSH,输入如下命令:

           apt-get install ssh

      ②安装JAVA环境,输入如下命令:

           apt-get install sun-java6-jdk

      这条命令将自动完成java包的下载、安装以及环境变量配置,安装完成之后,直接在命令行下输入java测试JDK环境是否已成功搭建,若成功,则如下图1-1所示:



图1-1 java环境测试

      另外,可通过输入java –version来查看java的版本号,如图1-2所示:


图1-2 查看JAVA版本号

      ③安装Hadoop安装包:

      首先将Hadoop的安装包复制到/usr目录下,然后在终端中输入命令解压

           tar -xzvf hadoop-1.1.2.tar

      然后是在Hadoop中配置java环境,及加入JAVA_HOME的目录地址,具体是修改conf/hadoop-env.sh文件,加入一行:

           exportJAVA_HOME=/usr/lib/jvm/java-6-sun-1.6.0.06

      也就是JAVA安装包默认的安装位置。

      ④在默认模式(单机模式下),测试Hadoop是否能正确运行,这里使用测试包中的WordCount类来测试:

      具体如下:(在解压后的hadoop-1.1.2文件夹目录下)

      创建输入文件夹input,并创建两个输入文件test1.txt和text2.txt,如下:

      mkdirinput

      cdinput

      echo“hello we are one world”>test1.txt

      echo“we are young one world”>test2.txt

      然后运行WordCount实例:

           bin/hadoop jarhadoop-examples-1.1.2.jar wordcount input output

      运行完了之后,可输入如下命令查看输出信息:

           cat output/*

      结果如下图1-3所示:


图1-3 默认模式下wordcount实例输出

(3)伪分布式模式下的配置和wordcount实例运行

      ①修改conf/ 目录下以下三个文件的参数,具体如下图1-4、1-5和1-6所示:


图1-4 core-site.xml文件


图1-5 hdfs-site.xml文件


图1-6 mpared-site.xml文件

      ②免密钥SSH设置:

      cd 到~/,先创建文件夹 .ssh ,然后生成密钥对:

           ssh-keygen -t rsa     一直按Enter,选择默认设置

      之后进入.ssh目录,复制密钥对:

           cp id_rsa.pub anthorized_keys 

      ③运行wordcount实例过程:

      格式化分布式文件系统:(当前目录是hadoop-1.1.2)

           bin/hadoop  namenode –format

      启动Hadoop守护进程:

           bin/start-all.ssh

      启动后,可输入jps命令查看当前所有java进程,如下图1-7所示:


图1-7 jps命令显示当前JAVA进程

      运行wordcount实例:

           由于是分布式,需要把本地输入文件夹input拷贝到HDFS下,这里创建in文件夹,就拷到这:

                 bin/hadoopfs -copyFromLocal input in

           然后就调用实例包来运行wordcount实例,注意这是分布式,输出结果也在HDFS端:

                 bin/hadoopjar hadoop-examples-1.1.2.jar wordcount in out

           执行完了之后,如下图1-8所示:


图1-8 运行情况

    然后查看输出结果,输入bin/hadoop fs -cat out/* ,如下图1-9所示:


图1-9 查看运行输出结果

2   利用Hadoop实现矩阵乘法

(1)编程思路:

    采用的是MapReduce的并行编程方法,MapReduce 的计算过程简而言之,就是将大数据集分解为成百上千的小数据集,每个(或若干个)数据集分别由集群中的一个结点(一般就是一台普通的计算机)进行处理并生成中间结果,然后这些中间结果又由大量的结点进行合并, 形成最终结果。其模型如下图2-1所示:


图2-1MapReduce并行计算模型

    计算模型的核心是 Map 和 Reduce 两个函数,这两个函数由用户负责实现,功能是按一定的映射规则将输入的<key, value> 对转换成另一个或一批 <key, value> 对输出。

    在矩阵乘法中,只有在第一个矩阵的列数和第二个矩阵的行数相同时才有定义。一般单指矩阵乘积时,指的便是一般矩阵乘积。若M为i×r矩阵,N为r×j矩阵,则他们的乘积M·N会是一个i×j矩阵。其乘积矩阵的元素如下式2-1得出:

   

 

(2)实现过程:

      对矩阵乘法的MapReduce实现方法是:

  ①Map函数:对于矩阵M的每个元素M[i,j],产生一系列的键值对:

                            (i,k)--> ( M , j , M[ i , j ] )

      其中k=1,2…,直到矩阵N的列数。

      同样,对于矩阵N的每个元素N[j,k],产生一系列的键值对:

                            ( i , k) ->( N , j , N[ j , k ])

      其中i=1,2…,直到矩阵M的行数。

  ②Reduce函数:根据MapReduce的原理,相同键i,k的数据会发送个同一个reduce。

      例如:

      如果M为2*2矩阵,N为2×3矩阵,reduce函数需要处理的数据为: (1,1)-> [(M,1,M[1,1])、(M,2, M[1,2])、(N,1, N[1,1])、(N,2, N[2,1])],

  (1,2)->[(M,1,M[1,1])、(M,2, M[1,2])、(N,1, N[1,2])、(N,2, N[2,2])],

 (1,3)->[(M,1,M[1,1])、(M,2, M[1,2])、(N,1, N[1,3])、(N,2,N[2,3])],

   (2,1)-> [(M,1,M[2,1])、(M,2, M[2,2])、(N,1, N[1,1])、(N,2, N[2,1])],

    (2,2)-> [(M,1,M[2,1])、(M,2, M[2,2])、(N,1, N[1,2])、(N,2, N[2,2])],

    (2,3)-> [(M,1,M[2,1])、(M,2, M[2,2])、(N,1, N[1,3])、(N,2, N[2,3])]。

      这样只要将所有(M,j, M[i,j])和(N,j, N[j,k])分别按照j值排序并放在不同的两个列表里面。将这个列表的第j个元素M[i,j]个N[j,k]相乘,然后将这些积相加,最后积的和与键(i,k)组对作为reduce函数的输出。对于上面的例子reduce的输出就是:

(1,1)->(M[1,1]*N[1,1]+ M[1,2]* N[2,1])

(1,2)->(M[1,1]*N[1,2]+ M[1,2]* N[2,2])

(1,3)->(M[1,1]*N[1,3]+ M[1,2]* N[2,3])

(2,1)->(M[2,1]*N[2,1]+ M[2,2]* N[2,1])

(2,2)->(M[2,1]*N[1,2]+ M[2,2]* N[2,2])

(2,3)->(M[2,1]*N[1,3]+ M[2,2]* N[2,3])

 

(3)具体代码实现如下:      【MartrixMultiplication.java】

来自网站:https://github.com/intergret/snippet/blob/master/MartrixMultiplication.java

importjava.io.IOException;

importorg.apache.hadoop.conf.Configuration;

importorg.apache.hadoop.fs.Path;

importorg.apache.hadoop.io.Text;

importorg.apache.hadoop.mapreduce.Job;

importorg.apache.hadoop.mapreduce.Mapper;

importorg.apache.hadoop.mapreduce.Reducer;

importorg.apache.hadoop.mapreduce.lib.input.FileInputFormat;

importorg.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

importorg.apache.hadoop.util.GenericOptionsParser;

 

publicclass MartrixMultiplication{

  public static class MartrixMapper extends Mapper<Object,Text, Text, Text>{

    private Text map_key = new Text();

    private Text map_value = new Text();

  

    int rNumber = 50;

    int cNumber = 50;              //一个50*50的矩阵

    String fileTarget;

    String i, j, k, ij, jk;

   

    public void map(Object key, Text value,Context context) throws IOException, InterruptedException {                                            //Map函数

        String eachterm[] =value.toString().split("#");

        fileTarget = eachterm[0];

       

        if(fileTarget.equals("M"))

              {

          i = eachterm[1];

          j = eachterm[2];

          ij = eachterm[3];

        for(int c = 1; c<=cNumber; c++)

               {

              map_key.set(i + "#" +String.valueOf(c));

              map_value.set("M" +"#" + j + "#" + ij);

              context.write(map_key,map_value);

          }

         }

              elseif(fileTarget.equals("N"))

              {

          j = eachterm[1];

          k = eachterm[2];

          jk = eachterm[3];

         for(int r = 1; r<=rNumber; r++)

               {

              map_key.set(String.valueOf(r) +"#" +k);

              map_value.set("N" +"#" + j + "#" + jk);

              context.write(map_key,map_value);

          }

        }

    }

  }

 

  public static class MartrixReducer extendsReducer<Text,Text,Text,Text> {

   

    private Text reduce_value = new Text();

    int jNumber = 50;

    int M_ij[] = new int[jNumber+1];

    int N_jk[] = new int[jNumber+1];

    int j, ij, jk;

    String fileTarget;

    intjsum = 0;

   

    public void reduce(Text key,Iterable<Text> values, Context context) throws IOException,InterruptedException {                //reduce函数

      jsum = 0;

      for (Text val : values)

         {

        String eachterm[] =val.toString().split("#");

        fileTarget = eachterm[0];

        j = Integer.parseInt(eachterm[1]);

        if(fileTarget.equals("M"))

                 {

                  ij= Integer.parseInt(eachterm[2]);

                  M_ij[j]= ij;

            }

           elseif(fileTarget.equals("N")){

                  jk= Integer.parseInt(eachterm[2]);

                  N_jk[j]= jk;

            }     

      }

      for(int d = 1; d<=jNumber; d++)

         {

             jsum += M_ij[d] * N_jk[d];

      }

      reduce_value.set(String.valueOf(jsum));

      context.write(key, reduce_value);

    }

  }

 

  public static void main(String[] args) throwsException {           //main函数入口

      Configuration conf = new Configuration();

      String[] otherArgs = newGenericOptionsParser(conf, args).getRemainingArgs();

      if (otherArgs.length != 2) {

             System.err.println("Usage:MartrixMultiplication <in> <out>");

             System.exit(2);

      }

 

      Job job = new Job(conf,"martrixmultiplication");

     job.setJarByClass(MartrixMultiplication.class);

      job.setMapperClass(MartrixMapper.class);

     job.setReducerClass(MartrixReducer.class);

 

      job.setOutputKeyClass(Text.class);

      job.setOutputValueClass(Text.class);

 

      FileInputFormat.addInputPath(job, newPath(otherArgs[0]));

      FileOutputFormat.setOutputPath(job, newPath(otherArgs[1]));

      System.exit(job.waitForCompletion(true) ?0 : 1);

  }

}

(4)编译运行过程:

      由于伪分布式环境下,节点性能有限,尤其是跑在虚拟机环境下,试了一下跑500*500的矩阵,Map到66%左右就发现虚拟机硬盘爆了,所以,为了测试算法的正确性,下面使用50*50的矩阵来运行。只要算法是恰当的,数据规模可以随硬件支持程度而改变。

      首先把源文件编译生成MartrixMultiplication.jar,需要调用以下两个包:

      /usr/hadoop-core-1.1.2.jar

      /usr/hadoop-1.1.2/lib/commons-cli-1.2.jar

 

      ①在缺省目录(/usr/hadoop-1.1.2/)下,把MartrixMultiplication.java文件放在一个新的文件夹local_matrix下(文件夹的名称随意,这个只是方便记忆,),然后把测试数据文件M.data放在另外一个新的文件夹input2下;

      M.data中的数据形式为:(一行一个数据)

           M#a#b#c    表示M矩阵第a行第b列的值是c;

           M#a#b#c    表示N矩阵第a行第b列的值是c;

      编译MartrixMultiplication.java文件,生成class文件:

           javac -classpathhadoop-core-1.1.2.jar:lib/commons-cli-1.2.jar

                  -d  local_matrix  local_matrix/MartrixMultiplication.java

      打包发布,生成MartrixMultiplication.jar文件:

           jar -cvflocal_matrix/MartrixMultiplication.jar -C local_matrix/ .

      ②把输入文件从本地拷贝到HDFS:

           bin/hadoop fs -copyFromLocal input2in2

      ③运行jar包

           bin/hadoop jarlocal_matrix/MartrixMultiplication.jar

                                  MartrixMultiplicationin2 out2

           运行过程如下图2-2所示:


图2-2 运行过程

      ④对于HDFS,其运行结果输出到了指定的文件夹out2中,要想在本地看到,还得从HDFS中拷贝出来:

           bin/hadoop fs -get out2 output2

      ⑤然后,在本地查看输出的矩阵相乘的结果,既可以直接打开output2文件夹看里面的输出文档part-r-00000,也可以输入下面的命令:

           cat output2/*

      在本次实验中,输入的测试数据是两个50*50,每行每列的值都是1的矩阵,所以按照理论上来说,应该输出一个50*50,每行每列都是50的矩阵,实际输出如下图2-3所示(一部分截图):


图2-3 输出结果

           由输出结果可知,本次计算是与理论相符和,也证明了这个算法的正确性。之后可通过修给代码和输入文件实现大规模数据的运算。此外,也可以配置完全分布式方式来运行。



                                                               *******Workpiece By Henry ******

  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值