您當前的位置:首頁 > 遊戲

大資料基礎【Task 2】搭建Hadoop叢集

作者:由 codingling 發表于 遊戲時間:2019-08-06

任務詳情:

搭建HA的Hadoop叢集並驗證,3節點(1主2從),理解HA/Federation,並截圖記錄搭建過程

閱讀Google三大論文,並總結

Hadoop的作用(解決了什麼問題)/執行模式/基礎元件及架構

學會閱讀HDFS原始碼,並自己閱讀一段HDFS的原始碼(推薦HDFS上傳/下載過程)

Hadoop中各個元件的通訊方式,RPC/Http等

學會寫WordCount(Java/Python-Hadoop Streaming),理解分散式/單機執行模式的區別

理解MapReduce的執行過程

Yarn在Hadoop中的作用

參考資料: Google三大論文

【環境搭建影片】連結:

https://

pan。baidu。com/s/1TmvPBB

MkLah-e_H-UHjuxA

提取碼:iagg

叢集規劃1-省機器:

大資料基礎【Task 2】搭建Hadoop叢集

叢集規劃2-清晰:

大資料基礎【Task 2】搭建Hadoop叢集

1。搭建HA的Hadoop叢集並驗證,3節點(1主2從)

按照叢集規劃1進行。

1.1 修改hostname

上一次我們搭建了三個虛擬機器,我的三個虛擬機器的hostname分別為CP1、CP2、CP5,為了連貫性,我把CP5改成CP3。命令hostname可以檢視當前主機名,hostname CP3可以將主機名修改為CP3。如圖所示:

大資料基礎【Task 2】搭建Hadoop叢集

對應的命令是:

//編輯檔案

vim /etc/sysconfig/network

//修改主機名是CP3,(注意hostname的大小寫)

hostname CP3

//命令列下修改hostname

hostname CP3

此時檢視hostname就會變成CP3:

大資料基礎【Task 2】搭建Hadoop叢集

1.2 建立hostname和ip的對映關係

這一步是為了部署叢集方便。在CP1上修改etc/hosts檔案:

//編輯hosts檔案

vim /etc/hosts

//建立ip和host的對映關係

192。168。1。12 CP1

192。168。1。11 CP2

192。168。1。14 CP3

emmm,忽略我的ip地址的不連貫吧。

大資料基礎【Task 2】搭建Hadoop叢集

同理在CP2、CP3上重複上述過程,檔案內容完全一樣。

1.3 關閉防火牆

在hadoop叢集中會經常發生 機器和機器之間的互動,為了避免因為防火牆產生的意外故障,因此我們需要將防火牆關閉,過程如下:

# 關閉防火牆

systemctl stop firewalld。service #停止firewall

systemctl disable firewalld。service #禁止firewall開機啟動

firewall-cmd ——state ##檢視防火牆狀態,是否是running

大資料基礎【Task 2】搭建Hadoop叢集

狀態從running變成了not running。

1.4 配置叢集SSH免密碼登入

首先要在三臺機器上配置對本機的ssh免密碼登入,然後是配置三臺機器之間的ssh免密碼登入。

對於CP1、CP2和CP3,都執行如下操作(配置對本機的ssh免密碼登入):

//建立金鑰,一直點確定到結束,預設將公鑰放在/root/。ssh目錄下

ssh-keygen -t rsa

//將公鑰複製為authorized_keys檔案,此時使用ssh連線本機就不需要輸入密碼了

cd /root/。ssh/

cp id_rsa。pub authorized_keys

然後就可以透過ssh連線了:

大資料基礎【Task 2】搭建Hadoop叢集

然後配置三臺機器之間的ssh免密碼登入,針對CP1,執行如下命令:

//將本機公鑰複製到指定機器的authorized_keys檔案中

ssh-copy-id -i CP2

根據提示依次輸入yes和CP2的登入密碼即可。然後可以嘗試ssh CP2,ssh登入機器CP2:

大資料基礎【Task 2】搭建Hadoop叢集

