Ubuntu 16.04 Hadoop-2.7.3全分佈模式 + eclipse hadoop

NullSpider發表於2019-03-04

Ps1:主要答疑區在本帖最下方,疑點會標註出來。個人在配置過程中遇到的困難都會此列舉。

Ps2:本帖也是我自己原創的,最近從CSDN搬家過來。原帖地址


實驗介紹:

  本次實驗主要介紹了Hadoop平臺的兩個核心工具,HDFS和Mapreduce,結合這兩個核心在Linux下搭建基於YARN叢集的全分佈模式的Hadoop架構。

  實驗案例,基於Hadoop平臺下的Wordcount分詞統計的試驗

實驗需求:

  1、PC機,區域網服務,Linux系統  

背景介紹:

  Hadoop實現了一個分散式檔案系統,簡稱HDFS。
  HDFS有高容錯性的特點,並且設計用來部署在普PC機上,而且它提供高吞吐量來訪問應用程式的資料,適合那些有著超大資料集的應用程式。
  HDFS放寬了POSIX的要求,可以以流的形式訪問檔案系統中的資料。
  Hadoop的框架最核心的設計就是:
    HDFS和MapReduce。
    HDFS為海量的資料提供了儲存,則MapReduce為海量的資料提供了計算。
  
  開發者在熟練掌握了hadoop的使用後輕鬆地在Hadoop上開發和執行處理海量資料的應用程式
  

  NameNode

  NameNode 是一個通常在 HDFS 例項中的單獨機器上執行的軟體。
  它負責管理檔案系統名稱空間和控制外部客戶機的訪問。NameNode 決定是否將檔案對映到 DataNode 上的複製塊上。
  對於最常見的 3 個複製塊,第一個複製塊儲存在同一機架的不同節點上,最後一個複製塊儲存在不同機架的某個節點上。
  實際的 I/O事務並沒有經過 NameNode,只有表示 DataNode 和塊的檔案對映的後設資料經過 NameNode。
  當外部客戶機傳送請求要求建立檔案時,NameNode 會以塊標識和該塊的第一個副本的 DataNode IP 地址作為響應,這個 NameNode 還會通知其他將要接收該塊的副本的 DataNode。
  NameNode 在一個稱為 FsImage 的檔案中儲存所有關於檔案系統名稱空間的資訊。
  這個檔案和一個包含所有事務的記錄檔案(這裡是 EditLog)將儲存在 NameNode 的本地檔案系統上。FsImage 和 EditLog 檔案也需要複製副本,以防檔案損壞或 NameNode 系統丟失。
  NameNode本身不可避免地具有SPOF單點失效的風險,主備模式並不能解決這個問題,通過Hadoop Non-stop namenode才能實現100% uptime可用時間。

  DataNode

  DataNode 也是一個通常在 HDFS例項中的單獨機器上執行的軟體。
  Hadoop 叢集包含一個 NameNode 和大量 DataNode。
  DataNode 通常以機架的形式組織,機架通過一個交換機將所有系統連線起來。
  Hadoop 的一個假設是:機架內部節點之間的傳輸速度快於機架間節點的傳輸速度。
  DataNode 響應來自 HDFS 客戶機的讀寫請求。它們還響應來自 NameNode 的建立、刪除和複製塊的命令。
  NameNode 依賴來自每個 DataNode 的定期心跳(heartbeat)訊息。每條訊息都包含一個塊報告,NameNode 可以根據這個報告驗證塊對映和其他檔案系統後設資料。
  如果 DataNode 不能傳送心跳訊息,NameNode 將採取修復措施,重新複製在該節點上丟失的塊。

實驗步驟及結果:

1.搭建平臺(全分散式hadoop + eclipse Neon.1 + JDK1.8)

  

  叢集搭建:

  主機兩臺(可擴充):

  (1)兩個主機系統均為Ubuntu 16.04 LTS

    詳情:

      master 192.168.:103.26(虛擬機器)

      slave2 192.168.103.22(物理機)

      

      注:

        (1)slave1是在同學的筆記本上,因為他的筆記本總是飄忽不定,所以這次部落格上就先不寫他的ip地址

        (2)master是虛擬機器的理由就是第一次嘗試怕配錯環境,導致崩潰,所以用了VMware為master,方便拯救平臺

  (2)hadoop平臺版本都為最新穩定版2.7.3(解壓及安裝hadoop)      

      下載地址:Hadoop官網 hadoop.apache.org/releases.ht…

      

      步驟1:點開網頁以後,點選紅色箭頭所指的連結

      步驟2:點開後如下圖

      

      步驟3:選擇一個連結下載(個人推薦最後一個 tsinghua.edu.cn 清華大學連結源比較好)

      步驟4:下載完後開啟檔案管理器,選擇Downloads資料夾(如果修改主要資料夾名字為中文的,應選擇“下載”)

      

      步驟5:解壓到指定路徑

      步驟5.1:在當前資料夾下右鍵 - 在終端開啟 鍵入su root命令

      

      步驟5.2:輸入root使用者密碼後,如下圖所示

      

      步驟5.3:鍵入解壓命令

