1. 程式人生 > >hadoop 偽分散式模式學習筆記

hadoop 偽分散式模式學習筆記

前言

Hadoop在大資料技術體系中的地位至關重要,Hadoop是大資料技術的基礎。

這是一篇記錄我自己學習的文章,Hadoop的學習方法很多,網上也有很多學習路線圖。

hadoop介紹

Hadoop是一個能夠對海量資料進行分散式處理的系統架構。我採用的是hadoop-2.8.0,它主要包含3大塊:

  • hdfs:分散式儲存系統HDFS(Hadoop Distributed File System)分散式儲存層
  • mapreduce:分散式計算框架MapReduce分散式計算層
  • yarn:資源管理系統YARN(Yet Another Resource Negotiator)叢集資源管理層

Hadoop的核心是:HDFS和MapReduce。

分散式儲存系統HDFS

HDFS(Hadoop Distributed File System,Hadoop 分散式檔案系統)是一個高度容錯性的系統,適合部署在廉價的機器上。HDFS 能提供高吞吐量的資料訪問,適合那些有著超大資料集(largedata set)的應用程式。HDFS負責大資料的儲存,通過將大檔案分塊後進行分散式儲存方式,突破了伺服器硬碟大小的限制,解決了單臺機器無法儲存大檔案的問題,HDFS是個相對獨立的模組,可以為YARN提供服務,也可以為HBase等其他模組提供服務。

核心

  • NameNode
  • DataNode
  • SecondaryNameNode(NameNode的快照)

HDFS是一個主從結構,一個HDFS叢集由一個名位元組點(NameNode)和多個數據節點(DataNode)組成。

HDFS的優點(設計思想)

1.高容錯性 HDFS 認為所有計算機都可能會出問題,為了防止某個主機失效讀取不到該主機的塊檔案,它將同一個檔案塊副本分配到其它某幾個主機上,如果其中一臺主機失效,可以迅速找另一塊副本取檔案。資料自動儲存多個節點;備份丟失後,自動恢復。

2.海量資料的儲存 非常適合上T 級別的大檔案或者一堆大資料檔案的儲存

3.檔案分塊儲存 HDFS 將一個完整的大檔案平均分塊(通常每塊64M)儲存到不同計算機上,這樣讀取檔案可以同時從多個主機取不同區塊的檔案,多主機讀取比單主機讀取效率要高得多得多。

4.移動計算 在資料儲存的地方進行計算,而不是把資料拉取到計算的地方,降低了成本,提高了效能!

5.流式資料訪問 一次寫入,並行讀取。不支援動態改變檔案內容,而是要求讓檔案一次寫入就不做變化,要變化也只能在檔案末新增內容。

6.可構建在廉價的機器上 通過多副本提高可靠性,提供了容錯和恢復機制。HDFS 可以應用在普通PC 機上,這種機制能夠讓一些公司用幾十臺廉價的計算機就可以撐起一個大資料叢集。

NameNode

作用

  • 它是一個管理檔案的名稱空間
  • 協調客戶端對檔案的訪問
  • 記錄每個檔案資料在各個DataNode上的位置和副本資訊

檔案解析

  • version:是一個properties檔案,儲存了HDFS的版本號
  • editlog:任何對檔案系統資料產生的操作,都會被儲存!
  • fsimage /.md5:檔案系統元資料的一個永久性的檢查點,包括資料塊到檔案的對映、檔案的屬性等
  • seen_txid :非常重要,是存放事務相關資訊的檔案

什麼是FSImage和EditsLog

FsImage和Editlog是HDFS的核心資料結構。這些檔案的損壞會導致整個叢集的失效。因此,名位元組點可以配置成支援多個FsImage和EditLog的副本。任何FsImage和EditLog的更新都會同步到每一份副本中。

SecondaryNameNode

作用

  • Namenode的一個快照,週期性的備份Namenode
  • 記錄Namenode中的metadata及其它資料
  • 可以用來恢復Namenode,並不能替代NameNode!