對CP3也執行上述操作。同樣地,CP2、CP3也要執行上述類似操作。

1.5 hadoop的叢集部署

首先要把本地的hadoop壓縮包上傳到虛擬機器,我們上傳到usr/local資料夾下,因此執行下列命令:

cd /usr/local

rz

rz是工具包lrzsz上傳檔案到虛擬機器的命令,將hadoop檔案上傳過去。

sz:將選定的檔案傳送(send)到本地機器

rz:執行該命令會彈出一個檔案選擇視窗,從本地選擇檔案上傳到伺服器(receive)

然後解壓縮檔案,並重命名:

//解壓hadoop

tar -zxvf hadoop-2。7。3。tar。gz

//將壓縮包刪掉(可選)

rm -rf hadoop-2。7。3。tar。gz

//改名為hadoop

mv hadoop-2。7。3 hadoop

首先,確認一下hadoop下有bin和sbin目錄:

大資料基礎【Task 2】搭建Hadoop叢集

(注意,下方的環境變數請配置在~/.bashrc裡!!!不然可能會出現我遇到的問題)

配置hadoop相關環境變數:

vi /etc/profile //改成 vi ~/。bashrc

原來的內容是這樣的:

export JAVA_HOME=/usr/local/java/jdk1。8。0_131

export CLASSPATH=$JAVA_HOME/lib/

export PATH=$PATH:$JAVA_HOME/bin

修改後的內容是這樣的:

export JAVA_HOME=/usr/local/java/jdk1。8。0_131

export HADOOP_HOME=/usr/local/hadoop

export CLASSPATH=$JAVA_HOME/lib/

export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin

執行命令使之生效:

source /etc/profile //改成source ~/。bashrc

分別輸入下列命令檢檢視看java和hadoop有沒有問題:

大資料基礎【Task 2】搭建Hadoop叢集

大資料基礎【Task 2】搭建Hadoop叢集

大資料基礎【Task 2】搭建Hadoop叢集

建立/usr/local/data目錄:

cd /usr/local

mkdir data

接下來修改hadoop的配置。首先是core-site。xml,在目錄hadoop/etc/hadoop下:

cd hadoop/etc/hadoop

vi core-site。xml

core-site。xml(檔案末尾)的修改內容如下:

fs。default。name

hdfs://CP1:9000

然後是hdfs-site。xml的修改內容:

dfs。name。dir

/usr/local/data/namenode

dfs。data。dir

/usr/local/data/datanode

dfs。tmp。dir

/usr/local/data/tmp

dfs。replication

2

因為我們的主節點是1個,從節點2個,這裡的副本也就設定成2個比較合適。

修改mapred-site。xml。發現目錄下只有一個叫mapred-site。xml。template的檔案,將其重新命名:

mv mapred-site。xml。template mapred-site。xml

然後修改,mapred-site。xml的修改內容:

mapreduce。framework。name

yarn

修改配置檔案yarn-site。xml的內容:

yarn。resourcemanager。hostname

CP1

yarn。nodemanager。aux-services

mapreduce_shuffle

設定從節點的位置

//編輯slaves檔案

vi slaves

//slaves的內容為(刪除預設的localhost):

CP2

CP3

上述操作都是針對CP1的,我們要把CP1的hadoop安裝包和配置檔案都複製過去,然後source配置檔案,使其生效,並且在CP2和CP3下的/usr/local目錄下建立data目錄。

首先cd到local目錄下,該目錄下有hadoop目錄和data目錄。

然後以遞迴的方式將hadoop檔案複製到CP2的/usr/local目錄下:

scp -r hadoop root@CP2:/usr/local

可以把配置檔案~/。bashrc也複製過去,我選擇自己修改。然後在CP2中建立/usr/local/目錄下的data目錄。

對CP3重複上述複製、修改配置檔案、使配置生效、建立data目錄操作。

接下來格式化

NameNode

並啟動叢集

//在CP1上格式化叢集

