Hadoop
一. 引言
1.1 什么是大數(shù)據(jù)
大數(shù)據(jù):(Big Data
):數(shù)據(jù)量級(jí)很大的應(yīng)用處理般眉。TB級(jí) ,日數(shù)據(jù)增長(zhǎng)GB級(jí)
K -- M---- G ---- T ----PB ---- EB ---ZB 1024
通過(guò)對(duì)海量數(shù)據(jù)進(jìn)行分析,挖掘,進(jìn)而發(fā)現(xiàn)數(shù)據(jù)內(nèi)在的規(guī)律流济,從而為企業(yè)或者國(guó)家創(chuàng)造價(jià)值。
1.2 大數(shù)據(jù)特點(diǎn)
4V
是大數(shù)據(jù)典型的特點(diǎn)具體指的是:
# 1.Volume (大量)
數(shù)據(jù)量很大腌闯,至少是TB或者日均增加GB級(jí)
# 2.Variety (多樣)
a.結(jié)構(gòu)化數(shù)據(jù) : 傳統(tǒng)關(guān)系型數(shù)據(jù)庫(kù)中的數(shù)據(jù)
b.半結(jié)構(gòu)化數(shù)據(jù): json xml mongodb存儲(chǔ)的數(shù)據(jù)
c.非結(jié)構(gòu)化數(shù)據(jù): 音頻 視頻
# 3.Velocity(快速)
處理數(shù)據(jù)速度要快 注意:是相對(duì)速度快
# 4.Value (價(jià)值)
海量沒(méi)有價(jià)值的數(shù)據(jù)中绳瘟,分析出有價(jià)值的內(nèi)容。
1.3 大數(shù)據(jù)的工作方向
# 1. 業(yè)務(wù)
電商的推薦系統(tǒng)姿骏,智能廣告系統(tǒng)糖声,專(zhuān)家系統(tǒng),智慧城市分瘦,智能交通蘸泻,金融大腦,智慧醫(yī)療嘲玫,災(zāi)害預(yù)警....
# 2. 工作方向
大數(shù)據(jù)運(yùn)維工程師悦施,大數(shù)據(jù)開(kāi)發(fā)工程師(實(shí)時(shí)計(jì)算,數(shù)據(jù)倉(cāng)庫(kù)去团,ETL,基本挖掘)抡诞,數(shù)據(jù)分析師(算法)
1.4 大數(shù)據(jù)的起源
Google是最早面臨大數(shù)據(jù)問(wèn)題的公司拜马。
1. GFS google File System
2. MapReduce
3. BigTable (NoSQL 數(shù)據(jù)庫(kù))
大數(shù)據(jù)起源可以說(shuō)是google最早開(kāi)源的3篇論文,開(kāi)創(chuàng)了大數(shù)據(jù)時(shí)代
1.5 大數(shù)據(jù)處理的核心數(shù)據(jù)類(lèi)型
大數(shù)據(jù)處理的核心數(shù)據(jù)類(lèi)型通常為:
文本類(lèi)型
1.6 大數(shù)據(jù)的數(shù)據(jù)來(lái)源
# 1.自己公司業(yè)務(wù)系統(tǒng)運(yùn)行產(chǎn)生的日志 (nginx,log4j,數(shù)據(jù)庫(kù)中的日志)
# 2.爬蟲(chóng)
# 3.行業(yè)數(shù)據(jù) 電信 醫(yī)療 政府.
1.7 大數(shù)據(jù)目前面臨問(wèn)題
# 1.存儲(chǔ)
如何解決現(xiàn)有大數(shù)據(jù)中數(shù)據(jù)存儲(chǔ)問(wèn)題
# 2.統(tǒng)計(jì)|計(jì)算
如何解決現(xiàn)有大規(guī)模的數(shù)據(jù)集中統(tǒng)計(jì)和計(jì)算的問(wèn)題
二. Hadoop的引言
2.1 解決問(wèn)題
Hadoop
主要是用來(lái)解決大數(shù)據(jù)所面臨的數(shù)據(jù)存儲(chǔ)
和數(shù)據(jù)計(jì)算
的問(wèn)題。
2.2 Hadoop誕生
2003-2004年沐绒,Google公布了部分GFS和MapReduce思想的細(xì)節(jié),受此啟發(fā)的Doug Cutting等人用2年的業(yè)余時(shí)間實(shí)現(xiàn)了DFS和MapReduce機(jī)制旺坠,使Nutch性能飆升乔遮。然后Yahoo招安Doug Gutting及其項(xiàng)目。
2005年取刃,Hadoop作為L(zhǎng)ucene的子項(xiàng)目Nutch的一部分正式引入Apache基金會(huì)蹋肮。
2006年2月被分離出來(lái),成為一套完整獨(dú)立的軟件璧疗,起名為Hadoop
Hadoop名字不是一個(gè)縮寫(xiě)坯辩,而是一個(gè)生造出來(lái)的詞。是Hadoop之父Doug Cutting兒子毛絨玩具象命名的崩侠。
Hadoop之父
Doug Cutting
漆魔,可能所有人都間接用過(guò)他的作品,他是Lucene
却音、Nutch
改抡、Hadoop
等項(xiàng)目的發(fā)起人
。是他系瓢,把高深莫測(cè)的搜索技術(shù)形成產(chǎn)品阿纤,貢獻(xiàn)給我們;還是他夷陋,打造了目前在云計(jì)算和大數(shù)據(jù)領(lǐng)域里如日中天的Hadoop欠拾。
# Haoop核心設(shè)計(jì)
HDFS (Hadoop Distribute File System) -------> GFS
MapReduce -------> MapReduce
HBase -------> Big Table
apache
組織正式開(kāi)源,并將hadoop作為apache頂級(jí)的開(kāi)源項(xiàng)目之一
2.3 Hadoop的發(fā)行版本
版本 | 是否收費(fèi) | 使用難度 |
---|---|---|
Apache 開(kāi)源的Hadoop | 免費(fèi) | ★★★★☆ |
Clouder(CDH) | $4000 (1個(gè)節(jié)點(diǎn)) | ★★★☆☆ |
Hortonworks | $12500(10個(gè)節(jié)點(diǎn)) | ★★★☆☆ |
華為hadoop | 未知(內(nèi)部使用) | ☆☆☆☆☆ |
注意:在實(shí)際開(kāi)發(fā)中Appache的Hadoop企業(yè)實(shí)際使用并不多。最原始(基礎(chǔ))版本骗绕。但是卻是學(xué)習(xí)hadoop的基礎(chǔ)藐窄。
2.4 hadoop的生態(tài)圈
# 1.hadoop核心 HDFS,MapReduce
# 2.Hive 通過(guò)SQl語(yǔ)句形式執(zhí)行mapreduce
# 3.Hbase Nosql數(shù)據(jù)庫(kù)
# 4.Flume 日志采集工具
# 5.Sqoop sql to hadoop 將數(shù)據(jù)導(dǎo)入到hadoop中
# 6.Zookeeper 協(xié)調(diào)服務(wù)工具
# 7.Mahout 算法庫(kù)
# 8.Pig 是MapReduce的一個(gè)抽象爹谭,它是一個(gè)工具/平臺(tái)枷邪,用于分析較大的數(shù)據(jù)集,并將它們表示為數(shù)據(jù)流诺凡。
三.Hadoop的安裝(單機(jī))
說(shuō)明: hadoop的核心為
HDFS
和MapReduce
3.1 Hadoop的核心之HDFS
3.1.1 HDFS引言
# HDFS (Hadoop Distribute File System): Hadoop 的分布式文件存儲(chǔ)系統(tǒng),他核心解決的大數(shù)據(jù)的存儲(chǔ)問(wèn)題
3.1.2 HDFS基本架構(gòu)圖
-
NameNode:
是整個(gè)HDFS集群的總?cè)肟?存儲(chǔ)著HDFS的集群的文件元數(shù)據(jù)(如:client上傳文件的文件名 副本數(shù) 塊數(shù)等相關(guān)信息)东揣。 -
DataNode:
是真正用來(lái)負(fù)責(zé)存儲(chǔ)數(shù)據(jù)的節(jié)點(diǎn),一個(gè)DataNode就是一個(gè)真實(shí)的物理主機(jī)。 -
Block:
數(shù)據(jù)塊,為了能通過(guò)多個(gè)節(jié)點(diǎn)保存大數(shù)據(jù)集,HDFS將大數(shù)據(jù)集文件切分成一塊塊的數(shù)據(jù)塊腹泌,在現(xiàn)有hadoop2版本中默認(rèn)一個(gè)塊大小為128M嘶卧。
3.1.3 Hadoop的安裝
準(zhǔn)備環(huán)境
# 0. 安裝centos7.x 虛擬機(jī),并啟動(dòng)
# 1. 輸入hostname 查看當(dāng)前主機(jī)名
# 2. 使用vim /etc/hostname 修改主機(jī)名
# 3. 重啟centos 系統(tǒng) reboot
# 4. 查看修改之后的主機(jī)名 hostname
# 5. 添加主機(jī)名與ip映射 vim /etc/hosts
加入 ip(當(dāng)前ip地址) centos(主機(jī)名)
# 6. 檢測(cè)主機(jī)名ip配置是否生效
# 7.關(guān)閉防火墻
`systemctl stop firewalld
`systemctl disable firewalld
配置java環(huán)境變量
# 0.下載jdk
wget https://download.oracle.com/otn/java/jdk/8u231-b11/5b13a193868b4bf28bcb45c792fce896/jdk-8u231-linux-x64.rpm
# 1. 安裝jdk文件
rpm -ivh jdk-8u231-linux-x64.rpm
# 2. 配置環(huán)境變量 vim /etc/profile
export JAVA_HOME=/usr/java/jdk1.8.0_171-amd64
export PATH=$PATH:$NODE_HOME/bin:$MAVEN_HOME/bin:$JAVA_HOME/bin
# 3. 重新載入配置
source /etc/profile
# 4. 檢測(cè)配置是否生效
jps
java
javac
安裝hadoop
# 0.下載hadoo
wget hadoop-2.9.2.tar.gz 注意:本次課程使用的事hadoop2.9.2版本 和 centos7.x
# 1. 上傳hadoop軟件包到系統(tǒng)中
hadoop-2.9.2.tar.gz
# 2. 解壓到指定文件目錄中
tar -zxvf hadoop-2.9.2.tar.gz -C /usr
# 3. 配置hadoop環(huán)境變量
export HADOOP_HOME=/usr/hadoop-2.9.2
export PATH=$PATH$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
# 4. 測(cè)試環(huán)境變量是否配置成功
直接輸入hdfs命令查看效果
# 5. 查看hadoop的安裝目錄 tree -L 1 /usr/hadoop-2.9.2
[root@hadoop ~]# tree -L 2 hadoop-2.9.2
hadoop-2.9.2
├── bin
│ ├── container-executor
│ ├── hadoop
│ ├── hadoop.cmd
│ ├── hdfs
│ ├── hdfs.cmd
│ ├── mapred
│ ├── mapred.cmd
│ ├── rcc
│ ├── test-container-executor
│ ├── yarn
│ └── yarn.cmd
├── etc
│ └── hadoop
├── include
│ ├── hdfs.h
│ ├── Pipes.hh
│ ├── SerialUtils.hh
│ ├── StringUtils.hh
│ └── TemplateFactory.hh
├── lib
│ └── native
├── libexec
│ ├── hadoop-config.cmd
│ ├── hadoop-config.sh
│ ├── hdfs-config.cmd
│ ├── hdfs-config.sh
│ ├── httpfs-config.sh
│ ├── kms-config.sh
│ ├── mapred-config.cmd
│ ├── mapred-config.sh
│ ├── yarn-config.cmd
│ └── yarn-config.sh
├── LICENSE.txt
├── logs
│ ├── hadoop-root-datanode-hadoop.log
│ ├── hadoop-root-datanode-hadoop.out
│ ├── hadoop-root-datanode-hadoop.out.1
│ ├── hadoop-root-datanode-hadoop.out.2
│ ├── hadoop-root-datanode-hadoop.out.3
│ ├── hadoop-root-datanode-hadoop.out.4
│ ├── hadoop-root-datanode-hadoop.out.5
│ ├── hadoop-root-namenode-hadoop.log
│ ├── hadoop-root-namenode-hadoop.out
│ ├── hadoop-root-namenode-hadoop.out.1
│ ├── hadoop-root-namenode-hadoop.out.2
│ ├── hadoop-root-namenode-hadoop.out.3
│ ├── hadoop-root-namenode-hadoop.out.4
│ ├── hadoop-root-namenode-hadoop.out.5
│ ├── hadoop-root-secondarynamenode-hadoop.log
│ ├── hadoop-root-secondarynamenode-hadoop.out
│ ├── hadoop-root-secondarynamenode-hadoop.out.1
│ ├── hadoop-root-secondarynamenode-hadoop.out.2
│ ├── hadoop-root-secondarynamenode-hadoop.out.3
│ ├── hadoop-root-secondarynamenode-hadoop.out.4
│ ├── hadoop-root-secondarynamenode-hadoop.out.5
│ ├── SecurityAuth-root.audit
│ ├── userlogs
│ ├── yarn-root-nodemanager-hadoop.log
│ ├── yarn-root-nodemanager-hadoop.out
│ ├── yarn-root-nodemanager-hadoop.out.1
│ ├── yarn-root-nodemanager-hadoop.out.2
│ ├── yarn-root-nodemanager-hadoop.out.3
│ ├── yarn-root-nodemanager-hadoop.out.4
│ ├── yarn-root-nodemanager-hadoop.out.5
│ ├── yarn-root-resourcemanager-hadoop.log
│ ├── yarn-root-resourcemanager-hadoop.out
│ ├── yarn-root-resourcemanager-hadoop.out.1
│ ├── yarn-root-resourcemanager-hadoop.out.2
│ ├── yarn-root-resourcemanager-hadoop.out.3
│ ├── yarn-root-resourcemanager-hadoop.out.4
│ └── yarn-root-resourcemanager-hadoop.out.5
├── NOTICE.txt
├── README.txt
├── sbin
│ ├── distribute-exclude.sh
│ ├── FederationStateStore
│ ├── hadoop-daemon.sh
│ ├── hadoop-daemons.sh
│ ├── hdfs-config.cmd
│ ├── hdfs-config.sh
│ ├── httpfs.sh
│ ├── kms.sh
│ ├── mr-jobhistory-daemon.sh
│ ├── refresh-namenodes.sh
│ ├── slaves.sh
│ ├── start-all.cmd
│ ├── start-all.sh
│ ├── start-balancer.sh
│ ├── start-dfs.cmd
│ ├── start-dfs.sh
│ ├── start-secure-dns.sh
│ ├── start-yarn.cmd
│ ├── start-yarn.sh
│ ├── stop-all.cmd
│ ├── stop-all.sh
│ ├── stop-balancer.sh
│ ├── stop-dfs.cmd
│ ├── stop-dfs.sh
│ ├── stop-secure-dns.sh
│ ├── stop-yarn.cmd
│ ├── stop-yarn.sh
│ ├── yarn-daemon.sh
│ └── yarn-daemons.sh
└── share
├── doc
└── hadoop
-
bin 和 sbin
目錄用來(lái)啟動(dòng)hdfs yarn 等可執(zhí)行的腳本文件 -
etc
目錄用來(lái)存放hadoop的配置文件 -
logs
目錄用來(lái)存放hadoop的日志文件 -
share
用來(lái)存放hadoop的依賴(lài)jar第三方j(luò)ar目錄 -
lib
用來(lái)存放hadoop使用核心庫(kù)文件
# 6.配置core-site.xml
vim /usr/hadoop-2.9.2/etc/hadoop/core-site.xml 加入如下配置:
<configuration>
<!--配置hdfs文件系統(tǒng)默認(rèn)名稱(chēng)-->
<property>
<name>fs.defaultFS</name>
<value>hdfs://hadoop(主機(jī)名):9000</value>
</property>
</configuration>
注意:名稱(chēng)是一個(gè)HDFS的URL
# 7.配置hdfs-site.xml
vim /usr/hadoop-2.9.2/etc/hadoop/hdfs-site.xml 加入如下配置:
<configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
</configuration>
# 8.配置slaves文件
vim /usr/hadoop-2.9.2/etc/hadoop/slaves 加入如下配置:
hadoop (當(dāng)前主機(jī)名)
# 9.格式化hdfs
hdfs namenode -format (僅僅是第一次使用需要格式化)
`出現(xiàn)如下錯(cuò)誤: /usr/hadoop-2.9.2/bin/hdfs:行319: /usr/java/jdk1.8.0_171-amd64/bin//bin/java: 沒(méi)有那個(gè)文件或目錄`參考步驟10解決
注意:這里的格式化是格式成hadoop可以識(shí)別的文件系統(tǒng),比如我們買(mǎi)了一塊硬盤(pán)我們需要格式化成windows或者mac,linux系統(tǒng)識(shí)別的文件系統(tǒng),才能使用這個(gè)文件系統(tǒng)。
# 10.配置etc/hadoop目錄中中hadoop-env.sh
將原來(lái)export JAVA_HOME=$JAVA_HOME ====修改為jdk安裝目錄==> export JAVA_HOME=/usr/java/jdk1.8.0_171-amd64
# 11.啟動(dòng)HDFS
start-dfs.sh 啟動(dòng)
stop-dfs.sh 關(guān)閉
# 12. 查看hadoop是否啟動(dòng)成功
jps 存在以下進(jìn)程名稱(chēng)說(shuō)明啟動(dòng)成功
5876 SecondaryNameNode
5702 DataNode
5995 Jps
5612 NameNode
注意:只要能看到NameNode 和 DataNode 說(shuō)明啟動(dòng)成功
# 13. 訪(fǎng)問(wèn)hdfs提供的web界面
http://IP地址:50070/
3.2 查看HDFS日志
# 1.進(jìn)入hadoop安裝目錄中l(wèi)ogs目錄中
hadoop-root-namenode-hadoop.log ---- namenode日志
hadoop-root-datanode-hadoop.log ---- datanode日志
hadoop-root-secondarynamenode-hadoop.log ---- secondnamenode 日志
yarn-root-resourcemanager-hadoop.log ---- resourcemanager 日志
yarn-root-nodemanager-hadoop.log ---- nodemanager 日志
注意:針對(duì)于hdfs日志規(guī)則為hadoop-用戶(hù)名-服務(wù)名-主機(jī)名.log,針對(duì)于后續(xù)學(xué)習(xí)的yarn生成規(guī)則為yarn-用戶(hù)名-服務(wù)名-主機(jī)名.log
3.3 修改hdfs默認(rèn)數(shù)據(jù)位置
- 說(shuō)明: 通過(guò)查看日志得知namenode數(shù)據(jù)和datanode數(shù)據(jù)默認(rèn)都是存放在/tmp//tmp/hadoop-root/dfs下,這對(duì)于我們來(lái)說(shuō)是不安全的,因?yàn)閠mp目錄為臨時(shí)目錄,系統(tǒng)可能會(huì)定期清除目錄中文件,因此為了保證數(shù)據(jù)安全修改數(shù)據(jù)默認(rèn)的存放位置
# 1.修改hadoop安裝目錄下etc/hadoop/core-site.xml 加入如下配置
<property>
<name>hadoop.tmp.dir</name>
<value>/usr/hadoop-2.9.2/data</value>
</property>
3.4 配置SSH免密登錄
SSH 為 [Secure Shell](https://baike.baidu.com/item/Secure Shell) 的縮寫(xiě)凉袱,由 IETF 的網(wǎng)絡(luò)小組(Network Working Group)所制定芥吟;SSH 為建立在應(yīng)用層基礎(chǔ)上的安全協(xié)議侦铜。
從客戶(hù)端來(lái)看,SSH提供兩種級(jí)別的安全驗(yàn)證钟鸵。
3.4.1基于口令的安全驗(yàn)證
只要你知道自己帳號(hào)和口令钉稍,就可以登錄到遠(yuǎn)程主機(jī)。所有傳輸?shù)臄?shù)據(jù)都會(huì)被加密棺耍,但是不能保證你正在連接的服務(wù)器就是你想連接的服務(wù)器贡未。可能會(huì)有別的服務(wù)器在冒充真正的服務(wù)器蒙袍,也就是受到“中間人”這種方式的攻擊俊卤。
3.4.2 基于密匙的安全驗(yàn)證
需要依靠密匙,也就是你必須為自己創(chuàng)建一對(duì)密匙害幅,并把公用密匙放在需要訪(fǎng)問(wèn)的服務(wù)器上消恍。如果你要連接到SSH服務(wù)器上,客戶(hù)端軟件就會(huì)向服務(wù)器發(fā)出請(qǐng)求以现,請(qǐng)求用你的密匙進(jìn)行安全驗(yàn)證狠怨。服務(wù)器收到請(qǐng)求之后,先在該服務(wù)器上你的主目錄下尋找你的公用密匙叼风,然后把它和你發(fā)送過(guò)來(lái)的公用密匙進(jìn)行比較取董。如果兩個(gè)密匙一致,服務(wù)器就用公用密匙加密“質(zhì)詢(xún)”(challenge)并把它發(fā)送給客戶(hù)端軟件无宿∫鹛客戶(hù)端軟件收到“質(zhì)詢(xún)”之后就可以用你的私人密匙解密再把它發(fā)送給服務(wù)器。
注意:第二種級(jí)別不僅加密所有傳送的數(shù)據(jù)孽鸡,而且“中間人”這種攻擊方式也是不可能的(因?yàn)樗麤](méi)有你的私人密匙)蹂午。但是整個(gè)登錄的過(guò)程可能需要10秒 。
3.4.3 ssh 登錄過(guò)程
3.4.4 配置ssh
# 1. 生成ssh秘鑰對(duì)
ssh-keygen -t rsa 然后回車(chē)幾次就可以啦
# 2. 查看秘鑰對(duì)生成位置
ls /root/.ssh 會(huì)發(fā)現(xiàn)在home目錄中生成了兩個(gè)文件
id_rsa(私鑰) id_rsa.pub(公鑰)
# 3. 將公鑰加入另一臺(tái)機(jī)器的受信列表中
ssh-copy-id hadoop(主機(jī)名)
cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys (和上面命令一樣)
# 4. 再次查看/root/.ssh 目錄 多出兩個(gè)文件其中authorized_keys就是存放公鑰列表文件
authorized_keys id_rsa id_rsa.pub known_hosts
# 5. 檢測(cè)是否配置成功
ssh hadoop 不需要輸入密碼即可
四. HDFS的基本操作
4.1 Shell基本操作
4.1.1 命令總結(jié)
[root@hadoop ~]# hdfs dfs
Usage: hadoop fs [generic options]
[-appendToFile <localsrc> ... <dst>]
[-cat [-ignoreCrc] <src> ...]
[-checksum <src> ...]
[-chgrp [-R] GROUP PATH...]
[-chmod [-R] <MODE[,MODE]... | OCTALMODE> PATH...]
[-chown [-R] [OWNER][:[GROUP]] PATH...]
[-copyFromLocal [-f] [-p] [-l] [-d] <localsrc> ... <dst>]
[-copyToLocal [-f] [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]
[-count [-q] [-h] [-v] [-t [<storage type>]] [-u] [-x] <path> ...]
[-cp [-f] [-p | -p[topax]] [-d] <src> ... <dst>]
[-createSnapshot <snapshotDir> [<snapshotName>]]
[-deleteSnapshot <snapshotDir> <snapshotName>]
[-df [-h] [<path> ...]]
[-du [-s] [-h] [-x] <path> ...]
[-expunge]
[-find <path> ... <expression> ...]
[-get [-f] [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]
[-getfacl [-R] <path>]
[-getfattr [-R] {-n name | -d} [-e en] <path>]
[-getmerge [-nl] [-skip-empty-file] <src> <localdst>]
[-help [cmd ...]]
[-ls [-C] [-d] [-h] [-q] [-R] [-t] [-S] [-r] [-u] [<path> ...]]
[-mkdir [-p] <path> ...]
[-moveFromLocal <localsrc> ... <dst>]
[-moveToLocal <src> <localdst>]
[-mv <src> ... <dst>]
[-put [-f] [-p] [-l] [-d] <localsrc> ... <dst>]
[-renameSnapshot <snapshotDir> <oldName> <newName>]
[-rm [-f] [-r|-R] [-skipTrash] [-safely] <src> ...]
[-rmdir [--ignore-fail-on-non-empty] <dir> ...]
[-setfacl [-R] [{-b|-k} {-m|-x <acl_spec>} <path>]|[--set <acl_spec> <path>]]
[-setfattr {-n name [-v value] | -x name} <path>]
[-setrep [-R] [-w] <rep> <path> ...]
[-stat [format] <path> ...]
[-tail [-f] <file>]
[-test -[defsz] <path>]
[-text [-ignoreCrc] <src> ...]
[-touchz <path> ...]
[-truncate [-w] <length> <path> ...]
[-usage [cmd ...]]
4.1.2 常見(jiàn)命令
# 1.查看目錄結(jié)構(gòu)
[root@hadoop1 ~]# hdfs dfs -ls /
# 2.上傳文件到HDFS
[root@hadoop1 ~]# hdfs dfs -put aa.txt /
# 3.創(chuàng)建文件夾
[root@hadoop1 ~]# hdfs dfs -mkdir -p /bbb/cccc
[root@hadoop1 ~]# hdfs dfs -ls /
Found 2 items
-rw-r--r-- 1 root supergroup 58 2019-12-18 16:13 /aa.txt
drwxr-xr-x - root supergroup 0 2019-12-18 16:16 /bbb
[root@hadoop1 ~]# hdfs dfs -ls /bbb/cccc
# 4.查看文件內(nèi)容
[root@hadoop1 ~]# hdfs dfs -cat /aa.txt
chenyn 1
xiaohei 1
wangwu 1
xiaohei 1
chenyn 1
zhangsan 1
[root@hadoop1 ~]# hdfs dfs -text /aa.txt
chenyn 1
xiaohei 1
wangwu 1
xiaohei 1
chenyn 1
zhangsan 1
# 5.刪除文件
[root@hadoop1 ~]# hdfs dfs -rm /aa.txt
Deleted /aa.txt
# 6.刪除空目錄
[root@hadoop1 ~]# hdfs dfs -rm -r /bbb ----- 遞歸刪除
Deleted /bbb
[root@hadoop1 ~]# hdfs dfs -mkdir -p /aa/bb/cc ----- 創(chuàng)建多級(jí)目錄
[root@hadoop1 ~]# hdfs dfs -rm -r -f /aa ----- 強(qiáng)制刪除
Deleted /aa
# 7.追加文件內(nèi)容
[root@hadoop1 ~]# hdfs dfs -put aa.txt /
[root@hadoop1 ~]# hdfs dfs -cat /aa.txt
chenyn 1
xiaohei 1
wangwu 1
xiaohei 1
chenyn 1
zhangsan 1
[root@hadoop1 ~]# touch bb.txt
[root@hadoop1 ~]# echo "xiaohei 1" >> bb.txt
[root@hadoop1 ~]# cat bb.txt
xiaohei 1
[root@hadoop1 ~]# hdfs dfs -appendToFile bb.txt /aa.txt
[root@hadoop1 ~]# hdfs dfs -cat /aa.txt
chenyn 1
xiaohei 1
wangwu 1
xiaohei 1
chenyn 1
zhangsan 1
xiaohei 1
# 8.查看文件的校驗(yàn)核
[root@hadoop1 ~]# hdfs dfs -checksum /aa.txt
/aa.txt MD5-of-0MD5-of-512CRC32C 000002000000000000000000fb2fbd294298362dbaabfb7fc8724306
# 9.查看文件的權(quán)限
[root@hadoop1 ~]# hdfs dfs -ls -R /aa.txt
-rw-r--r-- 1 root supergroup 68 2019-12-18 16:35 /aa.txt
[root@hadoop1 ~]# hdfs dfs -chmod a+x /aa.txt
[root@hadoop1 ~]# hdfs dfs -ls -R /aa.txt
-rwxr-xr-x 1 root supergroup 68 2019-12-18 16:35 /aa.txt
# 10.從本地copy到hdfs中
[root@hadoop1 ~]# hdfs dfs -copyFromLocal bb.txt /bb.txt -----從本地復(fù)制文件到HDFS
[root@hadoop1 ~]# hdfs dfs -copyFromLocal bb.txt /bb.txt -----如果文件已經(jīng)存在hdfs 復(fù)制失敗
copyFromLocal: `/bb.txt': File exists
[root@hadoop1 ~]# hdfs dfs -copyFromLocal -f bb.txt /bb.txt -----如果文件已經(jīng)存在hdfs 可以強(qiáng)制覆蓋hdfs中文件
# 11.hdfs中復(fù)制文件
[root@hadoop1 ~]# hdfs dfs -mkdir /datas
[root@hadoop1 ~]# hdfs dfs -cp /aa.txt /datas
[root@hadoop1 ~]# hdfs dfs -ls /datas
Found 1 items
-rw-r--r-- 1 root supergroup 68 2019-12-18 16:54 /datas/aa.txt
# 12.從hdfs上下載文件到本地
[root@hadoop1 ~]# hdfs dfs -ls /
Found 3 items
-rwxr-xr-x 1 root supergroup 68 2019-12-18 16:35 /aa.txt
-rw-r--r-- 1 root supergroup 10 2019-12-18 16:50 /bb.txt
drwxr-xr-x - root supergroup 0 2019-12-18 16:54 /datas
[root@hadoop1 ~]# ls
aa.txt bb.txt hadoop-2.9.2.tar.gz jdk-8u171-linux-x64.rpm
[root@hadoop1 ~]# hdfs dfs -get /aa.txt /root/down.txt
[root@hadoop1 ~]# ls
aa.txt bb.txt down.txt hadoop-2.9.2.tar.gz jdk-8u171-linux-x64.rpm
# 13.查找某個(gè)路徑下文件
[root@hadoop1 ~]# hdfs dfs -find / -name "aa.txt"
/aa.txt
/datas/aa.txt
# 14.將hdfs文件移動(dòng)到hdfs另一個(gè)位置
[root@hadoop1 ~]# hdfs dfs -ls /
Found 3 items
-rwxr-xr-x 1 root supergroup 68 2019-12-18 16:35 /aa.txt
-rw-r--r-- 1 root supergroup 10 2019-12-18 16:50 /bb.txt
drwxr-xr-x - root supergroup 0 2019-12-18 16:54 /datas
[root@hadoop1 ~]# hdfs dfs -ls /datas
Found 1 items
-rw-r--r-- 1 root supergroup 68 2019-12-18 16:54 /datas/aa.txt
[root@hadoop1 ~]# hdfs dfs -mv /bb.txt /datas/bb.txt
[root@hadoop1 ~]# hdfs dfs -ls /
Found 2 items
-rwxr-xr-x 1 root supergroup 68 2019-12-18 16:35 /aa.txt
drwxr-xr-x - root supergroup 0 2019-12-18 17:03 /datas
[root@hadoop1 ~]# hdfs dfs -ls /datas
Found 2 items
-rw-r--r-- 1 root supergroup 68 2019-12-18 16:54 /datas/aa.txt
-rw-r--r-- 1 root supergroup 10 2019-12-18 16:50 /datas/bb.txt
4.2 Java操作HDFS
4.2.1 引入依賴(lài)
<properties>
<hadoop.version>2.9.2</hadoop.version>
</properties>
<dependencies>
<!--hadoop公共依賴(lài)-->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>${hadoop.version}</version>
</dependency>
<!--hadoop client 依賴(lài)-->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>${hadoop.version}</version>
</dependency>
<!--junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
4.2.2 獲取hdfs客戶(hù)端
public class TestHDFS {
private FileSystem fileSystem; //hdfs客戶(hù)端對(duì)象
@Before
public void before() throws IOException {
//hadoop文件系統(tǒng)的權(quán)限設(shè)置為root
System.setProperty("HADOOP_USER_NAME","root");
//用來(lái)對(duì)core-site.xml hdfs-site.xml進(jìn)行配置
Configuration conf = new Configuration();
//連接hdfs
conf.set("fs.defaultFS","hdfs://10.15.0.4:9000");
//設(shè)置上傳文件的副本集
conf.set("dfs.replication","1");
fileSystem = FileSystem.get(conf);
}
@After
public void close() throws IOException {
fileSystem.close();
}
}
注意: FileSystem是java操作HDFS的客戶(hù)端對(duì)象
4.2.3 上傳文件到hdfs
@Test
public void testUpload() throws IOException {
FileInputStream is = new FileInputStream("/Users/chenyannan/IdeaProjects/ideacode/hadoop_hdfs/pom.xml");
Path path = new Path("/pom.xml");
FSDataOutputStream os = fileSystem.create(path);
//參數(shù)1:輸入流 參數(shù)2:輸出流 參數(shù)3:緩沖區(qū)大小 參數(shù)4:是否關(guān)閉流
IOUtils.copyBytes(is,os,1024,true);
}
4.2.4 hdfs下載文件
// 1.第一種方式
@Test
public void testDownload() throws IOException {
Path source = new Path("/pom.xml");
Path des = new Path("/Users/chenyannan");
fileSystem.copyToLocalFile(source,des);
}
// 2.第二種方式
@Test
public void testDownload1() throws IOException {
Path path = new Path("/pom.xml");
FSDataInputStream in = fileSystem.open(path);
FileOutputStream os = new FileOutputStream("/Users/chenyannan/aa.xml");
IOUtils.copyBytes(in,os,1024,true);
}
4.2.5 hdfs創(chuàng)建目錄
@Test
public void testMkdirs() throws IOException {
boolean mkdirs = fileSystem.mkdirs(new Path("/aa/cc/cc"));
System.out.println("mkdirs = " + mkdirs);
}
4.2.6 展示hdfs文件列表
@Test
public void testListFiles() throws IOException {
Path path = new Path("/");
RemoteIterator<LocatedFileStatus> listFiles = fileSystem.listFiles(path, true);
while (listFiles.hasNext()){
LocatedFileStatus next = listFiles.next();
System.out.println("next = " + next);
}
}
4.2.7 展示hdfs目錄和文件
@Test
public void testListDirs() throws IOException {
Path path = new Path("/");
FileStatus[] fileStatuses = fileSystem.listStatus(path);
for (FileStatus fileStatus : fileStatuses) {
System.out.println(fileStatus.isDirectory()+" "+fileStatus.getPath());
}
}
4.2.8 刪除文件
@Test
public void testDelete() throws IOException {
Path path= new Path("/aa");
//參數(shù)1:目錄路徑 參數(shù)2:是否遞歸刪除
fileSystem.delete(path,true);
}
4.3 HDFS配置文件的優(yōu)先級(jí)詳解
注意:hadoop的配置文件解析順序java代碼客戶(hù)端優(yōu)于 > hadoop目錄中etc/中配置優(yōu)于 >share中jar默認(rèn)配置
五. NameNode的持久化
5.1 NameNode的數(shù)據(jù)存在哪?
首先彬碱,我們做個(gè)假設(shè)豆胸,如果存儲(chǔ)在NameNode節(jié)點(diǎn)的磁盤(pán)中,因?yàn)榻?jīng)常需要進(jìn)行隨機(jī)訪(fǎng)問(wèn)巷疼,還有響應(yīng)客戶(hù)請(qǐng)求晚胡,必然是效率過(guò)低。因此嚼沿,元數(shù)據(jù)需要存放在內(nèi)存中估盘。
5.2 NameNode的持久化
NameNode數(shù)據(jù)存在內(nèi)存中,一旦斷電骡尽,元數(shù)據(jù)丟失遣妥,整個(gè)集群就無(wú)法工作了。因此產(chǎn)生在磁盤(pán)中備份元數(shù)據(jù)的FsImage攀细。這樣又會(huì)帶來(lái)新的問(wèn)題箫踩,當(dāng)在內(nèi)存中的元數(shù)據(jù)更新時(shí)爱态,如果同時(shí)更新FsImage,就會(huì)導(dǎo)致效率過(guò)低境钟,但如果不更新锦担,就會(huì)發(fā)生一致性問(wèn)題,一旦NameNode節(jié)點(diǎn)斷電慨削,就會(huì)產(chǎn)生數(shù)據(jù)丟失吆豹。因此,引入Edits文件(只進(jìn)行追加操作理盆,效率很高)。每當(dāng)元數(shù)據(jù)有更新或者添加元數(shù)據(jù)時(shí)凑阶,修改內(nèi)存中的元數(shù)據(jù)并追加到Edits中猿规。這樣,一旦NameNode節(jié)點(diǎn)斷電宙橱,可以通過(guò)FsImage和Edits的合并姨俩,合成元數(shù)據(jù)。但是,如果一旦長(zhǎng)時(shí)間添加數(shù)據(jù)到Edits中师郑,會(huì)導(dǎo)致該文件數(shù)據(jù)過(guò)大环葵,效率降低,而且一旦斷電宝冕,恢復(fù)元數(shù)據(jù)需要的時(shí)間過(guò)長(zhǎng)张遭。因此,需要定期進(jìn)行FsImage和Edits的合并地梨,如果這個(gè)操作由NameNode節(jié)點(diǎn)完成菊卷,又會(huì)效率過(guò)低。因此宝剖,引入一個(gè)新的節(jié)點(diǎn)SecondaryNamenode洁闰,專(zhuān)門(mén)用于FsImage和Edits的合并。
總結(jié):通過(guò)SecondaryNameNode 定期 對(duì) FsImage 和 Edits文件的合并來(lái)保證NameNode中數(shù)據(jù)的高可用
5.3 持久化機(jī)制工作原理
# 第一階段:NameNode啟動(dòng)
1>.第一次啟動(dòng)NameNode格式化后万细,創(chuàng)建Fsimage和Edits文件扑眉。如果不是第一次啟動(dòng),直接加載編輯日志和鏡像文件到內(nèi)存赖钞。
2>.客戶(hù)端對(duì)元數(shù)據(jù)進(jìn)行增刪改的請(qǐng)求腰素。
3>.NameNode記錄操作日志,更新滾動(dòng)日志仁烹。
4>.NameNode在內(nèi)存中對(duì)數(shù)據(jù)進(jìn)行增刪改耸弄。
# 第二階段:Secondary NameNode工作
1>.Secondary NameNode詢(xún)問(wèn)NameNode是否需要CheckPoint。直接帶回NameNode是否檢查結(jié)果卓缰。
2>.Secondary NameNode請(qǐng)求執(zhí)行CheckPoint计呈。
3>.NameNode滾動(dòng)正在寫(xiě)的Edits日志砰诵。
4>.將滾動(dòng)前的編輯日志和鏡像文件拷貝到Secondary NameNode。
5>.Secondary NameNode加載編輯日志和鏡像文件到內(nèi)存捌显,并合并茁彭。
6>.生成新的鏡像文件fsimage.chkpoint。
7>.拷貝fsimage.chkpoint到NameNode扶歪。
8>.NameNode將fsimage.chkpoint重新命名成fsimage静浴。
1>.NameNode啟動(dòng)時(shí),先滾動(dòng)Edits并生成一個(gè)空的edits.inprogress赢乓,然后加載Edits和Fsimage到內(nèi)存中谤饭,此時(shí)NameNode內(nèi)存就持有最新的元數(shù)據(jù)信息。
2>.Client開(kāi)始對(duì)NameNode發(fā)送元數(shù)據(jù)的增刪改的請(qǐng)求炫欺,這些請(qǐng)求的操作首先會(huì)被記錄到edits.inprogress中(查詢(xún)?cè)獢?shù)據(jù)的操作不會(huì)被記錄在Edits中乎完,因?yàn)椴樵?xún)操作不會(huì)更改元數(shù)據(jù)信息),如果此時(shí)NameNode掛掉品洛,重啟后會(huì)從Edits中讀取元數(shù)據(jù)的信息树姨。然后,NameNode會(huì)在內(nèi)存中執(zhí)行元數(shù)據(jù)的增刪改的操作桥状。
3>.由于Edits中記錄的操作會(huì)越來(lái)越多帽揪,Edits文件會(huì)越來(lái)越大,導(dǎo)致NameNode在啟動(dòng)加載Edits時(shí)會(huì)很慢辅斟,所以需要對(duì)Edits和Fsimage進(jìn)行合并(所謂合并转晰,就是將Edits和Fsimage加載到內(nèi)存中,照著Edits中的操作一步步執(zhí)行士飒,最終形成新的Fsimage)挽霉。
4>.SecondaryNameNode的作用就是幫助NameNode進(jìn)行Edits和Fsimage的合并工作。
5>.SecondaryNameNode首先會(huì)詢(xún)問(wèn)NameNode是否需要CheckPoint(觸發(fā)CheckPoint需要滿(mǎn)足兩個(gè)條件中的任意一個(gè)变汪,定時(shí)時(shí)間到和Edits中數(shù)據(jù)寫(xiě)滿(mǎn)了)侠坎。直接帶回NameNode是否檢查結(jié)果。
6>.SecondaryNameNode執(zhí)行CheckPoint操作裙盾,首先會(huì)讓NameNode滾動(dòng)Edits并生成一個(gè)空的edits.inprogress实胸,滾動(dòng)Edits的目的是給Edits打個(gè)標(biāo)記,以后所有新的操作都寫(xiě)入edits.inprogress番官,其他未合并的Edits和Fsimage會(huì)拷貝到SecondaryNameNode的本地庐完,然后將拷貝的Edits和Fsimage加載到內(nèi)存中進(jìn)行合并,生成fsimage.chkpoint徘熔,然后將fsimage.chkpoint拷貝給NameNode门躯,重命名為Fsimage后替換掉原來(lái)的Fsimage。
7>.NameNode在啟動(dòng)時(shí)就只需要加載之前未合并的Edits和Fsimage即可酷师,因?yàn)楹喜⑦^(guò)的Edits中的元數(shù)據(jù)信息已經(jīng)被記錄在Fsimage中
5.4 Checkpoint的時(shí)間參數(shù)設(shè)置
修改hdfs-site.xml配置合并時(shí)間
<property>
<name>dfs.namenode.checkpoint.period</name>
<value>3600</value>
</property>
修改hdfs-site.xml中操作次數(shù)和檢查操作次數(shù)周期
<property>
<name>dfs.namenode.checkpoint.txns</name>
<value>1000000</value>
<description>操作動(dòng)作次數(shù)</description>
</property>
<property>
<name>dfs.namenode.checkpoint.check.period</name>
<value>60</value>
<description> 1分鐘檢查一次操作次數(shù)</description>
</property>
六.HDFS完全分布式(簡(jiǎn)單版)
6.1 集群選型
# 1.NameNode 內(nèi)存大 性能好一點(diǎn)的機(jī)器
# 2.DataNode 硬盤(pán)大 性能中等一般的機(jī)器即可
# 3.可以讓NameNode 同時(shí)充當(dāng)DataNode節(jié)點(diǎn)
6.2 集群搭建
# 1.克隆三臺(tái)機(jī)器通過(guò)CRT連接
10.15.0.6
10.15.0.7
10.15.0.8
# 2.配置主機(jī)名以
vim /etc/hostname
NameNode修改為 : hadoop2
DataNode1修改為: hadoop3
DataNode2修改為: hadoop4
修改完成后必須重新啟動(dòng)
# 3.配置主機(jī)名與ip映射
vim /etc/hosts 三個(gè)機(jī)器配置一致
10.15.0.6 hadoop2
10.15.0.7 hadoop3
10.15.0.8 hadoop4
注意:配置完成后可以使用ping命令測(cè)試下是否配置成功
# 4.配置ssh免密登錄
NameNode中執(zhí)行: ssh-copyid root@hadoop2 ssh-copyid root@hadoop3 ssh-copyid root@hadoop4
# 5.安裝jdk配置環(huán)境變量省略
# 6.安裝hadoop 并配置環(huán)境變量省略
# 7.配置三個(gè)機(jī)器 hadoop-env.sh中環(huán)境變量設(shè)置
vim /usr/hadoop-2.9.2/etc/hadoop/hadoop-env.sh 文件
# 8.配置三臺(tái)機(jī)器的core-site.xml文件
vim /usr/hadoop-2.9.2/etc/hadoop/core-site.xml
<property>
<name>fs.defaultFS</name>
<value>hdfs://hadoop2:9000</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/usr/hadoop-2.9.2/data</value>
</property>
注意:在配置core-site.xml時(shí)想要使那臺(tái)節(jié)點(diǎn)作為NameNode節(jié)點(diǎn),就在配置文件中使用那個(gè)節(jié)點(diǎn)主機(jī)名作為fs.defaultFS的名字使用,圖中使用的是Hadoop2作為NameNode,所以配置全部為Hadoop2
# 9.配置三臺(tái)機(jī)器hdfs-site.xml配置文件
vim /usr/hadoop-2.9.2/etc/hadoop/hdfs-site.xml
注意:這里將副本數(shù)量修改為了3份,默認(rèn)配置也是3份
# 10.配置三個(gè)機(jī)器slaves文件
vim /usr/hadoop-2.9.2/etc/hadoop/slaves
hadoop2
hadoop3
hadoop4
注意:slaves文件用來(lái)決定哪些節(jié)點(diǎn)為datanode,因?yàn)镠adoop2節(jié)點(diǎn)既要是NameNode也要是DataNode因此也要講hadoop2放在salves文件中,這樣才會(huì)認(rèn)為自己也是一個(gè)dataNode節(jié)點(diǎn)
# 4.在hadoop2節(jié)點(diǎn)上進(jìn)行Namenode格式化
[root@hadoop2 ~]# hdfs namenode -format
# 5.啟動(dòng)hdfs集群
在hadoop2上執(zhí)行: start-dfs.sh 關(guān)閉使用: stop-dfs.sh
# 6.查看各個(gè)節(jié)點(diǎn)進(jìn)程
# 7.上傳文件到hdfs上測(cè)試
七.ZK搭建高可用HDFS集群
7.1 原理解析
QJM(Quorum Journal Manager)是Hadoop專(zhuān)門(mén)為Namenode共享存儲(chǔ)開(kāi)發(fā)的組件讶凉。其集群運(yùn)行一組Journal Node染乌,每個(gè)Journal 節(jié)點(diǎn)暴露一個(gè)簡(jiǎn)單的RPC接口,允許Namenode讀取和寫(xiě)入數(shù)據(jù)懂讯,數(shù)據(jù)存放在Journal節(jié)點(diǎn)的本地磁盤(pán)荷憋。當(dāng)Namenode寫(xiě)入edit log時(shí),它向集群的所有Journal Node發(fā)送寫(xiě)入請(qǐng)求褐望,當(dāng)多數(shù)節(jié)點(diǎn)回復(fù)確認(rèn)成功寫(xiě)入之后勒庄,edit log就認(rèn)為是成功寫(xiě)入。例如有3個(gè)Journal Node瘫里,Namenode如果收到來(lái)自2個(gè)節(jié)點(diǎn)的確認(rèn)消息实蔽,則認(rèn)為寫(xiě)入成功。
而在故障自動(dòng)轉(zhuǎn)移的處理上谨读,引入了監(jiān)控Namenode狀態(tài)的ZookeeperFailController(ZKFC)盐须。ZKFC一般運(yùn)行在Namenode的宿主機(jī)器上,與Zookeeper集群協(xié)作完成故障的自動(dòng)轉(zhuǎn)移漆腌。整個(gè)集群架構(gòu)圖如下:
7.2 搭建HDFS高可用集群
# 0.集群規(guī)劃 和 環(huán)境準(zhǔn)備
hadoop1 10.15.0.5 ---(zk cluster 這里zk集群放在單獨(dú)一臺(tái)機(jī)器搭建的是一個(gè)偽分布式,我們重點(diǎn)關(guān)注hdfs集群)
hadoop2 10.15.0.6 --- namenode(active) & datanode & DFSZKFailoverController(zkfc) & journalnode
hadoop3 10.15.0.7 --- datanode & namenode(standby) & DFSZKFailoverController(zkfc) & journalnode
hadoop4 10.15.0.8 --- datanode & journalnode
環(huán)境準(zhǔn)備: centos7.x 必須安裝: yum install psmisc -y
1.修改Linux主機(jī)名
2.修改IP
3.修改主機(jī)名和IP的映射關(guān)系 /etc/hosts
4.關(guān)閉防火墻
5.ssh免登陸
6.安裝JDK,配置環(huán)境變量等 省略
# 1.安裝zk(在一個(gè)機(jī)器上實(shí)現(xiàn)zk集群)
# 2.準(zhǔn)備3個(gè)數(shù)據(jù)存放目錄
mkdir -p /root/zkdata1
mkdir -p /root/zkdata2
mkdir -p /root/zkdata3
# 3.在每個(gè)數(shù)據(jù)文件夾中準(zhǔn)備一個(gè)myid文件
touch /root/zkdata1/myid
touch /root/zkdata2/myid
touch /root/zkdata3/myid
# 4.編輯每個(gè)data目錄中myid
vim /root/zkdata1/myid 輸入 1
vim /root/zkdata2/myid 輸入 2
vim /root/zkdata3/myid 輸入 3
# 5.將zk配置文件復(fù)制三份到zkdata目錄中
cp zk安裝目錄中/conf/zoo.cfg /root/zkdata1
cp zk安裝目錄中/conf/zoo.cfg /root/zkdata2
cp zk安裝目錄中/conf/zoo.cfg /root/zkdata3
# 6.分別修改zkdata目錄中zoo.cfg配置端口號(hào)和數(shù)據(jù)目錄位置
-
配置節(jié)點(diǎn)1 vim /root/zkdata1/zoo.cfg
tickTime=2000 initLimit=10 syncLimit=5 dataDir=/root/zkdata clientPort=3001 server.1=主機(jī)名:3002:3003 server.2=主機(jī)名:4002:4003 server.3=主機(jī)名:5002:5003
-
配置節(jié)點(diǎn)2 vim /root/zkdata2/zoo.cfg
tickTime=2000 initLimit=10 syncLimit=5 dataDir=/root/zkdata clientPort=4001 server.1=主機(jī)名:3002:3003 server.2=主機(jī)名:4002:4003 server.3=主機(jī)名:5002:5003
-
配置節(jié)點(diǎn)3 vim /root/zkdata3/zoo.cfg
tickTime=2000 initLimit=10 syncLimit=5 dataDir=/root/zkdata clientPort=5001 server.1=主機(jī)名:3002:3003 server.2=主機(jī)名:4002:4003 server.3=主機(jī)名:5002:5003
# 7.啟動(dòng)zk節(jié)點(diǎn)
[root@c60 zookeeper]# ./bin/zkServer.sh start /root/zkdata1/zoo.cfg
[root@c60 zookeeper]# ./bin/zkServer.sh start /root/zkdata2/zoo.cfg
[root@c60 zookeeper]# ./bin/zkServer.sh start /root/zkdata3/zoo.cfg
# 8.查看zk角色信息
[root@c60 zookeeper]# ./bin/zkServer.sh status /root/zkdata1/zoo.cfg
# 9.查看其它3個(gè)hadoop機(jī)器主機(jī)名 回顧集群規(guī)劃
hadoop1 10.15.0.5 --- (zkcluster 上面我們已經(jīng)構(gòu)建zk集群)
hadoop2 10.15.0.6 --- namenode(active) & datanode & DFSZKFailoverController(zkfc)
hadoop3 10.15.0.7 --- datanode & namenode(standby) & DFSZKFailoverController(zkfc)
hadoop4 10.15.0.8 --- datanode
# 1.配置hadoop的core-site.xml 三個(gè)機(jī)器一致內(nèi)容如下:
vim /usr/hadoop-2.9.2/etc/hadoop/core-site.xml
<!--hdfs主要入口不再是一個(gè)具體機(jī)器而是一個(gè)虛擬的名稱(chēng) -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://ns</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/usr/hadoop-2.9.2/data</value>
</property>
<property>
<name>ha.zookeeper.quorum</name>
<value>hadoop1:3001,hadoop1:4001,hadoop1:5001</value>
</property>
<img src="https://upload-images.jianshu.io/upload_images/19301226-54c05119fed56846.png" alt="image-20191219133333624" />
注意:ha.zookeeper.quorum 用來(lái)指定zk集群的節(jié)點(diǎn)數(shù)
# 2.配置hdfs-site.xml
<!--指定hdfs的nameservice為ns阶冈,需要和core-site.xml中的保持一致 -->
<property>
<name>dfs.nameservices</name>
<value>ns</value>
</property>
<!-- ns下面有兩個(gè)NameNode闷尿,分別是nn1,nn2 -->
<property>
<name>dfs.ha.namenodes.ns</name>
<value>nn1,nn2</value>
</property>
<!-- nn1的RPC通信地址 -->
<property>
<name>dfs.namenode.rpc-address.ns.nn1</name>
<value>hadoop2:9000</value>
</property>
<!-- nn1的http通信地址 -->
<property>
<name>dfs.namenode.http-address.ns.nn1</name>
<value>hadoop2:50070</value>
</property>
<!-- nn2的RPC通信地址 -->
<property>
<name>dfs.namenode.rpc-address.ns.nn2</name>
<value>hadoop3:9000</value>
</property>
<!-- nn2的http通信地址 -->
<property>
<name>dfs.namenode.http-address.ns.nn2</name>
<value>hadoop3:50070</value>
</property>
<!-- 指定NameNode的元數(shù)據(jù)在JournalNode上的存放位置 -->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://hadoop2:8485;hadoop3:8485;hadoop4:8485/ns</value>
</property>
<!-- 指定JournalNode在本地磁盤(pán)存放數(shù)據(jù)的位置 -->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/root/journal</value>
</property>
<!-- 開(kāi)啟NameNode故障時(shí)自動(dòng)切換 -->
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
<!-- 配置失敗自動(dòng)切換實(shí)現(xiàn)方式 -->
<property>
<name>dfs.client.failover.proxy.provider.ns</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
<!-- 配置隔離機(jī)制女坑,如果ssh是默認(rèn)22端口填具,value直接寫(xiě)sshfence即可 -->
<property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
</property>
<!-- 使用隔離機(jī)制時(shí)需要ssh免登陸 -->
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/root/.ssh/id_rsa</value>
</property>
# 修改slaves文件指定哪些機(jī)器為DataNode
hadoop2
hadoop3
hadoop4
注意:由于配置內(nèi)容比較多,這里就不截圖了,保證三個(gè)機(jī)器配置一致即可
# 3.在任意一個(gè)namenode上執(zhí)行如下命令:
[root@hadoop2 ~]# hdfs zkfc -formatZK
# 4.啟動(dòng)journalnode(分別在在hadoop2、hadoop3匆骗、hadoop4上執(zhí)行)
[root@hadoop2 ~]# hadoop-daemon.sh start journalnode
[root@hadoop3 ~]# hadoop-daemon.sh start journalnode
[root@hadoop4 ~]# hadoop-daemon.sh start journalnode
使用:jps查看如過(guò)都出現(xiàn)如下進(jìn)程說(shuō)明啟動(dòng)成功
# 5.在hadoop2上執(zhí)行(NameNode active)節(jié)點(diǎn)執(zhí)行:
[root@hadoop2 ~]# hdfs namenode -format ns
# 6.啟動(dòng)hdfs集群
[root@hadoop2 ~]# start-dfs.sh
# 7.在standby 的 NameNode節(jié)點(diǎn)上執(zhí)行如下命令:
[root@hadoop3 ~]# hdfs namenode -bootstrapStandby
[root@hadoop14 ~]# hadoop-daemon.sh start namenode
注意:啟動(dòng)standby的NameNode的
# 8.查看namenode(standby) 進(jìn)程 和 hadoop4 進(jìn)程
-
namenode (standby)
image-20191219150554696 -
hadoop4 進(jìn)程
image-20191219150717780
# 9.訪(fǎng)問(wèn)namenode(active) 與 namenode(standby) hdfsweb界面
-
hadoop2(namenode active)
image-20191219150921231 -
Hadoop3 (standby namenode)
image-20191219151042812
# 10.停止正常NameNode進(jìn)行測(cè)試
[root@hadoop2 ~]# jps
7426 DFSZKFailoverController
8499 NameNode
8631 Jps
7128 DataNode
5519 JournalNode
[root@hadoop2 ~]# kill 8499
[root@hadoop2 ~]# jps
7426 DFSZKFailoverController
7128 DataNode
8669 Jps
5519 JournalNode
-
hadoop2(namenode down)
image-20191219152146516 -
hadoop3(namenode active)
image-20191219152244403
八. MapReduce
8.1 計(jì)算
? 計(jì)算實(shí)際上也可以說(shuō)是統(tǒng)計(jì)和分析,就是在大量的數(shù)據(jù)集中通過(guò)計(jì)算從而統(tǒng)計(jì)劳景、分析出我們關(guān)注的數(shù)據(jù),從而為我們創(chuàng)造相應(yīng)的價(jià)值
8.2 如何解決大規(guī)模數(shù)據(jù)計(jì)算問(wèn)題
- 抽樣統(tǒng)計(jì)分析 ------> 結(jié)果不準(zhǔn)確
- 全部數(shù)據(jù)統(tǒng)計(jì) -------> 計(jì)算機(jī)性能要求極高
MapReduce就更好的解決了我們?cè)谔幚泶髷?shù)據(jù)集的計(jì)算問(wèn)題
8.2 MapReduce 引言
? MapReduce是hadoop體系下的一種計(jì)算模型(計(jì)算框架|編程框架),主要是用來(lái)對(duì)存儲(chǔ)在hdfs上的數(shù)據(jù)進(jìn)行統(tǒng)計(jì),分析的碉就。
8.3 MapReduce的核心思想
Map Reduce:
計(jì)算框架分為兩個(gè)部分: Map (局部統(tǒng)計(jì)) 和 Reduce (局部統(tǒng)計(jì),匯總計(jì)算)
Yarn:
資源調(diào)度,任務(wù)監(jiān)控 主要用來(lái)整合hadoop集群中的資源(CPU 內(nèi)存),進(jìn)行統(tǒng)一調(diào)度 同時(shí)監(jiān)控任務(wù)的執(zhí)行情況
Job作業(yè):
一組MapReduce又統(tǒng)稱(chēng)為一個(gè)Job作業(yè)盟广,在一個(gè)Hadoop集群中有很多job作業(yè)。
8.4 搭建yarn集群
8.4.1 配置mapred-site.xml
# 0.啟動(dòng)hdfs集群
# 1.復(fù)制 cp hadoop-2.9.2/etc/hadoop/mapred-site.xml.template hadoop-2.9.2/etc/hadoop/mapred-site.xml
# 2.編輯 vim hadoop-2.9.2/etc/hadoop/mapred-site.xml添加配置
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
8.4.2 配置yarn-site.xml
# 1.編輯 添加如下配置:
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.resourcemanager.hostname</name>
<value>Hadoop</value>
</property>
上述yarn.resourcemanager.hostname配置中的:
hadoop
為當(dāng)前機(jī)器的主機(jī)名
8.4.3 啟動(dòng)yarn
[root@hadoop hadoop]# start-yarn.sh
starting yarn daemons
starting resourcemanager, logging to /root/hadoop-2.9.2/logs/yarn-root-resourcemanager-hadoop.out
hadoop: starting nodemanager, logging to /root/hadoop-2.9.2/logs/yarn-root-nodemanager-hadoop.out
8.4.4 是否啟動(dòng)成功
[root@hadoop hadoop]# jps
4897 Jps
4724 NodeManager
3542 SecondaryNameNode
3367 DataNode
4619 ResourceManager
3229 NameNode
如果出現(xiàn)
NodeManager
和ResourceManager
這兩個(gè)進(jìn)程說(shuō)明配置成功
8.4.5 mapreduce的web監(jiān)控頁(yè)面
http://10.15.0.4:8088/cluster
8.5 Job 作業(yè)總體流程
8.6 World Count 第一個(gè)案例
8.6.1 什么是Word Count
? 說(shuō)明: World Count 簡(jiǎn)單說(shuō)也叫單詞計(jì)數(shù)統(tǒng)計(jì),就是在一個(gè)文件中統(tǒng)計(jì)出每個(gè)單詞出現(xiàn)的次數(shù) 如圖:
?- 說(shuō)明: 解決上述問(wèn)題,實(shí)際上使用曾經(jīng)的 Core Java就可以很快的計(jì)算出來(lái),為什么需要Hadoop呢?注意:如果數(shù)據(jù)非常少我們可以很快計(jì)算,但是如果數(shù)據(jù)非常大有1TB或者10TB這樣的大文件我們可能很難計(jì)算結(jié)果瓮钥。這個(gè)使用我們?nèi)绻柚鶫adoop為我們提供的Map Reduce 我們就能很好解決這個(gè)問(wèn)題筋量!
8.6.2 使用Map Reduce 完成 Word Count 的思路分析
8.6.3 Map Reduce 的第一個(gè)程序
-
準(zhǔn)備數(shù)據(jù)上傳的HDFS中
chenyn xiaohei xiaowang chenyn zhaoliu wangwu zhangsan xiaoming xiaochen chenyn chenyn xiaozhang xiaohei xiaoliu xiaozi xiaosun xiaochen
[root@hadoop5 ~]# touch data [root@hadoop5 ~]# vim data [root@hadoop5 ~]# hdfs dfs -mkdir -p /wordcount [root@hadoop5 ~]# hdfs dfs -put data /wordcount/data [root@hadoop5 ~]# hdfs dfs -cat /wordcount/data chenyn xiaohei xiaowang chenyn zhaoliu wangwu zhangsan xiaoming xiaochen chenyn chenyn xiaozhang xiaohei xiaoliu xiaozi xiaosun xiaochen
image-20191221102907540image-20191221102941296
-
引入依賴(lài)
<properties> <hadoop.version>2.9.2</hadoop.version> </properties> <dependencies> <!--hadoop公共依賴(lài)--> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-common</artifactId> <version>${hadoop.version}</version> </dependency> <!--hadoop client 依賴(lài)--> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-hdfs</artifactId> <version>${hadoop.version}</version> </dependency> <!--junit--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <!--map reduce--> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-mapreduce-client-core</artifactId> <version>${hadoop.version}</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-mapreduce-client-common</artifactId> <version>${hadoop.version}</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-mapreduce-client-jobclient</artifactId> <version>2.9.2</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> </dependencies>
-
開(kāi)發(fā)Job作業(yè)編碼
//word count job作業(yè)開(kāi)發(fā) public class WordCountJob extends Configured implements Tool { public static void main(String[] args) throws Exception { ToolRunner.run(new WordCountJob(),args); } @Override public int run(String[] strings) throws Exception { //創(chuàng)建job作業(yè) Configuration conf = getConf(); Job job = Job.getInstance(conf); job.setJarByClass(WordCountJob.class); //設(shè)置Input Format job.setInputFormatClass(TextInputFormat.class); TextInputFormat.addInputPath(job,new Path("/wordcount/data")); //設(shè)置map階段 job.setMapperClass(WordCountMap.class); job.setMapOutputKeyClass(Text.class); job.setMapOutputValueClass(IntWritable.class); //設(shè)置Shuffle 階段 默認(rèn) //設(shè)置reduce 階段 job.setReducerClass(WordCountReduce.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); //設(shè)置 Output Formate job.setOutputFormatClass(TextOutputFormat.class); //注意:要求結(jié)果目錄不能存在 FileSystem fileSystem = FileSystem.get(conf); Path res = new Path("/wordcount/res"); if(fileSystem.exists(res)) { fileSystem.delete(res,true); } TextOutputFormat.setOutputPath(job, res); //提交job作業(yè) boolean b = job.waitForCompletion(true); System.out.println("作業(yè)執(zhí)行狀態(tài) = " + b); return 0; } //開(kāi)發(fā)Map階段 public static class WordCountMap extends Mapper<LongWritable, Text,Text, IntWritable>{ @Override protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { //value 就是讀入的一行數(shù)據(jù) String[] keys = value.toString().split(" "); for (String word : keys) { context.write(new Text(word),new IntWritable(1)); } } } //開(kāi)發(fā)Reduce階段 public static class WordCountReduce extends Reducer<Text,IntWritable,Text,IntWritable>{ @Override protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { int sum = 0; for (IntWritable value : values) { sum+=value.get(); } context.write(key,new IntWritable(sum)); } } }
注意:在執(zhí)行mapreduce作業(yè)過(guò)程中,一定涉及到數(shù)據(jù)數(shù)據(jù)的序列化,hadoop對(duì)原始基本數(shù)據(jù)類(lèi)型進(jìn)行了二次包裝
hadoop中包裝類(lèi)型 java原始數(shù)據(jù)類(lèi)型 Text String LongWritable Long IntWritable Integer FloatWritable Float DoubleWritable Double -
將wordcount打成jar包
image-20191221111624981 -
上傳到hadoop集群并執(zhí)行wordcount jar包
[root@hadoop5 ~]# hadoop jar hadoop_wrodcount-1.0-SNAPSHOT.jar com.baizhi.wordcount.WordCountJob
Xnip2019-12-21_11-45-01 -
查看執(zhí)行結(jié)果
image-20191221114704335[root@hadoop5 ~]# hdfs dfs -text /wordcount/res/part-r-00000 chenyn 4 wangwu 1 xiaochen 2 xiaohei 2 xiaoliu 1 xiaoming 1 xiaosun 1 xiaowang 1 xiaozhang 1 xiaozi 1 zhangsan 1 zhaoliu 1
image-20191221114847995
8.7 MapReduce 自動(dòng)化運(yùn)行配置
8.7.1 打包時(shí)指定main Class信息
默認(rèn)直接通過(guò)maven插件打成jar包中沒(méi)有指定main class 信息,因此在運(yùn)行mapreduce的jar包時(shí)必須在指令后面明確指定main class 的信息是誰(shuí),這樣日后在執(zhí)行mapreduce作業(yè)時(shí)會(huì)加大執(zhí)行的難度,因此我們需要在打jar包時(shí)指定main class信息,減少執(zhí)行作業(yè)時(shí)的操作,如果需要在打包中指定main class 信息:只需要對(duì)打包插件進(jìn)行配置即可:
<build>
<plugins>
<!-- 在打包插件中指定main class 信息 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<outputDirectory>${basedir}/target</outputDirectory>
<archive>
<manifest>
<mainClass>com.baizhi.wordcount.WordCountJob</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
加入上述配置之后再打包,日后就可以直接執(zhí)行jar包,不需要額外指定main class 信息:
執(zhí)行命令: clean package
8.7.2 使用wagon插件實(shí)現(xiàn)自動(dòng)上傳至hadoop集群
<build>
<!--擴(kuò)展maven的插件中加入ssh插件-->
<extensions>
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ssh</artifactId>
<version>2.8</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>wagon-maven-plugin</artifactId>
<version>1.0</version>
<configuration>
<fromFile>target/test.jar 或者 ${project.build.finalName}.jar</fromFile>
<url>scp://user:password@192.168.20.128/root</url>
</configuration>
</plugin>
</plugins>
</build>
打包后直接執(zhí)行wagon uplod-single
即可:
執(zhí)行命令操作: clean package wagon:upload-single
8.7.3 使用wagon上傳jar完成后遠(yuǎn)程執(zhí)行job作業(yè)
wagon配置加入commands命令
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>wagon-maven-plugin</artifactId>
<version>1.0</version>
<configuration>
<fromFile>target/${project.build.finalName}.jar</fromFile>
<url>scp://root:1@10.15.0.5/root</url>
<commands>
<!-- 通過(guò)sh 執(zhí)行shell腳本文件 -->
<command>nohup hadoop-2.9.2/bin/hadoop jar hadoop_wordcount-1.0-SNAPSHOT.jar > /root/mapreduce.out 2>&1 & </command>
</commands>
<displayCommandOutputs>true</displayCommandOutputs>
</configuration>
</plugin>
執(zhí)行命令操作:clean package wagon:upload-single wagon:sshexec
任務(wù)執(zhí)行成功:
8.8 配置歷史服務(wù)器調(diào)試Map Reduce
8.8.1 配置mapped-site.xml 并同步集群配置
<property>
<name>mapreduce.jobhistory.address</name>
<value>hadoop5:10020</value>
</property>
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>hadoop5:19888</value>
</property>
8.8.2 配置yarn-site.xml 并同步集群配置
<!--開(kāi)啟日志聚合-->
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<!--日志保存時(shí)間 單位秒 這里是7天-->
<property>
<name>yarn.log-aggregation.retain-seconds</name>
<value>604800</value>
</property>
8.8.3 啟動(dòng)歷史服務(wù)器
[root@hadoop6 ~]# mr-jobhistory-daemon.sh start historyserver
[root@hadoop6 ~]# mr-jobhistory-daemon.sh stop historyserver