執行流程

  1. SecondaryNameNode節點會定期和NameNode通訊,請求其停止使用EditLog,暫時將新的寫操作到一個新的檔案edit.new上來,這個操作是瞬間完成的。
  2. SecondaryNameNode 通過HTTP Get方式從NameNode上獲取到FsImage和EditLog檔案並下載到本地目錄
  3. 將下載下來的FsImage 和EditLog載入到記憶體中這個過程就是FsImage和EditLog的合併(checkpoint)
  4. 合併成功之後,會通過post方式將新的FsImage檔案傳送NameNode上。
  5. SecondaryNamenode 會將新接收到的FsImage替換掉舊的,同時將edit.new替換EditLog,這樣EditLog就會變小。

DataNode

作用

  • 真實資料的儲存管理
  • 一次寫入,多次讀取(不修改)
  • 檔案由資料塊組成,Hadoop2.x的塊大小預設是128MB
  • 將資料塊儘量散佈到各個節點

檔案解析

  • blk_<id>:HDFS的資料塊,儲存具體的二進位制資料
  • blk_<id>.meta:資料塊的屬性資訊:版本資訊、型別資訊

可以通過修改hdfs-site.xml的dfs.replication屬性設定產生副本的個數!預設是3!

基本操作

MapReduce

MapReduce分散式處理框架為海量的資料提供了計算。MapReduce是一個計算框架,它給出了一種資料處理的方式,即通過Map階段、Reduce階段來分散式地流式處理資料。它只適用於大資料的離線處理,對實時性要求很高的應用不適用。

簡介

  • MapReduce是一種分散式計算模型,是Google提出的,主要用於搜尋領域,解決海量資料的計算問題。
  • MR有兩個階段組成:Map和Reduce,使用者只需實現map()和reduce()兩個函式,即可實現分散式計算。

MapReduce執行流程

MapReduce原理

MapReduce的執行步驟

  1. 讀取HDFS中的檔案。每一行解析成一個<k,v>。每一個鍵值對呼叫一次map函式。 - <0,hello you> <10,hello me>
  2. 覆蓋map(),接收1產生的<k,v>,進行處理,轉換為新的<k,v>輸出。 - <hello,1> <you,1> <hello,1> <me,1>
  3. 對2輸出的<k,v>進行分割槽。預設分為一個區。
  4. 對不同分割槽中的資料進行排序(按照k)、分組。分組指的是相同key的value放到一個集合中。 - 排序後:<hello,1> <hello,1> <me,1> <you,1> ;分組後:<hello,{1,1}><me,{1}><you,{1}>
  5. (可選)對分組後的資料進行歸約
  6. 多個map任務的輸出,按照不同的分割槽,通過網路copy到不同的reduce節點上。(shuffle)
  7. 對多個map的輸出進行合併、排序。覆蓋reduce函式,接收的是分組後的資料,實現自己的業務邏輯 -  <hello,2> <me,1> <you,1> 處理後,產生新的<k,v>輸出。
  8. 對reduce輸出的<k,v>寫到HDFS中。

MapReduce原理總結

原語通常由若干條指令組成,用來實現某個特定的操作。通過一段不可分割的或不可中斷的程式實現其功能。且常駐記憶體。但是這樣一來,如果原語執行需要的開銷超過了機器能給予的開銷,則該原語在機器上無法執行,通常解決該問題的辦法是增加機器配置,但計算機的配置在上層每提升一點所需要的資金都是翻倍的。因此根據分散式檔案系統的原理,MapReduce誕生了。它將原語分成了兩個步驟即map()和reduce(),同時兩個階段還可以分成多個模組在不同的機器上執行。

開始學習

  1. 上傳hadoop.tar.gz到伺服器並解壓

  1. 配置hadoop環境變數
vi /etc/prifile
複製程式碼

新增配置