hdfs namenode -format

//在CP1上啟動叢集

start-dfs。sh

然後出錯了:

大資料基礎【Task 2】搭建Hadoop叢集

網上查了一下,說是還要配置hadoop-env。sh檔案的jAVA_HOME,因為hadoop找不到Java。。。明明/etc/profile都已經配置好了的。。。(可能配置~/。bashrc就不會出這個錯)

沒辦法,cd到目錄/usr/local/hadoop/etc/hadoop下,修改hadoop-env。sh,把java_home引數改成絕對路徑:

cd /usr/local/hadoop/etc/hadoop

vi hadoop-env。sh

// 修改內容

export JAVA_HOME=/usr/local/java/jdk1。8。0_131

同樣地,對CP2、CP3執行相同操作。

再次執行命令start-dfs。sh。

如果出現“namenode running as process XXX stop it first”這樣的錯誤,可以先stop-dfs。sh,再start-dfs。sh。(start-all。sh可以看到更多)

可以用jps命令檢視啟動的情況:

大資料基礎【Task 2】搭建Hadoop叢集

大資料基礎【Task 2】搭建Hadoop叢集

大資料基礎【Task 2】搭建Hadoop叢集

如果用start-all。sh,再輸入jps:

大資料基礎【Task 2】搭建Hadoop叢集

大資料基礎【Task 2】搭建Hadoop叢集

大資料基礎【Task 2】搭建Hadoop叢集

可以在瀏覽器網址欄輸入:虛擬機器ip地址:50070,比如我的是:

192。168。1。12:50070

影片教程裡說主機名:50070可以開啟,但我的一直打不開。

如果上述網址也打不開,可以嘗試下列方法:

vi /etc/selinux/config

//修改

SELINUX=disabled

檢視一些資訊:

大資料基礎【Task 2】搭建Hadoop叢集

可以在Utilities-browse the file system檢視自己的檔案系統,可以看到現在什麼都沒有:

大資料基礎【Task 2】搭建Hadoop叢集

可以嘗試上傳一個檔案。在虛擬機器vi hello。txt,寫入內容,然後執行:

hdfs dfs -put hello。txt /hello。txt

上傳檔案。

然後再看上述介面:

大資料基礎【Task 2】搭建Hadoop叢集

就有了檔案。

下面來啟動yarn叢集。

start-yarn。sh

//檢視yarn叢集啟動情況

jps

//在web上檢視的網址是http://192。168。1。12:8088

1.6貌似不在任務要求裡???。。。偏偏這塊花了挺長時間的....

1.6 安裝hive

同樣地,透過在xshell輸入rz命令將hive壓縮檔案上傳到虛擬機器的/usr/local資料夾下,然後解壓縮,重新命名,修改環境變數:

//解壓縮

tar -zxvf apache-hive-2。1。1-bin。tar。gz

//重新命名

mv apache-hive-2。1。1-bin hive

//修改環境變數

vi ~/。bashrc

修改後的~/。bashrc:

export JAVA_HOME=/usr/local/java/jdk1。8。0_131

export HIVE_HOME=/usr/local/hive

export HADOOP_HOME=/usr/local/hadoop

export PATH=$PATH:$JAVA_HOME/bin:$HIVE_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin

讓配置檔案生效:

source ~/。bashrc

下面來安裝mysql

yum install -y mysql-server

執行上述命令後出現“No package mysql-server available”錯誤,原因是CentOS7帶有MariaDB而不是MySQL,MariaDB和MySQL一樣也是開元的資料庫,可以使用yum -y install mariadb-server mariadb命令安裝。

如果必須要安裝MySQL,首先必須新增mysql社群repo透過輸入命令:

sudo rpm -Uvh http://dev。mysql。com/get/mysql-community-release-el7-5。noarch。rpm

最後使用像安裝MySQL的常規方法一樣安裝mysql:

yum install mysql mysql-server mysql-libs mysql-server

安裝過程中,出現“No more mirrors to try”錯誤,執行下列命令:

yum clean all

yum makecache

再重新安裝。這個移動的網速真的太渣了!

從下午5點到凌晨1點,除去中間吃飯洗澡的時間,大概花了6個小時,就做了這麼一點。。。

安裝完成之後,啟動mysql服務:

service mysqld start

配置程序隨著機器啟動:

chkconfig mysqld on

安裝mysql-connector-java驅動包

yum install -y mysql-connector-java

將mysql connector複製到hive的lib包中,這樣hive才能用mysql驅動包來連線mysql資料庫,作為它的元資料庫(可以到/usr/share/java目錄下檢視檔名)

cp /usr/share/java/mysql-connector-java。jar /usr/local/hive/lib

在mysql上建立hive元資料庫,建立hive賬號並進行授權。先輸入mysql進入mysql,再輸入下列命令:

create database if not exists hive_metadata;

grant all privileges on hive_metadata。* to ‘hive’@‘%’ identified by ‘hive’;

grant all privileges on hive_metadata。* to ‘hive’@‘localhost’ identified by ‘hive’;

grant all privileges on hive_metadata。* to ‘hive’@‘CP1’ identified by ‘hive’;

flush privileges;

use hive_metadata;

輸入exit退出mysql。

配置hive-site。xml:

首先進入/usr/local/hive/conf目錄,重新命名檔案:

mv hive-default。xml。template hive-site。xml

修改配置檔案hive-site。xml的內容。由於檔案內容太多,我們將其上傳到本地機器,用文字編輯器開啟進行編輯:

sz hive-site。xml

會彈出一個文字框,選擇一個儲存位置即可。

然後修改:

javax。jdo。option。ConnectionURL

jdbc:mysql://CP1:3306/hive_metadata?createDatabaseIfNotExist=true

javax。jdo。option。ConnectionDriverName

com。mysql。jdbc。Driver

javax。jdo。option。ConnectionUserName

hive

javax。jdo。option。ConnectionPassword

hive

可以使用查詢功能,找到上面的name中的內容,修改value的值。

然後用rz命令上傳修改後的檔案到虛擬機器(注意要先刪除虛擬機器上的檔案rm -rf,否則無法上傳成功)。

配置其它檔案:

//重新命名

mv hive-env。sh。template hive-env。sh

//修改hive-config。sh

vi /usr/local/hive/bin/hive-config。sh

//新增內容

export JAVA_HOME=/usr/local/java/jdk1。8。0_131

export HIVE_HOME=/usr/local/hive

export HADOOP_HOME=/usr/local/hadoop

測試 hive是否安裝成功

大資料基礎【Task 2】搭建Hadoop叢集

第一個錯誤是因為上述jar包有重複繫結Logger類,刪除較舊版本即可。

rm -rf /usr/local/hadoop/share/hadoop/common/lib/slf4j-log4j12-1。7。10。jar

第二個錯誤是因為沒有正常啟動Hive 的 Metastore Server服務程序。 執行如下命令:

hive ——service metastore &

然後又出錯:

大資料基礎【Task 2】搭建Hadoop叢集

修改conf/hive-site。xml 中的 “hive。metastore。schema。verification” 值為 false:

hive。metastore。schema。verification

false

Enforce metastore schema version consistency。

True: Verify that version information stored in is compatible with one from Hive jars。 Also disable automatic

schema migration attempt。 Users are required to manually migrate schema after Hive upgrade which ensures

proper metastore schema migration。 (Default)

False: Warn if the version information stored in metastore doesn‘t match with one from in Hive jars。

但是還有錯:

大資料基礎【Task 2】搭建Hadoop叢集

需要 使用 schematool工具初始化hive的 元素,執行:

schematool -initSchema -dbType mysql

居然還有錯:

大資料基礎【Task 2】搭建Hadoop叢集

執行下列步驟:

mkdir tmpdir

將conf/hive-site。xml中的所有的“${system:java。io。tmpdir}”修改為“/usr/local/hive/tmpdir/”。