sudo tar zxvf hadoop-2.7.3.tar.gz -C /usr/local/hadoop
複製程式碼

        (注意:如果提示hadoop資料夾不存在的,可以在root使用者下用cd命令到 /usr/local路徑下 鍵入 sudo mkdir /hadoop 建立夾)

      步驟5.4:解壓後如下圖所示

        (注意:路徑滿足如圖所示即可,或自行定義)

    至此hadoop前期下載準備工作已經完成。接下準備java環境的配置

 

  (3)JDK版本為java8-oracle(配置java環境)

     (環境:系統穩定聯網狀態下)

      步驟1:開啟終端鍵入命令(root使用者模式可以不用加sudo字首)

sudo add-apt-repository ppa:webupd8team/java複製程式碼

      步驟2:出現一段文字後按回車繼續

      步驟3:繼續鍵入命令

sudo apt-get update複製程式碼

      步驟4:待系統載入完所有下載源

      步驟5:鍵入安裝命令

sudo apt-get install oracle-java8-installer複製程式碼

      步驟6:等待下載結束(過程稍微有點漫長)

      

      這個版本的java預設安裝在 /usr/lib/jvm資料夾下

      安裝結束後配置環境變數

      

      終端輸入:

sudo gedit /etc/profile複製程式碼

      步驟7:配置完後,按 ctrl + s 儲存

      步驟8:在終端中輸入

sudo source /etc/profile複製程式碼

      使配置的環境變數生效

      步驟9:和在Windows下配置一樣,在終端測試java和javac命令是否生效,在linux下可以多測試下jps命令看java程式號

      

      至此java環境變數配置完畢

  (4)SSH免密配置

    SSH 是目前較可靠,專為遠端登入會話和其他網路服務提供安全性的協議。利用 SSH 協議可以有效防止遠端管理過程中的資訊洩露問題。SSH最初是UNIX系統上的一個程式,後來又迅速擴充套件到其他操作平臺。

    SSH在正確使用時可彌補網路中的漏洞。SSH客戶端適用於多種平臺。

      Ubuntu Linux下配置免密登入主要依靠 ssh localhost的命令

      !!注意,如果改過 /etc/hosts 下的內容需要重新配置(下圖是我的例子)

    

    由於後期為了避免hadoop的一些埠和IP錯誤,所以我把localhost的名字改了,順帶把 /etc/hostname 的名字也改了。

    改了上述的 hosts 和 hostname的名字後,記得重啟電腦或者虛擬機器

    

    192.168.91.45是我虛擬的IP的地址 名字叫master 相當於 沒有改變配置檔案之前的 127.0.0.1 localhost

    所以配置ssh免密的時候是鍵入 ssh master 而不是 ssh localhost

    

    話不多說!

    步驟0:SSH需要安裝OpenSSH-server(如果已經安裝則無需理會)

sudo apt-get install openssh-server複製程式碼

    步驟1:在非root使用者模式下開啟終端鍵入ssh localhost(或者是定義的使用者名稱)

    步驟2:提示輸入密碼,輸入你的ssh密碼(自己記得住就好)

    步驟3:輸入完以後,測試一下ssh localhost(或是自定義名字),輸入密碼後是否如下圖彈出一些資訊

    

    步驟4:如果下午所示後,則建立ssh成功

    步驟5:建立免密登入(不需要關閉終端),鍵入如下命令

ssh-keygen -t rsa複製程式碼

    

    步驟6:一直按回車直至出現RSA視窗即可

    步驟7:鍵入命令

sudo cp .ssh/id_rsa.pub .ssh/authorized_keys複製程式碼

    步驟8:驗證免密登入,輸入ssh localhost(或者自定義的名字),是否還需要輸入密碼登入

    root使用者下:

    步驟1:進入root使用者模式(使用者模式下在終端鍵盤入:su root,輸入root密碼即可)

    步驟2:進入ssh配置檔案