export HADOOP_HOME="/opt/modules/hadoop-2.8.0"
export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH
複製程式碼

執行:

source /etc/profile
複製程式碼

使得配置生效,並驗證引數

echo ${HADOOP_HOME}
複製程式碼

  1. 配置 hadoop-env.shmapred-env.sh、yarn-env.sh檔案的JAVA_HOME引數

修改JAVA_HOME引數為java的安裝路徑

如何檢視java安裝路徑:

4.配置core-site.xml

以下操作都是在hadoop解壓後的目錄中操作

vi etc/hadoop/core-site.xml
複製程式碼

其中:

  • fs.defaultFS - 配置的是hdfs的地址,又為預設檔案系統的名稱。一個URI,其方案和許可權決定了FileSystem的實現。uri的方案確定命名FileSystem實現類的config屬性(fs.SCHEME.impl)。 uri的許可權用於確定檔案系統的主機,埠等。 如果是本地模式,該配置可以如下:
<configuration>
  <property>
    <name>fs.defaultFS</name>
    <value>hdfs://localhost:9000</value>
  </property>
</configuration>
複製程式碼

如果是全分佈模式配置,該配置可以如下:

<configuration>
  <property>
    <name>fs.defaultFS</name>
    <value>hdfs://master:9000</value>
  </property>
  <property>
    <name>io.file.buffer.size</name>
    <value>131072</value>
  </property>
  <property>
    <name>hadoop.tmp.dir</name>
    <value>file:/home/hadoop/tmp</value>
  </property>
  <property>
    <name>hadoop.proxyuser.hduser.hosts</name>
    <value>*</value>
  </property>
  <property>
    <name>hadoop.proxyuser.hduser.groups</name>
    <value>*</value>
  </property>
</configuration>
複製程式碼
  • hadoop.tmp.dir - 配置的是Hadoop臨時目錄,比如HDFS的NameNode資料預設都存放這個目錄下,檢視*-default.xml等預設配置檔案,就可以看到很多依賴${hadoop.tmp.dir}的配置。預設的hadoop.tmp.dir是/tmp/hadoop-${user.name},此時有個問題就是NameNode會將HDFS的元資料儲存在這個/tmp目錄下,如果作業系統重啟了,系統會清空/tmp目錄下的東西,導致NameNode元資料丟失,是個非常嚴重的問題,所有我們應該修改這個路徑。

更多配置屬性介紹可以檢視這裡

5.配置hdfs-site.xml

vi etc/hadoop/hdfs-site.xml
複製程式碼

dfs.replication - 配置的是HDFS儲存時的備份數量,因為這裡是偽分散式環境只有一個節點,所以這裡設定為1。

  1. 格式化hdfs
hdfs namenode -format
複製程式碼

格式化是對HDFS這個分散式檔案系統中的DataNode進行分塊,統計所有分塊後的初始元資料的儲存在NameNode中。格式化後,檢視core-site.xml裡hadoop.tmp.dir(本例是/opt/data目錄)指定的目錄下是否有了dfs目錄,如果有,說明格式化成功。

ll /opt/data/tmp
複製程式碼

注意:

  • 格式化時,這裡注意hadoop.tmp.dir目錄的許可權問題,應該hadoop普通使用者有讀寫許可權才行,可以將/opt/data的所有者改為hadoop。
sudo chown -R hadoop:hadoop /opt/data
複製程式碼

檢視NameNode格式化後的目錄

ll /opt/data/tmp/dfs/name/current
複製程式碼

  • fsimage - 是NameNode元資料在記憶體滿了後,持久化儲存到的檔案。
  • fsimage*.md5 - 是校驗檔案,用於校驗fsimage的完整性。
  • seen_txid - 是hadoop的版本
  • VERSSION - 檔案中儲存著namespaceID:NameNode的唯一ID。clusterID:叢集ID,NameNode和DataNode的叢集ID應該一致,表明是一個叢集。

  1. 啟動namenode、datanode、secondarynamenode