大資料基礎【Task 2】搭建Hadoop叢集

終於!!!

大資料基礎【Task 2】搭建Hadoop叢集

我們可以嘗試一下匯入txt檔案到hive表。

先退出hive(exit;),在/usr/local目錄下新建users。txt,內容如下:

大資料基礎【Task 2】搭建Hadoop叢集

然後在hive裡依次輸入:

create table users(id int, name string);

load data local inpath ’/usr/local/users。txt‘ into table users;

select name from users;

大資料基礎【Task 2】搭建Hadoop叢集

emmm,不知道為什麼,這個問題先留著吧,反正是hive語法的問題,應該不是環境部署的問題。

1.7 安裝zookeeper

用rz命令將壓縮包上傳到虛擬機器的/usr/local目錄下,然後:

tar -zxvf zookeeper-3。4。10。tar。gz

rm -rf zookeeper-3。4。10。tar。gz

mv zookeeper-3。4。10 zk

//修改配置檔案

vi ~/。bashrc

//修改後的內容

export JAVA_HOME=/usr/local/java/jdk1。8。0_131

export HIVE_HOME=/usr/local/hive

export HADOOP_HOME=/usr/local/hadoop

export ZOOKEEPER_HOME=/usr/local/zk

export PATH=$PATH:$JAVA_HOME/bin:$HIVE_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$ZOOKEEPER_HOME/bin

//使配置生效

source ~/。bashrc

配置zoo。cfg

cd zk/conf

mv zoo_sample。cfg zoo。cfg

vi zoo。cfg

//修改內容

dataDir=/usr/local/zk/data

//新增,需要3個結點以上,而且是奇數

server。0=CP1:2888:3888

server。1=CP2:2888:3888

server。2=CP3:2888:3888

然後設定zk節點標識

//進入zk目錄

cd 。。

mkdir data

cd data

vi myid

//myid的內容

0

搭建zk叢集,在另外兩個節點上按照上述步驟配置ZooKeeper,使用scp將zk和。bashrc複製到CP2和CP3上即可。

唯一的區別是CP2和CP3上的標識號分別設定為1和2。

//進入local

cd 。。

scp -r zk root@CP2:/usr/local

scp ~/。bashrc root@CP2:~/

複製之後,去CP2檢查一下有沒有複製成功,並且source配置檔案,將myid的內容改成1

大資料基礎【Task 2】搭建Hadoop叢集

大資料基礎【Task 2】搭建Hadoop叢集

針對CP3重複上述複製、檢查、source、修改myid為2的操作。

啟動ZooKeeper叢集

分別在三臺機器上執行:zkServer。sh start

檢查ZooKeeper狀態:zkServer。sh status

大資料基礎【Task 2】搭建Hadoop叢集

大資料基礎【Task 2】搭建Hadoop叢集

大資料基礎【Task 2】搭建Hadoop叢集

然後用jps在三個機器上看看三個節點是否都有QuorumPeerMain程序:

大資料基礎【Task 2】搭建Hadoop叢集

大資料基礎【Task 2】搭建Hadoop叢集

大資料基礎【Task 2】搭建Hadoop叢集

第一部分所有環境搭建的參考資料:

https://

blog。csdn。net/zxz547388

910/article/details/86468925

https://

blog。csdn。net/LoveCarpe

nter/article/details/78808135

CentOS 7 開啟關閉FirewallD防火牆埠命令

https://

blog。csdn。net/gongchenu

pc/article/details/68066990

Hive環境搭建

https://www。

cnblogs。com/aspirant/p/

6616575。html

2. Google三大論文

看這篇文章吧,寫的很好,由於知識儲備量不夠,暫時無法以自己的語言解釋。。。:

https://

blog。csdn。net/w1573007/

article/details/52966742

3。 Hadoop的作用(解決了什麼問題)/執行模式/基礎元件及架構