gedit /etc/ssh/sshd_config複製程式碼

    

    步驟3:把PermitRootLogin的欄位改成 yes(原來的好像是Prohibit xxxx的),有點忘記了。總之改成yes就可以了

    步驟4:儲存退出終端

    步驟5:開啟新的終端鍵入命令

sudo service ssh restart複製程式碼

    重啟ssh服務之後,開啟終端

    

    步驟6:進入root使用者模式下,鍵入 ssh localhost(或是你的自定義名字)

    步驟7:輸入自定義ssh密碼後,與使用者模式下的類似

    步驟8:鍵入 ssh-keygen -t rsa 建立RSA金鑰

    步驟9:一直回車直至出現RSA金鑰圖,(如果提示Overwrite 輸入 y 即可)

    步驟10:鍵入配置免密的命令

cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys複製程式碼

    步驟11:完成後,在root使用者模式輸入 ssh localhost(或自定義名字)後,如下圖所示即可。

        

    

    至此,root使用者和普通使用者模式的ssh免密配置完成。

    

  (4.1)SSH免密配置(節點篇)

      需求:如果每個節點都需要下載安裝hadoop ,則大量耗費人力物力。

      解決:所以需要一個SSH來遠端傳送hadoop包分發給每個節點。

      

      接下來來講解master打通每個節點的連線方式(單節點和多節點一樣,只要配置好就可以進行連線)

      步驟1:在hosts檔案中配置好各子節點的ip地址以及名稱(如下圖)

      

      步驟2: 編輯好hosts檔案儲存並關閉,(root使用者模式下)開啟終端輸入

ssh-copy-id -i ~/.ssh/id_rsa.pub root@slave* 
(星號代表子節點號碼,或者把slave*換成自定義的名稱)複製程式碼

      步驟3:提示輸入,子節點的登入密碼,輸入完成後,等待命令完成

      步驟4:在終端中輸入 ssh slave*(或者自定義名字),如下圖:

     步驟5:ssh打通master和子節點的通道,可以通過scp命令傳輸資料了。

     至此,完成對於子節點的ssh免密訪問配置。

  (5)hadoop平臺版本都為最新穩定版2.7.3(解壓及安裝hadoop)

    hadoop配置下主要注意配置檔案路徑的問題

    主要包括:hadoop根目錄下 /etc/hadoop 裡面的xml配置檔案

      例:hadoop-env.sh , hdfs-site.xml, mapred-site.xml , core-site.xml , yarn-site.xml

      

      注:mapred-site.xml需要複製出來到本路徑,原本是mapred-site.xml.template 需要用 cp 命令複製並改名字

        或者可以通過 gedit 命令建立一個新的mapred-site.xml,把模板內的內容複製過去,然後再進行配置

     

      配置檔案1:hadoop-env.sh(配置環境變數,讓hadoop識別)

      配置檔案2:core-site.xml

<configuration>
    <property>
        <name>fs.default.name</name>
        <value>hdfs://master:8020</value>
    </property>
    <property>
        <name>io.file.buffer.size</name>
        <value>131072</value>
    </property>
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/home/hadoop/tmp</value>
    </property>
    <property>
        <name>hadoop.proxyuser.hadoop.hosts</name>
        <value>*</value>
    </property>
    <property>
        <name>hadoop.proxyuser.hadoop.group</name>
        <value>*</value>
    </property>
    <property>
        <name>dfs.permissions</name>
        <value>false</value>
    </property>
</configuration>複製程式碼

      配置檔案3:hdfs-site.xml

<configuration>
    <property>
        <name>dfs.namenode.secondary.http-address</name>
        <value>master:9000</value>
    </property>
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>file:/home/hadoop/dfs/name</value>
    </property>
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>file:/home/hadoop/dfs/data</value>
    </property>
    <property>
        <name>dfs.replication</name>
        <value>3</value>
    </property>
    <property>
        <name>dfs.webhdfs.enabled</name>
        <value>true</value>
    </property>
</configuration>複製程式碼

      配置檔案4: mapred-site.xml

<configuration>
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
    <property>
        <name>mapred.job.tracker</name>
        <value>master:9001</value>
    </property>
    <property>
        <name>mapred.job.tracker.http.address</name>
        <value>master:50030</value>
    </property>
    <property>
        <name>mapreduce.jobhistory.address</name>
        <value>master:10020</value>
    </property>
    <property>
        <name>mapreduce.jobhistory.webapp.address</name>
        <value>master:19888</value>
    </property>