並通過jps命令檢視是否啟動

  1. hdfs上測試建立目錄、上傳、下載檔案
  • 建立目錄
hdfs dfs -mkdir /demol
複製程式碼

通過hdfs建立的目錄我們直接用ls是檢視不到的,此時可以使用以下命令檢視

hdfs dfs -ls /
複製程式碼

  • 上傳本地檔案到HDFS上
hdfs dfs -put {本地檔案路徑} /demol
複製程式碼

這裡我遇到了一個問題,上傳的時候提示我datanode沒有啟動,後來我用jps命令查看了發現datanode自動關閉了,這個問題的原因是因為datanode的clusterID 和 namenode的clusterID 不匹配。

解決辦法,檢查hdfs-site.xml和core-site.xml的配置,如果沒有錯誤,則檢視tmp/dfs下的name和data的VERISON中的叢集id是否匹配,如果不匹配則刪除datanode中current下的檔案然後重新啟動;或者直接修改叢集id

  • 下載檔案到本地
hdfs dfs -get {HDFS檔案路徑} 
複製程式碼

  1. 配置mapred-site.xml,yarn-site.xml

預設沒有mapred-site.xml檔案,但是有個mapred-site.xml.template配置模板檔案。複製模板生成mapred-site.xml

cp etc/hadoop/mapred-site.xml.template etc/hadoop/mapred-site.xml 
複製程式碼

新增配置如下:

<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
複製程式碼

指定mapreduce執行在yarn框架上。

配置yarn-site.xml,新增配置如下:

<property>
  <name>yarn.nodemanager.aux-services</name>
  <value>mapreduce_shuffle</value>
</property>
<property>
    <name>yarn.resourcemanager.hostname</name>
    <value>0.0.0.0</value>
</property>
複製程式碼
  • yarn.nodemanager.aux-services配置了yarn的預設混洗方式,選擇為mapreduce的預設混洗演算法。
  • yarn.resourcemanager.hostname指定了Resourcemanager執行在哪個節點上。

更多屬性檢視

  1. 啟動resourcemanager、nodemanager
yarn-daemon.sh start resourcemanager
yarn-daemon.sh start nodemanager
複製程式碼

通過jsp檢視是否成功開啟

  1. 執行MapReduce Job

在hadoop的share目錄裡,自帶了一些jar包,裡面帶有一些mapreduce例項的小例子,位置在share/hadoop/mapreduce/hadoop-mapreduce-examples-2.5.0.jar,這裡執行一個經典的單詞統計例項

建立測試用的input檔案

建立輸入目錄並將檔案上傳上去

hdfs dfs -mkdir -p /wordcount/input
hdfs dfs -put /opt/data/wc.input /wordcount/input
複製程式碼

執行wordcount mapreduce job

yarn jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.8.0.jar wordcount /wordcount/input /wordcount/output
複製程式碼

檢視結果目錄

hdfs dfs -ls /wordcount/output
複製程式碼

  • output目錄中有兩個檔案,_SUCCESS檔案是空檔案,有這個檔案說明Job執行成功。

  • part-r-00000檔案是結果檔案,其中-r-說明這個檔案是Reduce階段產生的結果,mapreduce程式執行時,可以沒有reduce階段,但是肯定會有map階段,如果沒有reduce階段這個地方有是-m-。

  • 一個reduce會產生一個part-r-開頭的檔案。

檢視結果檔案

總結

  • hdfs - 負責大資料檔案的儲存,檔案儲存為hadoop二進位制檔案,無法被直接檢視,保證了安全性。其中的目錄相當於虛擬目錄。
  • yarn - 一個任務排程框架,mapreduce在它上面執行。同時它還可以執行storm,spark等
  • mapreduce - 計算框架,給出資料處理方案,然後通過yarn在多臺機器上執行,如果將每臺機器看作一個CPU,那麼該程式編寫過程中要求能支援並行且不會導致資料混亂。