Hadoop是一個開源框架,可編寫和執行分散式應用處理大規模資料。 Hadoop框架的核心是HDFS和MapReduce。其中 HDFS 是分散式檔案系統,MapReduce 是分散式資料處理模型和執行環境。

隨著資料的來源途徑越來越多,資料的格式也越來越複雜,資料量越來越大,傳統的資料庫已經很難滿足需求,Hadoop就是為了解決這個問題而誕生的。其底層的分散式檔案系統具有高拓展性,透過資料冗餘保證資料不丟失和提交計算效率,同時可以儲存各種格式的資料。同時其還支援多種計算框架,既可以進行離線計算也可以進行線上實時計算。

Hadoop有三種執行模式:單機模式、偽分散式模式、完全分散式模式。

單機模式

-預設模式。

-不對配置檔案進行修改。

-使用本地檔案系統,而不是分散式檔案系統。

-Hadoop不會啟動NameNode、DataNode、JobTracker、TaskTracker等守護程序,Map()和Reduce()任務作為同一個程序的不同部分來執行的。

-用於對MapReduce程式的邏輯進行除錯,確保程式的正確。

偽分散式模式

-在一臺主機模擬多主機。

-Hadoop啟動NameNode、DataNode、JobTracker、TaskTracker這些守護程序都在同一臺機器上執行,是相互獨立的Java程序。

-在這種模式下,Hadoop使用的是分散式檔案系統,各個作業也是由JobTraker服務,來管理的獨立程序。在單機模式之上增加了程式碼除錯功能,允許檢查記憶體使用情況,HDFS輸入輸出,以及其他的守護程序互動。類似於完全分散式模式,因此,這種模式常用來開發測試Hadoop程式的執行是否正確。

-修改3個配置檔案:core-site。xml(Hadoop叢集的特性,作用於全部程序及客戶端)、hdfs-site。xml(配置HDFS叢集的工作屬性)、mapred-site。xml(配置MapReduce叢集的屬性)

-格式化檔案系統

完全分散式模式

-Hadoop的守護程序執行在由多臺主機搭建的叢集上,是真正的生產環境。

-在所有的主機上安裝JDK和Hadoop,組成相互連通的網路。

-在主機間設定SSH免密碼登入,把各從節點生成的公鑰新增到主節點的信任列表。

-修改3個配置檔案:core-site。xml、hdfs-site。xml、mapred-site。xml,指定NameNode和JobTraker的位置和埠,設定檔案的副本等引數

三種模式的叢集必須配置資訊:

大資料基礎【Task 2】搭建Hadoop叢集

Hadoop的基礎元件

Hadoop1。0的核心由HDFS(Hadoop Distributed File System)和MapReduce(分散式計算框架)構成。而在Hadoop2。0中增加了Yarn(Yet Another Resource Negotiator),來負責叢集資源的統一管理和排程。

大資料基礎【Task 2】搭建Hadoop叢集

參考資料:

https://www。

zybuluo。com/Cesar/note/

239412

https://

blog。csdn。net/u01027040

3/article/details/51493191

https://

blog。csdn。net/u01306315

3/article/details/53115216

https://

blog。csdn。net/qq_264425

53/article/details/78710170

4.學會閱讀HDFS原始碼,並自己閱讀一段HDFS的原始碼(推薦HDFS上傳/下載過程)

原始碼可以在官網下載,我就直接在網上找了相關的文章看啦,參考下方的資料,講的很詳細了。

以檔案上傳為例,其執行過程是這樣的:

FileSystem初始化,Client拿到NameNodeRpcServer代理物件,建立與NameNode的RPC通訊

呼叫FileSystem的create()方法,由於實現類為DistributedFileSystem,所以是呼叫該類中的create()方法

DistributedFileSystem持有DFSClient的引用,繼續呼叫DFSClient中的create()方法

DFSOutputStream提供的靜態newStreamForCreate()方法中呼叫NameNodeRpcServer服務端的create()方法並建立DFSOutputStream輸出流物件返回

透過hadoop提供的IOUtil工具類將輸出流輸出到本地