</configuration>複製程式碼

      配置檔案5:yarn-site.xml

<configuration>
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>
    <property>
        <name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name>
        <value>org.apache.hadoop.mapred.ShuffleHandler</value>
    </property>
    <property>
        <name>yarn.resourcemanager.address</name>
        <value>master:8032</value>
    </property>
    <property>
        <name>yarn.resourcemanager.scheduler.address</name>
        <value>master:8030</value>
    </property>
    <property>
        <name>yarn.resourcemanager.resource-tracker.address</name>
        <value>master:8031</value>
    </property>
    <property>
        <name>yarn.resourcemanager.admin.address</name>
        <value>master:8033</value>
    </property>
    <property>
        <name>yarn.resourcemanager.webapp.address</name>
        <value>master:8088</value>
    </property>
</configuration>複製程式碼

      !!!注:如果是master節點(即伺服器)需要新增多一個slaves檔案指定slave

      配置檔案6:slaves(選)

slave2 192.168.90.33複製程式碼

     

    最後步驟:以上配置檔案配置完畢後開啟終端視窗,輸入

hadoop namenode -format複製程式碼

    出現如下結果,沒有JAVA報錯即可

    初始化hadoop namenode節點成功!

    

    開啟終端利用 cd 命令進入hadoop啟動命令檔案下

cd /usr/local/hadoop/hadoop-2.7.3/sbin複製程式碼

    

    鍵入如下命令啟動hadoop(root使用者模式下)     

./start-all.sh複製程式碼

    關閉hadoop則鍵入命令關閉

./stop-all.sh複製程式碼

    

    輸入jps在master節點測試,如果如上圖所示則測試成功

    在ssh slave2 節點輸入jps測試

    

    通過hadoop 自帶命令

hadoop dfsadmin -report複製程式碼

    如上圖所示輸出Live Datanodes,說明有存活節點,死節點為空。

    證明叢集配置成功!

  (6)叢集安裝hadoop(完成Master節點的hadoop安裝以及SSH的搭建)    

    構建好master與各個slave之間的ssh通訊,如下圖所示

    步驟1:測試ssh命令與各節點間的通訊

    步驟2:確認本機的hadoop安裝地址

    步驟3:

scp –r /usr/local/hadoop/ root@slaver2:/usr/local/hadoop 複製程式碼

    把master上的hadoop分發給slave2節點(其他節點依次類推,只要搭好ssh就可以傳輸)。

    傳輸過程有點久,耐心等候。

    步驟4:在slave節點上配置環境變數

HADOOP_HOME=/usr/local/Hadoop  PATH=$PATH:${HADOOP_HOME}/bin:${HADOOP_HOME}/sbin複製程式碼

    步驟5:在master啟動hadoop進行測試

Namenode介面 50070埠

hadoop管理介面 8088埠

hadoop SecondaryNamenode 管理介面 埠9000

  (7)hadoop Wordcount測試(完成eclipse和eclipse hadoop外掛安裝)

    步驟0:安裝eclipse和eclipse hadoop外掛

      步驟0.1:安裝eclipse

      

    下載後,解壓到自定義路徑,解壓後如所示

      在此給出eclipse hadoop外掛下載(pan.baidu.com/s/1mi6UP5I

      下載後,把jar放到eclipse根目錄的dropins的目錄

      在根目錄進入終端,進入root使用者模式,輸入

./eclipse複製程式碼

      進入eclipse介面,完成安裝。

      

    步驟1:啟動hadoop完成上述叢集測試

    步驟2:通過終端把測試資料 test.txt上傳到hdfs中 (test.txt為hadoop跟目錄下的NOTICE.txt)

      步驟2.1:在hdfs目錄下建立input資料夾

hadoop fs -mkdir /input
hadoop fs -put test.txt /input複製程式碼

    如圖所示,則上傳成功。

    如果許可權不對的話可以修改許可權

hadoop fs -chmod -R 777 /input/test.txt複製程式碼

    

    步驟3:開啟eclipse,並完成mapreduce的wordcount程式碼,完成eclipse hadoop的配置

   步驟4:確保左上角的DFS Location能夠顯示hdfs中的檔案目錄

WordCount程式碼:

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;

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());
            while (itr.hasMoreTokens()) 
            {
                word.set(itr.nextToken());
                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);
        }
    }

    public static void main(String[] args) throws Exception 
    {
        Configuration conf = new Configuration();
        Job job = Job.getInstance(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);
        FileInputFormat.addInputPath(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));
        System.exit(job.waitForCompletion(true) ? 0 : 1);
    }
}複製程式碼

