hadoop 核心概念及入門
Hadoop
Hadoop背景
什麼是HADOOP
HADOOP是apache旗下的一套開源軟體平臺HADOOP提供利用伺服器叢集,根據使用者的自定義業務邏輯,對海量資料進行分散式處理,HADOOP的核心元件有:HDFS(分散式檔案系統)、YARN(運算資源排程系統)、MAPREDUCE(分散式運算程式設計框架),廣義上來說,HADOOP通常是指一個更廣泛的概念——HADOOP生態圈
HADOOP產生背景
HADOOP最早起源於Nutch。Nutch的設計目標是構建一個大型的全網搜尋引擎,包括網頁抓取、索引、查詢等功能,但隨著抓取網頁數量的增加,遇到了嚴重的可擴充套件性問題——如何解決數十億網頁的儲存和索引問題。2003年、2004年穀歌發表的兩篇論文為該問題提供了可行的解決方案。——分散式檔案系統(GFS),可用於處理海量網頁的儲存——分散式計算框架MAPREDUCE,可用於處理海量網頁的索引計算問題。Nutch的開發人員完成了相應的開源實現HDFS和MAPREDUCE,並從Nutch中剝離成為獨立專案HADOOP,到2008年1月,HADOOP成為Apache頂級專案,迎來了它的快速發展期。
HADOOP在大資料、雲端計算中的位置和關係
雲端計算是分散式計算、平行計算、網格計算、多核計算、網路儲存、虛擬化、負載均衡等傳統計算機技術和網際網路技術融合發展的產物。藉助IaaS(基礎設施即服務)、PaaS(平臺即服務)、SaaS(軟體即服務)等業務模式,把強大的計算能力提供給終端使用者。
現階段,雲端計算的兩大底層支撐技術為“虛擬化”和“大資料技術”
而HADOOP則是雲端計算的PaaS層的解決方案之一,並不等同於PaaS,更不等同於雲端計算本身。
HADOOP生態圈以及各組成部分的簡介
- HDFS:分散式檔案系統
- MAPREDUCE:分散式運算程式開發框架
- HIVE:基於大資料技術(檔案系統+運算框架)的SQL資料倉庫工具
- HBASE:基於HADOOP的分散式海量資料庫
- ZOOKEEPER:分散式協調服務基礎元件
- Mahout:基於mapreduce/spark/flink等分散式運算框架的機器學習演算法庫
- Oozie:工作流排程框架
- Sqoop:資料匯入匯出工具
- Flume:日誌資料採集框架
分散式系統概述
注:由於大資料技術領域的各類技術框架基本上都是分散式系統,因此,理解hadoop、storm、spark等技術框架,都需要具備基本的分散式系統概念
什麼是分散式
分散式系統是由一組通過網路進行通訊、為了完成共同的任務而協調工作的計算機節點組成的系統。分散式系統的出現是為了用廉價的、普通的機器完成單個計算機無法完成的計算、儲存任務。其目的是利用更多的機器,處理更多的資料 。分散式系統的特點是:硬體獨立,各裝置之間獨立,互不依賴、 軟體統一,對使用者來說,就像是跟單個系統打交道。
為什麼需要分散式
為了效能擴充套件:系統負載高,單臺機器無法承受,希望通過多臺機器來提高系統負載能力 為了增強可靠性:軟體不是完美的,網路不是完美的,甚至機器也不是完美的,隨時可能出錯,為了避免故障,需要將業務分散開保留一定的冗餘度
分散式軟體系統(Distributed Software Systems)
該軟體系統會劃分成多個子系統或模組,各自執行在不同的機器上,子系統或模組之間通過網路通訊進行協作,實現最終的整體功能
比如分散式作業系統、分散式程式設計語言及其編譯(解釋)系統、分散式檔案系統和分散式資料庫系統等。
分散式軟體系統舉例:solrcloud
一個solrcloud叢集通常有多臺solr伺服器
每一個solr伺服器節點負責儲存整個索引庫的若干個shard(資料分片)
每一個shard又有多臺伺服器存放若干個副本互為主備用
索引的建立和查詢會在整個叢集的各個節點上併發執行
solrcloud叢集作為整體對外服務,而其內部細節可對客戶端透明
總結:利用多個節點共同協作完成一項或多項具體業務功能的系統就是分散式系統。
為什麼使用分散式
- 單機處理能力存在瓶頸;
- 升級單機處理能力的價效比越來越低;
- 分散式系統穩定性、可用性好
離線資料分析流程介紹
注:本環節主要感受資料分析系統的巨集觀概念及處理流程,初步理解hadoop等框架在其中的應用環節,不用過於關注程式碼細節
web日誌資料探勘
“Web點選流日誌”包含著網站運營很重要的資訊,通過日誌分析,我們可以知道網站的訪問量,哪個網頁訪問人數最多,哪個網頁最有價值,廣告轉化率、訪客的來源資訊,訪客的終端資訊等。
日誌來源
本案例的資料主要由使用者的點選行為記錄
獲取方式:在頁面預埋一段js程式,為頁面上想要監聽的標籤繫結事件,只要使用者點選或移動到標籤,即可觸發ajax請求到後臺servlet程式,用log4j記錄下事件資訊,從而在web伺服器(nginx、tomcat等)上形成不斷增長的日誌檔案。
形如:
58.215.204.118 - - [18/Sep/2013:06:51:35 +0000] "GET /wp-includes/js/jquery/jquery.js?ver=1.10.2 HTTP/1.1" 304 0 "http://blog.fens.me/nodejs-socketio-chat/" "Mozilla/5.0 (Windows NT 5.1; rv:23.0) Gecko/20100101 Firefox/23.0"
流程解釋
- 資料採集:定製開發採集程式,或使用開源框架FLUME
- 資料儲存:你用hDFS分散式檔案處理海量資料
- 資料預處理:定製開發mapreduce程式運行於hadoop叢集
- 資料倉庫技術:基於hadoop之上的Hive
- 資料匯出:基於hadoop的sqoop資料匯入匯出工具
- 資料視覺化:定製開發web程式或使用kettle等產品
- 整個過程的流程排程:hadoop生態圈中的oozie工具或其他類似開源產品
hadoop叢集搭建
叢集簡介
HADOOP叢集具體來說包含兩個叢集:HDFS叢集和YARN叢集,兩者邏輯上分離,但物理上常在一起
- HDFS叢集:負責海量資料的儲存,叢集中的角色主要有 NameNode / DataNode
- YARN叢集:負責海量資料運算時的資源排程,叢集中的角色主要有 ResourceManager /NodeManager(那mapreduce是什麼呢?它其實是一個應用程式開發包)
伺服器分配
本叢集搭建案例,以5節點為例進行搭建,角色分配如下:
節點 | 程序 |
---|---|
node-1 | NameNode SecondaryNameNode |
node-2 | ResourceManager |
node-3 | DataNode NodeManager |
node-4 | DataNode NodeManager |
node-5 | DataNode NodeManager |
伺服器系統配置
配置系統網路,安裝常用依賴包如檔案上傳、編輯器、網路工具
同步時間、配置各主機名稱對映、配置ssh免密登陸
安裝java環境
hadoop叢集安裝部署
上傳HADOOP安裝包並解壓
規劃安裝目錄 /export/servers/hadoop-2.7.7/
修改配置檔案 $HADOOP_HOME/etc/hadoop/
$ vi /etc/profile
export HADOOP_HOME=/export/servers/hadoop2.7.7
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
$ vi hadoop-env.sh
export JAVA_HOME=/usr/local//jdk1.8.0_191
$ vi core-site.xml
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://hdp-node-01:9000</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/home/HADOOP/apps/hadoop-2.6.1/tmp</value>
</property>
</configuration>
$ vi hdfs-site.xml
<configuration>
<property>
<name>dfs.namenode.name.dir</name>
<value>/home/hadoop/data/name</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>/home/hadoop/data/data</value>
</property>
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
<property>
<name>dfs.secondary.http.address</name>
<value>hdp-node-01:50090</value>
</property>
</configuration>
$ vi mapred-site.xml
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
</configuration>
$ vi yarn-site.xml
<configuration>
<property>
<name>yarn.resourcemanager.hostname</name>
<value>node-1</value>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
</configuration>
$ vi salves
node-3
node-4
node-5
啟動hadoop叢集
初始化HDFS
$HADOOP_HOME/sbin/hadoop namenode -format
啟動HDFS
$HADOOP_HOME/sbin/start-dfs.sh
啟動YARN
$HADOOP_HOME/sbin/start-yarn.sh
啟動所有
$HADOOP_HOME/sbin/start-all.sh
測試hadoop叢集
hdfs 常用操作
hadoop常用命令
# 檢視hadoop版本
$ hadoop verion
# 執行jar檔案
$ hadoop jar
# 建立資料夾
$ hadoop fs -mkdir -p /data/input
# 遞迴檢視資料夾
$ hadoop fs -ls -R /data/input
# 上傳本地檔案到HDFS
$ hadoop fs -put /root/words.txt /data/input
# 檢視HDFS上的檔案
$ hadoop fs -cat /data/input/words.txt
# 刪除HDFS上的檔案
$ hadoop fs -rm -f /data/input/words.txt
執行一個mapreduce程式
在hadoop安裝目錄下,執行一個示例mr程式
$ cd $HADOOP_HOME/share/hadoop/mapreduce/
$ hadoop jar hadoop-mapreduce-examples-2.7.7.jar wordcount /data/input /data/output
叢集使用初步
可開啟web控制檯檢視HDFS叢集資訊,在瀏覽器開啟http:/node-1:50070/
MAPREDUCE使用
- mapreduce是hadoop中的分散式運算程式設計框架,只要按照其程式設計規範,只需要編寫少量的業務邏輯程式碼即可實現一個強大的海量資料併發處理程式
HDFS詳解
HDFS前言
設計思想
- 分而治之:將大檔案、大批量檔案,分散式存放在大量伺服器上,以便於採取分而治之的方式對海量資料進行運算分析;
在大資料系統中作用:
- 為各類分散式運算框架(如:mapreduce,spark,tez,……)提供資料儲存服務
重點概念
- 檔案切塊,副本存放,元資料
HDFS的概念和特性
首先,它是一個檔案系統,用於儲存檔案,通過統一的名稱空間——目錄樹來定位檔案
其次,它是分散式的,由很多伺服器聯合起來實現其功能,叢集中的伺服器有各自的角色;
- 重要特性如下:
HDFS中的檔案在物理上是分塊儲存(block),塊的大小可以通過配置引數( dfs.blocksize)來規定,預設大小在hadoop2.x版本中是128M,老版本中是64M
HDFS檔案系統會給客戶端提供一個統一的抽象目錄樹,客戶端通過路徑來訪問檔案,形如:hdfs://host:port/xxx/xxx/file.data
目錄結構及檔案分塊資訊(元資料)的管理由namenode節點承擔
——namenode是HDFS叢集主節點,負責維護整個hdfs檔案系統的目錄樹,以及每一個路徑(檔案)所對應的block塊資訊(block的id,及所在的datanode伺服器)檔案的各個block的儲存管理由datanode節點承擔
---- datanode是HDFS叢集從節點,每一個block都可以在多個datanode上儲存多個副本(副本數量也可以通過引數設定dfs.replication)HDFS是設計成適應一次寫入,多次讀出的場景,且不支援檔案的修改
(注:適合用來做資料分析,並不適合用來做網盤應用,因為,不便修改,延遲大,網路開銷大,成本太高)
HDFS常用命令
* dfs == hadoop fs
* dfs -mkdir /xxx //在hdfs上建立目錄
* dfs -ls -r /xxx //顯示目錄資訊
* dfs -lsr /xxx //遞迴檢視HDFS目錄檔案
* dfs -put a.html /xxx //等同於copyFromLocal
* dfs -get /xxx/a.html //等同於copyToLocal,就是從hdfs下載檔案到本地
* dfs -rm -r -f /data //刪除資料夾下所有檔案
* dfs -cat /xxx/a.txt //顯示檔案內容
* dfs -moveFromLocal //從本地剪下貼上到hdfs
* dfs -moveToLocal //從hdfs剪下貼上到本地
* dfs -appendToFile //追加一個檔案到已經存在的檔案末尾
* dfs -tail //顯示一個檔案的末尾
* dfs -cp //從hdfs的一個路徑拷貝hdfs的另一個路徑
* dfs -mv //從hdfs的一個路徑拷貝hdfs的另一個路徑
* dfs -rm //刪除檔案或資料夾
* version
HSFS原理
hdfs工作機制
(工作機制的學習主要是為加深對分散式系統的理解,以及增強遇到各種問題時的分析解決能力,形成一定的叢集運維能力)
注:很多不是真正理解hadoop技術體系的人會常常覺得HDFS可用於網盤類應用,但實際並非如此。要想將技術準確用在恰當的地方,必須對技術有深刻的理解
- 概述
- HDFS叢集分為兩大角色:NameNode、DataNode (Secondary Namenode)
- NameNode負責管理整個檔案系統的元資料
- DataNode 負責管理使用者的檔案資料塊
- 檔案會按照固定的大小(blocksize)切成若干塊後分布式儲存在若干臺datanode上
- 每一個檔案塊可以有多個副本,並存放在不同的datanode上
- Datanode會定期向Namenode彙報自身所儲存的檔案block資訊,而namenode則會負責保持檔案的副本數量
- HDFS的內部工作機制對客戶端保持透明,客戶端請求訪問HDFS都是通過向namenode申請來進行
HDFS上傳檔案的步驟
客戶端要向HDFS寫資料,首先要跟namenode通訊以確認可以寫檔案並獲得接收檔案block的datanode,然後,客戶端按順序將檔案逐個block傳遞給相應datanode,並由接收到block的datanode負責向其他datanode複製block的副本
- 根namenode通訊請求上傳檔案,namenode檢查目標檔案是否已存在,父目錄是否存在
- namenode返回是否可以上傳
- client請求第一個 block該傳輸到哪些datanode伺服器上
- namenode返回3個datanode伺服器ABC
- client請求3臺dn中的一臺A上傳資料(本質上是一個RPC呼叫,建立pipeline),A收到請求會繼續調
- 然後B呼叫C,將真個pipeline建立完成,逐級返回客戶端
- client開始往A上傳第一個block(先從磁碟讀取資料放到一個本地記憶體快取),以packet為單位,A收到一個packet就會傳給B,B傳給C;A每傳一個packet會放入一個應答佇列等待應答
- 當一個block傳輸完成之後,client再次請求namenode上傳第二個block的伺服器。
HDFS 讀資料流程
客戶端將要讀取的檔案路徑傳送給namenode,namenode獲取檔案的元資訊(主要是block的存放位置資訊)返回給客戶端,客戶端根據返回的資訊找到相應datanode逐個獲取檔案的block並在客戶端本地進行資料追加合併從而獲得整個檔案
- 跟namenode通訊查詢元資料,找到檔案塊所在的datanode伺服器
- 挑選一臺datanode(就近原則,然後隨機)伺服器,請求建立socket流
- datanode開始傳送資料(從磁盤裡面讀取資料放入流,以packet為單位來做校驗)
- 客戶端以packet為單位接收,現在本地快取,然後寫入目標檔案
namenode工作機制
namenode職責
負責客戶端請求的響應,元資料的管理(查詢,修改)
元資料管理
namenode對資料的管理採用了三種儲存形式:
- 記憶體元資料(NameSystem)
- 磁碟元資料映象檔案
- 資料操作日誌檔案(可通過日誌運算出元資料)
元資料儲存機制
記憶體中有一份完整的元資料(記憶體meta data)
磁碟有一個“準完整”的元資料映象(fsimage)檔案(在namenode的工作目錄中
用於銜接記憶體metadata和持久化元資料映象fsimage之間的操作日誌(edits檔案)
注:當客戶端對hdfs中的檔案進行新增或者修改操作,操作記錄首先被記入edits日誌檔案中,當客戶端操作成功後,相應的元資料會更新到記憶體meta.data中
元資料手動檢視
- 可以通過hdfs的一個工具來檢視edits中的資訊
- bin/hdfs oev -i edits -o edits.xml
- bin/hdfs oiv -i fsimage_0000000000000000087 -p XML -o fsimage.xml
元資料的checkpoint
每隔一段時間,會由secondary namenode將namenode上積累的所有edits和一個最新的fsimage下載到本地,並載入到記憶體進行merge(這個過程稱為checkpoint)
元資料目錄說明
在第一次部署好Hadoop叢集的時候,我們需要在NameNode(NN)節點上格式化磁碟:
$HADOOP_HOME/bin/hdfs namenode -format
格式化完成之後,將會在$dfs.namenode.name.dir/current目錄下如下的檔案結構
current/
|-- VERSION
|-- edits_*
|-- fsimage_0000000000008547077
|-- fsimage_0000000000008547077.md5
|-- seen_txid
其中的dfs.name.dir是在hdfs-site.xml檔案中配置的,預設值如下:
<property>
<name>dfs.name.dir</name>
<value>file://${hadoop.tmp.dir}/dfs/name</value>
</property>
hadoop.tmp.dir是在core-site.xml中配置的,預設值如下
<property>
<name>hadoop.tmp.dir</name>
<value>/tmp/hadoop-${user.name}</value>
<description>A base for other temporary directories.</description>
</property>
dfs.namenode.name.dir屬性可以配置多個目錄,
如/data1/dfs/name,/data2/dfs/name,/data3/dfs/name,....。各個目錄儲存的檔案結構和內容都完全一樣,相當於備份,這樣做的好處是當其中一個目錄損壞了,也不會影響到Hadoop的元資料,特別是當其中一個目錄是NFS(網路檔案系統Network File System,NFS)之上,即使你這臺機器損壞了,元資料也得到儲存。
下面對$dfs.namenode.name.dir/current/目錄下的檔案進行解釋。
1、VERSION檔案是Java屬性檔案,內容大致如下:
#Fri Nov 15 19:47:46 CST 2013
namespaceID=934548976
clusterID=CID-cdff7d73-93cd-4783-9399-0a22e6dce196
cTime=0
storageType=NAME_NODE
blockpoolID=BP-893790215-192.168.24.72-1383809616115
layoutVersion=-47
其中
(1).namespaceID是檔案系統的唯一識別符號,在檔案系統首次格式化之後生成的;
(2).storageType說明這個檔案儲存的是什麼程序的資料結構資訊(如果是DataNode,storageType=DATA_NODE);
(3).cTime表示NameNode儲存時間的建立時間,由於我的NameNode沒有更新過,所以這裡的記錄值為0,以後對NameNode升級之後,cTime將會記錄更新時間戳;
(4).layoutVersion表示HDFS永久性資料結構的版本資訊, 只要資料結構變更,版本號也要遞減,此時的HDFS也需要升級,否則磁碟仍舊是使用舊版本的資料結構,這會導致新版本的NameNode無法使用;
(5).clusterID是系統生成或手動指定的叢集ID,在-clusterid選項中可以使用它;如下說明
a、使用如下命令格式化一個Namenode:
$HADOOP_HOME/bin/hdfs namenode -format [-clusterId <cluster_id>]
選擇一個唯一的cluster_id,並且這個cluster_id不能與環境中其他叢集有衝突。如果沒有提供cluster_id,則會自動生成一個唯一的ClusterID。
b、使用如下命令格式化其他Namenode:
`$HADOOP_HOME/bin/hdfs namenode -format -clusterId <cluster_id>`
c、升級叢集至最新版本。在升級過程中需要提供一個ClusterID,例如:
$HADOOP_PREFIX_HOME/bin/hdfs start namenode --config $HADOOP_CONF_DIR -upgrade -clusterId <cluster_ID>
如果沒有提供ClusterID,則會自動生成一個ClusterID。
(6).blockpoolID:是針對每一個Namespace所對應的blockpool的ID,上面的這個BP-893790215-192.168.24.72-1383809616115就是在我的ns1的namespace下的儲存塊池的ID,這個ID包括了其對應的NameNode節點的ip地址。
2、$dfs.namenode.name.dir/current/seen_txid非常重要,是存放transactionId的檔案,format之後是0,它代表的是namenode裡面的edits_*檔案的尾數,namenode重啟的時候,會按照seen_txid的數字,循序從頭跑edits_0000001~到seen_txid的數字。所以當你的hdfs發生異常重啟的時候,一定要比對seen_txid內的數字是不是你edits最後的尾數,不然會發生建置namenode時metaData的資料有缺少,導致誤刪Datanode上多餘Block的資訊。
3、$dfs.namenode.name.dir/current目錄下在format的同時也會生成fsimage和edits檔案,及其對應的md5校驗檔案。
補充:seen_txid
檔案中記錄的是edits滾動的序號,每次重啟namenode時,namenode就知道要將哪些edits進行載入edits
DATANODE的工作機制
概述
- Datanode工作職責:
儲存管理使用者的檔案塊資料
定期向namenode彙報自身所持有的block資訊(通過心跳資訊上報)
(這點很重要,因為,當叢集中發生某些block副本失效時,叢集如何恢復block初始副本數量的問題)
<property> <name>dfs.blockreport.intervalMsec</name> <value>3600000</value> </property>
Datanode掉線判斷時限引數
datanode程序死亡或者網路故障造成datanode無法與namenode通訊,namenode不會立即把該節點判定為死亡,要經過一段時間,這段時間暫稱作超時時長。HDFS預設的超時時長為10分鐘+30秒。如果定義超時時間為timeout,則超時時長的計算公式為:
timeout = 2 * heartbeat.recheck.interval + 10 * dfs.heartbeat.interval。
而預設的heartbeat.recheck.interval 大小為5分鐘,dfs.heartbeat.interval預設為3秒。
需要注意的是hdfs-site.xml 配置檔案中的heartbeat.recheck.interval的單位為毫秒,dfs.heartbeat.interval的單位為秒。所以,舉個例子,如果heartbeat.recheck.interval設定為5000(毫秒),dfs.heartbeat.interval設定為3(秒,預設),則總的超時時間為40秒。<property> <name>heartbeat.recheck.interval</name> <value>2000</value> </property> <property> <name>dfs.heartbeat.interval</name> <value>1</value> </property>
驗證DATANODE功能
- 上傳一個檔案,觀察檔案的block具體的物理存放情況:
在每一臺datanode機器上的這個目錄中能找到檔案的切塊:
/home/hadoop/app/hadoop-2.4.1/tmp/dfs/data/current/BP-193442119-192.168.2.120-1432457733977/current/finalized