下面針對這個執行過程來分析原始碼。

1。FileSystem初始化,Client拿到NameNodeRpcServer代理物件,建立與NameNode的RPC通訊(詳情見參考文獻第一篇)

2。呼叫FileSystem的create()方法,由於實現類為DistributedFileSystem,所以是呼叫該類中的create()方法

HDFSDemo。java

OutputStream os = fs。create(new Path(“/test。log”));

這裡呼叫了FileSystem的create()方法,由於FileSystem是一個抽象類,這裡實際上是呼叫的是該類的子類create()方法

//FileSystem。java

public

abstract

FSDataOutputStream

create

Path

f

FsPermission

permission

boolean

overwrite

int

bufferSize

short

replication

long

blockSize

Progressable

progress

throws

IOException

FileSystem。get()返回的是DistributedFileSystem物件,所以這裡我們直接進入DistributedFileSystem

//DistributedFileSystem。java

@Override

public FSDataOutputStream create(final Path f, final FsPermission permission,

final EnumSet cflags, final int bufferSize,

final short replication, final long blockSize, final Progressable progress,

final ChecksumOpt checksumOpt) throws IOException {

statistics。incrementWriteOps(1);

Path absF = fixRelativePart(f);

return new FileSystemLinkResolver() {

@Override

public FSDataOutputStream doCall(final Path p)

throws IOException, UnresolvedLinkException {

final DFSOutputStream dfsos = dfs。create(getPathName(p), permission,

cflags, replication, blockSize, progress, bufferSize,

checksumOpt);

//dfs為DistributedFileSystem所持有的DFSClient物件,這裡呼叫DFSClient中的create()方法

return dfs。createWrappedOutputStream(dfsos, statistics);

}

@Override

public FSDataOutputStream next(final FileSystem fs, final Path p)

throws IOException {

return fs。create(p, permission, cflags, bufferSize,

replication, blockSize, progress, checksumOpt);

}

}。resolve(this, absF);

}

3。DistributedFileSystem持有DFSClient的引用,繼續呼叫DFSClient中的create()方法

DFSClient的create()返回一個DFSOutputStream物件

//DFSClient。java

public DFSOutputStream create(String src,

FsPermission permission,

EnumSet flag,

boolean createParent,

short replication,

long blockSize,

Progressable progress,

int buffersize,

ChecksumOpt checksumOpt,

InetSocketAddress[] favoredNodes) throws IOException {

checkOpen();

if (permission == null) {

permission = FsPermission。getFileDefault();

}

FsPermission masked = permission。applyUMask(dfsClientConf。uMask);

if(LOG。isDebugEnabled()) {

LOG。debug(src + “: masked=” + masked);

}

//呼叫DFSOutputStream的靜態方法newStreamForCreate,返回輸出流

final DFSOutputStream result = DFSOutputStream。newStreamForCreate(this,

src, masked, flag, createParent, replication, blockSize, progress,

buffersize, dfsClientConf。createChecksum(checksumOpt),

getFavoredNodesStr(favoredNodes));

beginFileLease(result。getFileId(), result);

return result;

}

4。DFSOutputStream提供的靜態newStreamForCreate()方法中呼叫NameNodeRpcServer服務端的create()並建立DFSOutputStream輸出流物件返回

newStreamForCreate()中的業務邏輯:

//DFSOutputStream。java