log4j日誌檔案:

log4j.rootLogger=debug, stdout, R 
#log4j.rootLogger=stdout, R   
log4j.appender.stdout=org.apache.log4j.ConsoleAppender   
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout   
#log4j.appender.stdout.layout.ConversionPattern=%5p - %m%n   
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n  
log4j.appender.R=org.apache.log4j.RollingFileAppender   
log4j.appender.R.File=log4j.log   
log4j.appender.R.MaxFileSize=100KB   
log4j.appender.R.MaxBackupIndex=1   
log4j.appender.R.layout=org.apache.log4j.PatternLayout   
#log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n   
log4j.appender.R.layout.ConversionPattern=%d %p [%c] - %m%n  
#log4j.logger.com.codefutures=DEBUG複製程式碼

    步驟5:配置Run Configuration

    步驟6:右鍵Run As - Run On Hadoop(日誌我選用了DEBUG模式測試,所以會很長,但是方便測試)

    

    此時,master hdfs多出一個資料夾存放分詞結果

    下列圖為結果部分截圖:

    

    至此,從安裝到mapreduce Wordcount測試全部結束了。

    hadoop2.7.6全模式下,結合eclipse hadoop外掛配置,完成Wordcount測試。

實驗結果分析:

1、Wordcount專案程式碼是結合Map-reduce的核心思想,以及對於Java輸入輸出流的認識所編寫,也參考了一下"大牛"部落格編寫的,能夠基本實現分詞-詞頻統計。

2、小專案的分詞的效果顯然沒有Python Jieba分詞來的精確,但是基於Hadoop Mapreduce的運算,分詞一篇詞彙眾多的文件只需要5秒。(如需檢視請點開。文件來源:Hadoop LICENSE.txt)

測試文件

心得體會:

    1、實驗完成結果到達預期目標,在搭建平臺的過程耗費了很多學習成本,主要花在安裝包的下載以及對於Linux系統的理解和hadoop配置檔案的理解。

    2、實驗完成的過程中與小組成員分工合作,在搭建過程中自學了linux的命令操作以及linux系統的一些工作原理。

    3、在搭建hadoop平臺時,遇到很多匪夷所思的問題,通過hadoop平臺自帶的log檔案,檢視日誌檔案,百度搜尋或者看國外網站的配置方式,再通過自己的嘗試,解決問題。

    4、在搭建過程體會最深的就是hadoop對於埠的使用很謹慎,第一次在嘗試的時候沒有仔細看清楚官網文件的埠設定,配置出錯,導致進度耽誤幾天,最後才發現是埠的問題。

    5、在搭建完後對於linux系統也有深刻的體會,對於linux的許可權設定,SSH,以及基本的檔案操作命令等有基本的掌握經驗。

    6、小組成員在第一次衝刺後決定更改軟體工程專案,主要是為了適應目前的學習任務以及工作任務。小組成員目前在分析 學校歷年學生體質測試資料 以及 網路招聘崗位資料對應學校各二級學院的專業核心技能

      Python Django專案屬於python後端專案,初期小組成員定題是為了學習除java後端以外的另外一直後端開發。但是後期因為繁重的分析任務以及報告,所以決定開始尋找新的出路,也順利在第三次衝刺前幾天完成實驗。

      雖然可能與軟體工程的專案關係不太大,但是在搭建平臺的過程,小組成員也深刻體會到團隊合作的意義。以及對於大資料平臺的理解,不再是覺得深不可測,改變對於大資料平臺以及雲端計算的看法。

展望:

    1、希望在接下來的寒假或者未來的時間點,完善自己的hadoop平臺,通過hadoop平臺提交小組的資料分析專案,利用Mapreduce並行化演算法以及YARN叢集分散式計算,提高資料分析的效率。

    2、以及寫一個基於hadoop平臺的分散式爬蟲,提高大資料的讀取時間。

    3、目前也在學習Spark,掌握與Mapreduce相類似的並行化運算框架,也希望在日後的使用中,結合HBase,Mapreduce/Spark搭建一個雲端計算平臺專案。

    4、在未來的時間,花更多時間從理解hadoop的核心架構,到理解hadoop的外沿,學習Spark,HBase,Pig,Mahout,Hive等核心工具的使用。

    5、最近時間關注大資料方向注意到關聯資料RDF的應用,也希望能嘗試利用Sqoop讀取關聯資料,進行資料分析。


相關文章