static DFSOutputStream newStreamForCreate(DFSClient dfsClient, String src,

FsPermission masked, EnumSet flag, boolean createParent,

short replication, long blockSize, Progressable progress, int buffersize,

DataChecksum checksum, String[] favoredNodes) throws IOException {

TraceScope scope =

dfsClient。getPathTraceScope(“newStreamForCreate”, src);

try {

HdfsFileStatus stat = null;

boolean shouldRetry = true;

int retryCount = CREATE_RETRY_COUNT;

while (shouldRetry) {

shouldRetry = false;

try {

//這裡透過dfsClient的NameNode代理物件呼叫NameNodeRpcServer中實現的create()方法

stat = dfsClient。namenode。create(src, masked, dfsClient。clientName,

new EnumSetWritable(flag), createParent, replication,

blockSize, SUPPORTED_CRYPTO_VERSIONS);

break;

} catch (RemoteException re) {

IOException e = re。unwrapRemoteException(

AccessControlException。class,

DSQuotaExceededException。class,

FileAlreadyExistsException。class,

FileNotFoundException。class,

ParentNotDirectoryException。class,

NSQuotaExceededException。class,

RetryStartFileException。class,

SafeModeException。class,

UnresolvedPathException。class,

SnapshotAccessControlException。class,

UnknownCryptoProtocolVersionException。class);

if (e instanceof RetryStartFileException) {

if (retryCount > 0) {

shouldRetry = true;

retryCount——;

} else {

throw new IOException(“Too many retries because of encryption” +

“ zone operations”, e);

}

} else {

throw e;

}

}

}

Preconditions。checkNotNull(stat, “HdfsFileStatus should not be null!”);

//new輸出流物件

final DFSOutputStream out = new DFSOutputStream(dfsClient, src, stat,

flag, progress, checksum, favoredNodes);

out。start();//呼叫內部類DataStreamer的start()方法,DataStreamer繼承Thread,所以說這是一個執行緒,從NameNode中申請新的block資訊;

return out;

} finally {

scope。close();

}

}

到此,Client拿到了服務端的輸出流物件,那麼後面就容易了,都是一些簡單的檔案輸出,輸入流的操作(hadoop提供的IOUitl)。

參考 資料:

Hadoop之HDFS原理及檔案上傳下載原始碼分析(上)

Hadoop之HDFS原理及檔案上傳下載原始碼分析(下)

5.Hadoop中各個元件的通訊方式,RPC/Http等

RPC,即

Remote Procdure Call

,中文名:

遠端過程呼叫

(1)它允許一臺計算機程式遠端呼叫另外一臺計算機的子程式,而不用去關心底層的網路通訊細節,對我們來說是

透明

的。因此,它經常用於分散式網路通訊中。

RPC協議假定某些傳輸協議的存在,如TCP或UDP,為通訊程式之間攜帶資訊資料。在OSI網路通訊模型中,RPC跨越了傳輸層和應用層。RPC使得開發包括網路分散式多程式在內的應用程式更加容易。

(2)Hadoop的程序間互動都是透過RPC來進行的,比如Namenode與Datanode之間,Jobtracker與Tasktracker之間等。

詳細的內容可以看下面兩篇文章:

https://www。

cnblogs。com/nucdy/p/565

5811。html

https://www。

cnblogs。com/edisonchou/

p/4285817。html

6.學會寫WordCount(Java/Python-Hadoop Streaming),理解分散式/單機執行模式的區別

另起了一篇文章

MapReduce任務—WordCount(Python-Hadoop Streaming)例項

7.理解MapReduce的執行過程

參考資料:

https://

zhuanlan。zhihu。com/p/45

305945

https://

blog。csdn。net/u01308751

3/article/details/77771600

8.Yarn在Hadoop中的作用

Yarn是Hadoop叢集的資源管理系統。Yarn可以提高資源的利用率。Yarn的另一個目標就是拓展Hadoop,使得它不僅僅可以支援MapReduce計算,還能很方便的管理諸如Hive、Hbase、Pig、Spark/Shark等應用。這種新的架構設計能夠使得各種型別的應用執行在Hadoop上面,並透過Yarn從系統層面進行統一的管理,也就是說,有了Yarn,各種應用就可以互不干擾的執行在同一個Hadoop系統中,共享整個叢集資源

參考資料:

https://

blog。csdn。net/suifeng30

51/article/details/49486927

https://www。

zhihu。com/question/3401

6617

附:HDFS的常用命令:

HDFS常用Shell命令和基礎開發

標簽: hive  usr  local  Hadoop