建筑工程外架安全網(wǎng)西安的網(wǎng)絡(luò)優(yōu)化公司
前言(全部為語(yǔ)雀導(dǎo)出,個(gè)人所寫(xiě),僅用于學(xué)習(xí)!!!!)
復(fù)習(xí)之前我們要有目的性,明確考什么,不考什么。對(duì)于hadoop來(lái)說(shuō),首先理論方面是跑不掉的,而且還是重中之重。例如:hdfs的讀寫(xiě)流程,hdfs副本機(jī)制等等。其次是hadoop命令,如果學(xué)習(xí)了hadoop不了解hadoop dfs …和hdfs dfs …那么你可以重修了。最后要明確那一部分會(huì)出什么題。
下面背景色或者字體改變的背過(guò)就完了。
一 初始Hadoop部分(了解)
這一章主要考點(diǎn)如下:1.大數(shù)據(jù)技術(shù)的5V特征是什么?(選擇,簡(jiǎn)答)
容量(Volume):數(shù)據(jù)的大小決定所考慮的數(shù)據(jù)的價(jià)值和潛在的信息
種類(Variety):數(shù)據(jù)類型的多樣性
速度(Velocity):指獲得數(shù)據(jù)的速度
可變性(Variability):妨礙了處理和有效地管理數(shù)據(jù)的過(guò)程
真實(shí)性(Veracity):數(shù)據(jù)的質(zhì)量
2.大數(shù)據(jù)包括特點(diǎn)是(選擇,簡(jiǎn)答)
海量數(shù)據(jù)處理;多結(jié)構(gòu)化數(shù)據(jù);增長(zhǎng)速度快;價(jià)值密度低。
3.Hadoop的創(chuàng)始人是誰(shuí)?(選擇)
Doug Cutting。
擴(kuò)充:以下項(xiàng)目中,哪個(gè)不是由Doug Cutting所創(chuàng)立的()。
A、Hadoop B、Nutch C、Lucene D、Solr
4.Hadoop 的框架最核心的設(shè)計(jì):HDFS(存儲(chǔ))和 MapReduce(計(jì)算)?;蛘邌?wèn)Hadoop核心三大組件是:HDFS 、MapReduce 和 YARN。(填空)
注意:兩個(gè)就沒(méi)YARN,三個(gè)就有。
5.Hadoop 物理架構(gòu):Master-Slave 架構(gòu)。(選擇、填空)
6.Hadoop 的優(yōu)點(diǎn)? (簡(jiǎn)答)
高可靠性:Hadoop按位存儲(chǔ)和處理數(shù)據(jù)的能力值得人們信賴。
高效性:Hadoop能夠在節(jié)點(diǎn)之間動(dòng)態(tài)地移動(dòng)數(shù)據(jù),并保證各個(gè)節(jié)點(diǎn)的動(dòng)態(tài)平衡,因此處理速度非???。
高擴(kuò)展性:Hadoop是在可用的計(jì)算機(jī)集蔟間分配數(shù)據(jù)并完成計(jì)算任務(wù)的,這些集蔟可以方便地?cái)U(kuò)展到數(shù)以千計(jì)的節(jié)點(diǎn)。
高容錯(cuò)性:Hadoop能夠自動(dòng)保存數(shù)據(jù)的多個(gè)副本,并且能夠自動(dòng)將失敗的任務(wù)重新分配。
7.請(qǐng)列舉幾個(gè)Hadoop生態(tài)圈里的組件并簡(jiǎn)述其作用?(簡(jiǎn)答)最少記住四個(gè)標(biāo)黃的
HDFS :分布式文件系統(tǒng),用于存儲(chǔ)大規(guī)模數(shù)據(jù),具備高容錯(cuò)性。
MapReduce:編程模型和計(jì)算框架,用于批量處理大數(shù)據(jù),分為 Map 和 Reduce 階段。
YARN :資源管理和調(diào)度系統(tǒng),負(fù)責(zé)集群資源的分配和任務(wù)調(diào)度。
Hive:數(shù)據(jù)倉(cāng)庫(kù)工具,使用類 SQL 查詢語(yǔ)言進(jìn)行數(shù)據(jù)分析和處理。
HBase:分布式 NoSQL 數(shù)據(jù)庫(kù),支持實(shí)時(shí)隨機(jī)數(shù)據(jù)訪問(wèn)。
Spark:快速的計(jì)算引擎,支持批處理和流式處理,更高效于 MapReduce。
ZooKeeper:集群協(xié)調(diào)服務(wù),處理分布式應(yīng)用程序的同步和狀態(tài)管理。
二 Hadoop3.x 環(huán)境搭建(附實(shí)驗(yàn)考點(diǎn))(重點(diǎn))
1.目前,[ Hadoop](https://so.csdn.net/so/search?q=Hadoop&spm=1001.2101.3001.7020) 的最高版本是Hadoop3.x。(選擇)2.Hadoop有三種運(yùn)行模式,分別是:單機(jī)(本地)模式,偽分布式模式,全分布式模式。(選擇)
運(yùn)行模式 | 說(shuō)明 | 使用場(chǎng)景 | 配置要求 |
---|---|---|---|
單機(jī)模式(Local Mode) | 所有Hadoop組件在單個(gè)進(jìn)程中運(yùn)行,沒(méi)有啟動(dòng)守護(hù)進(jìn)程。 | 開(kāi)發(fā)和測(cè)試小規(guī)模的Hadoop應(yīng)用,快速驗(yàn)證程序邏輯。 | 配置簡(jiǎn)單,不需要復(fù)雜的集群設(shè)置。 |
偽分布式模式(Pseudo-Distributed Mode) | 模擬分布式環(huán)境,Hadoop守護(hù)進(jìn)程(如NameNode、DataNode等)作為獨(dú)立進(jìn)程運(yùn)行。 | 進(jìn)行全面的測(cè)試,適合HDFS的文件輸入輸出操作和內(nèi)存檢查。 | 需配置Hadoop的配置文件(如core-site.xml、hdfs-site.xml)以模擬多節(jié)點(diǎn)環(huán)境。 |
全分布式模式(Fully-Distributed Mode) | 在多臺(tái)機(jī)器上運(yùn)行,每臺(tái)機(jī)器作為獨(dú)立節(jié)點(diǎn),運(yùn)行不同的Hadoop守護(hù)進(jìn)程。 | 生產(chǎn)環(huán)境和大規(guī)模數(shù)據(jù)處理,充分利用集群資源。 | 配置每臺(tái)機(jī)器,包括網(wǎng)絡(luò)設(shè)置、SSH無(wú)密碼登錄等。 |
補(bǔ)充:關(guān)于Hadoop單機(jī)模式和偽分布式模式的說(shuō)法,正確的是(D)
A. 兩者都起守護(hù)進(jìn)程,且守護(hù)進(jìn)程運(yùn)行在一臺(tái)機(jī)器上
B. 單機(jī)模式不使用HDFS,但加載守護(hù)進(jìn)程
C. 兩者都不與守護(hù)進(jìn)程交互,避免復(fù)雜性
D. 后者比前者增加了HDFS輸入輸出以及可檢查內(nèi)存使用情況
以下哪一項(xiàng)不屬于 Hadoop 可以運(yùn)行的模式(C)。
A、單機(jī)(本地)模式 B、偽分布式模式
C、互聯(lián)網(wǎng)模式 D、全分布式模式
3.Hadoop集群配置文件及其作用。(選擇)這幾個(gè)都要背過(guò)必考類型
配置文件 | 修改內(nèi)容 | 可修改參數(shù) |
---|---|---|
hadoop-env.sh | 配置 JDK 環(huán)境變量 | <font style="background-color:#FBDE28;">JAVA_HOME</font> |
core-site.xml | 配置 HDFS 地址和臨時(shí)文件目錄 | <font style="background-color:#FBDE28;">fs.defaultFS</font> , hadoop.tmp.dir |
hdfs-site.xml | 配置 HDFS 上的 NameNode 和 DataNode 設(shè)置 | dfs.replication , dfs.namenode.name.dir , dfs.datanode.data.dir |
mapred-site.xml | 指定 MapReduce運(yùn)行時(shí)框架 | mapreduce.framework.name |
yarn-site.xml | 配置 ResourceManager 和 NodeManager | yarn.resourcemanager.address , yarn.nodemanager.aux-services |
slaves | 記錄所有從節(jié)點(diǎn)的主機(jī)名 | 列出每個(gè)從節(jié)點(diǎn)的主機(jī)名 |
補(bǔ)充例:
在配置Hadoop時(shí),經(jīng)常會(huì)在下面哪一個(gè)文件中配置JAVA_HOME(c)。
A、hadoop-default.xml B、hadoop-site.xml
C、hadoop-env.sh D、configuration.xsl
HDFS默認(rèn)的當(dāng)前工作目錄是/user/$USER,fs.default.name的值需要在哪個(gè)配置文件內(nèi)說(shuō)明。(B)**
A. mapred-site.xml B. core-site.xml
C. hdfs-site.xml **D. 以上均不是
4.搭建環(huán)境時(shí)比較重要命令。(選擇,填空,簡(jiǎn)答)
(1 讓新的linux環(huán)境變量生效:source /etc/profile
(2 進(jìn)行初始化命令:hdfs namenode -format
(3 單節(jié)點(diǎn)逐個(gè)啟動(dòng):
在主節(jié)點(diǎn)上啟動(dòng)HDFS namenode進(jìn)程:hadoop-daemon.sh start namenode
在從節(jié)點(diǎn)上使用指令啟動(dòng) HDFS DataNode進(jìn)程 :hadoop-daemon.sh start DataNode
在主節(jié)點(diǎn)上使用指令啟動(dòng)Yarn RecourseManager進(jìn)程:yarn-daemon.sh start recoursemanager
在每個(gè)節(jié)點(diǎn)上從節(jié)點(diǎn)上使用指令啟動(dòng)Yarn nodemanager進(jìn)程:yarn-daemon.sh start nodemanager
在規(guī)劃節(jié)點(diǎn)Hadoop02使用指令啟動(dòng)SecondaryNameNode:hadoop-daemon.sh start secondarynamenode
(4 腳本一鍵啟動(dòng)和關(guān)閉全部守護(hù)進(jìn)程
在主節(jié)點(diǎn)Hadoop上使用指令啟動(dòng)所有HDFS服務(wù)進(jìn)程:start-dfs.sh
在主節(jié)點(diǎn)Hadoop01上使用指令啟動(dòng)所有Yarn服務(wù)進(jìn)程:start-yarn.sh
將以上指令start改為stop就為關(guān)閉服務(wù)命令
(5 查看master上啟動(dòng)的5個(gè)NameNode、DataNode、SecondaryNameNode、NodeManager、ResourceManager守護(hù)進(jìn)程:jps
注:這里只有搭建環(huán)境部分,剩余內(nèi)容再第六,第七章。
補(bǔ)充例:Hadoop集群?jiǎn)为?dú)啟動(dòng)NameNode進(jìn)程的命令是(c)。
A、./start-namenode.sh
B、./start-all.sh start namenode
C、./hadoop-daemon.sh start namenode
D、./hadoop-daemons.sh start namenode
三 認(rèn)識(shí)HDFS分布式文件系統(tǒng)(核心)
1.HDFS是分布式文件系統(tǒng),根據(jù)Google發(fā)表的論文 GFS建立起來(lái)的。(選擇,填空)補(bǔ)充例:下面與HDFS類似的框架是(B)。
A、EXT3 B、GFS C、NTFS D、FAT32
2.HDFS的優(yōu)勢(shì):(簡(jiǎn)答)
(1 大數(shù)據(jù)處理:HDFS 默認(rèn)會(huì)將文件分割成 Block,以 128MB (默認(rèn))為 1 個(gè) Block,然后按鍵值對(duì)存儲(chǔ)在 HDFS 上,并將鍵值對(duì)的映射存儲(chǔ)到內(nèi)存中。如果小文件太多,那么內(nèi)存負(fù)擔(dān)會(huì)很重。
(2 流式數(shù)據(jù)訪問(wèn):一次寫(xiě)入,多次讀取是最高效的訪問(wèn)模式。因此,讀取整個(gè)數(shù)據(jù)集的時(shí)間延遲比讀取第一條記錄的時(shí)間延遲更重要。
(3 商?硬件:Hadoop 被設(shè)計(jì)運(yùn)行在商?硬件的集群上,并通過(guò)保存多個(gè)副本的形式提供冗余的容錯(cuò)機(jī)制,且副本丟失或宕機(jī)會(huì)自動(dòng)恢復(fù)。默認(rèn)保存的副本數(shù)為 3 個(gè)。
補(bǔ)充:例下列選項(xiàng)中,Hadoop集群的主要瓶頸是(B)。
A、CPU B、磁盤(pán)IO C、網(wǎng)絡(luò) D、內(nèi)存
3.HDFS的局限性:(簡(jiǎn)答)
(1)不能進(jìn)行低時(shí)間延遲的數(shù)據(jù)訪問(wèn):HDFS是為高數(shù)據(jù)吞吐量應(yīng)用優(yōu)化的,以提高時(shí)間延遲為代價(jià)。<font style="background-color:#F9EFCD;">HDFS要求低時(shí)間延遲數(shù)據(jù)訪問(wèn)的應(yīng)用不適合在HDFS上運(yùn)行。</font>(2)不能存儲(chǔ)大量的小文件:由于NameNode將文件系統(tǒng)的元數(shù)據(jù)存儲(chǔ)在內(nèi)存中,因此該文件系統(tǒng)所能存儲(chǔ)的文件總數(shù)受限于NameNode的內(nèi)存容量。每個(gè)文件、目錄和數(shù)據(jù)塊的存儲(chǔ)信息大約占150個(gè)字節(jié)。因此,舉例來(lái)說(shuō),如果有一百萬(wàn)個(gè)文件,且每個(gè)文件占一個(gè)數(shù)據(jù)塊,那至少需要300MB的內(nèi)存。但是如果存儲(chǔ)數(shù)據(jù)十億的文件就超出了當(dāng)前硬件的能力。<font style="background-color:#F9EFCD;">所以存儲(chǔ)文件時(shí)盡量將小文件合并成較大的文件。</font>(3)不支持并發(fā)寫(xiě)入、文件隨機(jī)修改:一個(gè)文件只能有一個(gè)寫(xiě),不允許多個(gè)線程同時(shí)寫(xiě);僅支持?jǐn)?shù)據(jù)append(追加),不支持文件的隨機(jī)修改,這種限制使得<font style="background-color:#F9EFCD;">HDFS不適合需要頻繁修改文件內(nèi)容的應(yīng)用。</font>
補(bǔ)充:
(1 請(qǐng)例舉出不適用HDFS的場(chǎng)景。
低延遲數(shù)據(jù)訪問(wèn)需求;大量小文件存儲(chǔ);需要高并發(fā)寫(xiě)入;需要隨機(jī)修改文件內(nèi)容。
(2 HDFS無(wú)法高效存儲(chǔ)大量小文件,想讓它能處理好小文件,比較可行的改進(jìn)策略不包括(D)
A. 利用SequenceFile、MapFile、Har等方式歸檔小文件。
B. 多Master設(shè)計(jì)。
C. Block大小適當(dāng)調(diào)小。
D. 調(diào)大namenode內(nèi)存或?qū)⑽募到y(tǒng)元數(shù)據(jù)存到硬盤(pán)里。
4.HDFS的特性:(了解有印象即可,不大好出題,可能會(huì)簡(jiǎn)答,但是過(guò)于簡(jiǎn)單,最好記下幾條)
高度容錯(cuò),可擴(kuò)展性及可配置性強(qiáng)。
跨平臺(tái)。使用Java語(yǔ)言開(kāi)發(fā),以JVM為運(yùn)行環(huán)境,支持多個(gè)主流平臺(tái)的環(huán)境。
Shell命令接口。HDFS擁有一套文件系統(tǒng)操作的Shell命令,可以用來(lái)直接操作HDFS文件系統(tǒng)。Web管理平臺(tái)。NameNode和DataNode內(nèi)置有Web服務(wù)器,方便用戶檢查集群的當(dāng)前運(yùn)行狀態(tài)。文件權(quán)限管理。Hadoop分布式文件系統(tǒng)實(shí)現(xiàn)了一個(gè)和POSIX系統(tǒng)類似的文件和目錄的權(quán)限模型。每個(gè)文件和目錄有一個(gè)所有者(owner)和一個(gè)組(group)。文件或目錄對(duì)其所有者、同組的其他用戶以及所有其他用戶分別有不同的權(quán)限。機(jī)架感知功能。機(jī)架感知功能使得Hadoop在任務(wù)調(diào)度和分配存儲(chǔ)空間時(shí)系統(tǒng)會(huì)考慮節(jié)點(diǎn)的物理位置,從而實(shí)現(xiàn)高效的訪問(wèn)和計(jì)算。安全模式。安全模式是Hadoop的一種保護(hù)機(jī)制,用于保證集群中的數(shù)據(jù)塊的安全性。集群維護(hù)時(shí)進(jìn)入這種管理模式。當(dāng)集群?jiǎn)?dòng)時(shí)會(huì)首先進(jìn)入安全模式。當(dāng)系統(tǒng)處于安全模式時(shí)會(huì)檢查數(shù)據(jù)塊的完整性。Rebalancer功能。當(dāng)DataNode之間數(shù)據(jù)不均衡時(shí),可以平衡集群上的數(shù)據(jù)負(fù)載,實(shí)現(xiàn)數(shù)據(jù)負(fù)載均衡。允許升級(jí)和回滾。在軟件更新后有異常情況發(fā)生時(shí),HDFS允許系統(tǒng)回滾到更新或升級(jí)之前的狀態(tài)。
5.HDFS的設(shè)計(jì)目標(biāo):(了解有印象即可,不大好出題,可能會(huì)簡(jiǎn)答,但是過(guò)于簡(jiǎn)單,最好記下幾條)
檢測(cè)和快速恢復(fù)硬件故障:硬件錯(cuò)誤是常態(tài)而不是異常。因此錯(cuò)誤檢測(cè)和快速、自動(dòng)的恢復(fù)是HDFS最核心的架構(gòu)目標(biāo)。流式數(shù)據(jù)訪問(wèn):運(yùn)行在HDFS上的應(yīng)用和普通的應(yīng)用不同,需要流式訪問(wèn)它們的數(shù)據(jù)集。比之?dāng)?shù)據(jù)訪問(wèn)的低延遲問(wèn)題,更關(guān)鍵的在于數(shù)據(jù)訪問(wèn)的高吞吐量。大規(guī)模數(shù)據(jù)集:運(yùn)行在HDFS上的應(yīng)用具有很大的數(shù)據(jù)集。因此,HDFS被調(diào)節(jié)以支持大文件存儲(chǔ)。簡(jiǎn)化一致的模型:“一次寫(xiě)入多次讀取”的文件訪問(wèn)模型。一個(gè)文件經(jīng)過(guò)創(chuàng)建、寫(xiě)入和關(guān)閉之后就不需要改變。這一假設(shè)簡(jiǎn)化了數(shù)據(jù)一致性問(wèn)題,并且使高吞吐量的數(shù)據(jù)訪問(wèn)成為可能。移動(dòng)計(jì)算的代價(jià)比移動(dòng)數(shù)據(jù)的代價(jià)低:一個(gè)應(yīng)用請(qǐng)求的計(jì)算,離它操作的數(shù)據(jù)越近就越高效,在數(shù)據(jù)達(dá)到海量級(jí)別的時(shí)候更是如此。因?yàn)檫@樣就能降低網(wǎng)絡(luò)阻塞的影響,提高系統(tǒng)數(shù)據(jù)的吞吐量。在不同的軟硬件平臺(tái)間的可移植性:HDFS在設(shè)計(jì)的時(shí)候就考慮到平臺(tái)的可移植性。這種特性方便了HDFS作為大規(guī)模數(shù)據(jù)應(yīng)用平臺(tái)的推廣。健壯性:在出錯(cuò)時(shí)也要保證數(shù)據(jù)存儲(chǔ)的可靠性。標(biāo)準(zhǔn)的通信協(xié)議:所有的HDFS通訊協(xié)議都是建立在TCP/IP協(xié)議之上??蛻舳送ㄟ^(guò)一個(gè)可配置的TCP端口連接到Namenode,通過(guò)ClientProtocol協(xié)議與Namenode交互。
6.HDFS核心概念:(超級(jí)重點(diǎn)必考全部要背過(guò),選擇,填空,簡(jiǎn)答都會(huì)考)
(1 數(shù)據(jù)塊:
默認(rèn)為 128MB(Hadoop 2.X);
可根據(jù)實(shí)際需求進(jìn)行配置,配置 hdfs-site.xml 文件中的 dfs.block.size 屬性;
HDFS上的文件劃分為數(shù)據(jù)塊,作為獨(dú)立的存儲(chǔ)單元,數(shù)據(jù)塊是HDFS文件系統(tǒng)存儲(chǔ)處理數(shù)據(jù)的最小單元;
儲(chǔ)存模式方式看下面你就明白了,200MB文件儲(chǔ)存,200/128=1個(gè)快+72MB,一共占用倆塊,這里需要注意的是HDFS中小于一個(gè)塊大小的文件并不會(huì)占據(jù)整個(gè)塊的空間,可以繼續(xù)用于儲(chǔ)存其他文件。
核心問(wèn)題1:為什么HDFS的數(shù)據(jù)塊如此之大?(理解版:核心問(wèn)題是效率,總時(shí)間=尋址時(shí)間+傳輸時(shí)間,尋址時(shí)間遠(yuǎn)大于傳輸時(shí)間,因此hdfs數(shù)據(jù)塊大。)
HDFS的數(shù)據(jù)塊比磁盤(pán)塊大,以最小化尋址開(kāi)銷。如果塊足夠大,從磁盤(pán)傳輸數(shù)據(jù)的時(shí)間將顯著大于定位塊起始位置的時(shí)間。因此,傳輸一個(gè)由多個(gè)塊組成的文件的時(shí)間主要取決于磁盤(pán)傳輸速率。然而,塊大小也不能過(guò)大,否則任務(wù)數(shù)可能少于集群節(jié)點(diǎn)數(shù)量,從而影響作業(yè)運(yùn)行速度。
例如:要傳輸100MB的數(shù)據(jù),假設(shè)尋址時(shí)間為10ms,而傳輸?shù)乃俾蕿?00MB/s:如果我們將塊大小設(shè)置為100MB,這時(shí)尋址的時(shí)間僅占傳輸時(shí)間的1%;如果將塊的大小設(shè)置為10MB,這時(shí)尋址的時(shí)間會(huì)占傳輸時(shí)間的10%。所以在允許的范圍內(nèi),增加塊的大小,可以有效縮短數(shù)據(jù)傳輸?shù)臅r(shí)間。
核心問(wèn)題2: 對(duì)分布式文件系統(tǒng)中的塊進(jìn)行抽象會(huì)帶來(lái)什么好處。
1.一個(gè)文件的大小可以大于集群中任意一個(gè)磁盤(pán)的容量
2.簡(jiǎn)化存儲(chǔ)子空間
3.塊還非常適合?于數(shù)據(jù)備份,提供數(shù)據(jù)冗余,進(jìn)而提高數(shù)據(jù)容錯(cuò)能力和提高可 ?性
補(bǔ)充例:
Hadoop2.0中HDFS 默認(rèn) Block Size(C)。
A. 32MB B. 64MB C. 128MB D. 256MB
一個(gè)gzip文件大小75MB,客戶端設(shè)置Block大小為64MB,請(qǐng)問(wèn)其占用幾個(gè)Block?(B)
A、3 B、2 C、4 D、1
如果一個(gè)Hadoop集群中HDFS的默認(rèn)大小是128MB,本地磁盤(pán)有個(gè)HDFS上的目錄包含100個(gè)純文本文件,每個(gè)文件200MB。如果使用TextInputFormat作為輸入格式類,將該目錄作為作業(yè)輸入,將會(huì)啟動(dòng)(C)個(gè)Map。
A. 64 B. 100 C. 200 D. 640
一個(gè)文件大小156MB,在Hadoop2.0中默認(rèn)情況下請(qǐng)問(wèn)其占用幾個(gè)Block(B)?
A. 1 B. 2 C. 3 D. 4
(2 數(shù)據(jù)復(fù)制:
HDFS存儲(chǔ)大數(shù)據(jù),文件分成等大小塊(除最后一個(gè)),塊默認(rèn)復(fù)制多次以保證數(shù)據(jù)冗余。塊大小和復(fù)制次數(shù)可配置,文件只能寫(xiě)一次,且同時(shí)只能有一個(gè)寫(xiě)入者。
理解例子:
文件/users/sameerp/data/part-0的Replication因子值是2,Block的ID列表包括了1和3,可以看到塊1和塊3分別被冗余復(fù)制了兩份數(shù)據(jù)塊。
文件/users/sameerp/data/part-1的Replication因子值是3,Block的ID列表包括了2、4和5,可以看到塊2、塊4和塊5分別被冗余復(fù)制了三份數(shù)據(jù)塊。
(3 數(shù)據(jù)副本的存放策略:
HDFS默認(rèn)的副本復(fù)制因子是3。
修改副本存放策略。
方法1:修改配置文件hdfs-site.xml。(需要重啟HDFS系統(tǒng)才能生效)
<property><name>dfs.replication</name><value>1</value>
</property>
默認(rèn)dfs.replication的值為3,通過(guò)這種方法雖然更改了配置文件,但是參數(shù)只在文件被寫(xiě)入dfs時(shí)起作用,不會(huì)改變之前寫(xiě)入的文件的備份數(shù)。
方法2:通過(guò)命令更改備份數(shù)。(不需要重啟HDFS系統(tǒng)即可生效)
# bin/hadoop fs -setrep -R 1 /
理解例子:(最好背過(guò))
第一個(gè)Block副本放在client所在機(jī)架的node里(如果client不在集群范圍內(nèi),則存放這第一個(gè)Block副本的node是隨機(jī)選取的,當(dāng)然系統(tǒng)會(huì)嘗試不選擇哪些太滿或者太忙的node)。
第二個(gè)Block副本放置在與第一個(gè)Block副本不同機(jī)架的node中(隨機(jī)選擇)。第三個(gè)Block副本和第二個(gè)Block副本在同一個(gè)機(jī)架,隨機(jī)放在不同的node中。
(4 機(jī)架感知
NameNode管理HDFS文件塊的復(fù)制?;镜母北痉胖貌呗允菍⒏北痉植荚诓煌瑱C(jī)架,以提高系統(tǒng)的可靠性,但這會(huì)增加寫(xiě)副本的成本,因?yàn)樾枰鐧C(jī)架或數(shù)據(jù)中心傳輸數(shù)據(jù)。機(jī)架感知的策略在保證副本分布在不同機(jī)架的可靠性的同時(shí),優(yōu)化了帶寬使用,通常只需在一個(gè)機(jī)架內(nèi)傳輸數(shù)據(jù)。
默認(rèn)Hadoop機(jī)架感知是沒(méi)有啟用的,需要在NameNode機(jī)器的<font style="color:#70000D;">core-site.xml</font>里配置。
在沒(méi)有機(jī)架信息的情況下,NameNode默認(rèn)將所有的slaves機(jī)器全部默認(rèn)為在/default-rack下,此時(shí)寫(xiě)B(tài)lock時(shí),所有DataNode機(jī)器的選擇完全是隨機(jī)的。
當(dāng)Hadoop配置了機(jī)架感知信息后,數(shù)據(jù)副本的存放策略如下:
- 第一個(gè)副本放在上傳文件的DataNode(如果該DataNode是上傳機(jī)器),或者隨機(jī)選擇一個(gè)DataNode。
- 第二個(gè)副本放在與第一個(gè)副本不同機(jī)架的隨機(jī)DataNode上。
- 第三個(gè)副本放在第二個(gè)副本所在機(jī)架的某個(gè)DataNode上,如果前兩個(gè)副本不在同一機(jī)架,則可能放在任一機(jī)架上。
- NameNode會(huì)根據(jù)客戶端與DataNode之間的“距離”對(duì)DataNode列表排序。
- 客戶端(DFSClient)根據(jù)排序后的列表,從最近的DataNode開(kāi)始寫(xiě)入數(shù)據(jù)。
- 依次寫(xiě)入后續(xù)的DataNode,直到所有副本都寫(xiě)入成功。
示例:
關(guān)于數(shù)據(jù)副本的存放策略正確的有些?(ABCD)
A、第三個(gè)副本:與第一個(gè)副本相同機(jī)架的其他節(jié)點(diǎn)上;
B、更多副本:隨機(jī)節(jié)點(diǎn)。
C、第一個(gè)副本,放置在上傳文件的數(shù)據(jù)節(jié)點(diǎn);
D、第二個(gè)副本,放置在與第一個(gè)副本不同的機(jī)架的節(jié)點(diǎn)上;
(5 安全模式 (只列考點(diǎn)
作用:保護(hù)集群數(shù)據(jù)的完整性.
啟動(dòng)方式:NameNode在啟動(dòng)時(shí)會(huì)自動(dòng)進(jìn)入安全模式(SafeMode),也可以手動(dòng)進(jìn)入。
進(jìn)入后,檢查數(shù)據(jù)完整性(數(shù)據(jù)塊的副本數(shù)量是否滿足配置的最小副本比率)。
在hdfs-default.xml文件中,通過(guò)dfs.safemode.threshold.pct屬性設(shè)置最小副本比率閾值。
當(dāng)系統(tǒng)處于安全模式時(shí),不接受任何對(duì)名稱空間的修改,也不會(huì)對(duì)數(shù)據(jù)塊進(jìn)行復(fù)制或刪除,但是可以瀏覽目錄結(jié)構(gòu)、查看文件內(nèi)容等操作。在安全模式下嘗試進(jìn)行禁止的操作時(shí),會(huì)拋出SafeModeException
。
hadoop dfsadmin -safemode leave //強(qiáng)制退出安全模式
hadoop dfsadmin -safemode enter //進(jìn)入安全模式
hadoop dfsadmin -safemode get //查看安全模式狀態(tài)
hadoop dfsadmin -safemode wait //等待,一直到安全模式結(jié)束
補(bǔ)充例:NameNode在啟動(dòng)時(shí)自動(dòng)進(jìn)入安全模式,在安全模式階段,說(shuō)法錯(cuò)誤的是(D)
A. 安全模式目的是在系統(tǒng)啟動(dòng)時(shí)檢查各個(gè)DataNode上數(shù)據(jù)塊的有效性。
B. 根據(jù)策略對(duì)數(shù)據(jù)塊進(jìn)行必要的復(fù)制或刪除。
C. 當(dāng)數(shù)據(jù)塊最小百分比數(shù)滿足最小副本數(shù)條件時(shí),會(huì)自動(dòng)退出安全模式。
D. 文件系統(tǒng)允許有修改。
(6 負(fù)載均衡 (考的幾率不大)
重新均衡DataNode上的數(shù)據(jù)分布命令:
$ HADOOP_HOME/bin/start-balancer.sh -t 10%
在這個(gè)命令中,-t 參數(shù)后面跟的是 HDFS 達(dá)到平衡狀態(tài)的磁盤(pán)使?率偏差值。如果機(jī)器與機(jī)器之間磁盤(pán)使?率偏差小于 10%,那么我們就認(rèn)為 HDFS 集群已經(jīng)達(dá)到了平衡狀態(tài)。
具體過(guò)程:
① 數(shù)據(jù)均衡服務(wù)( Rebalancing Server) 首先要求 NameNode 生成 DataNode 數(shù)據(jù)分布分析報(bào)告, 獲取每個(gè) DataNode磁盤(pán)使用情況。
② 數(shù)據(jù)均衡服務(wù)匯總需要移動(dòng)的數(shù)據(jù)塊分布情況,計(jì)算具體數(shù)據(jù)塊遷移路線圖, 確保為網(wǎng)絡(luò)內(nèi)的最短路徑。③ 開(kāi)始數(shù)據(jù)塊遷移任務(wù), Proxy Source DataNode(代理源數(shù)據(jù)節(jié)點(diǎn))復(fù)制一塊需要移動(dòng)的數(shù)據(jù)塊。④ 將復(fù)制的數(shù)據(jù)塊復(fù)制到目標(biāo) DataNode節(jié)點(diǎn)上。⑤ 刪除原始數(shù)據(jù)塊及在 NameNode 上存儲(chǔ)的元信息, 并將新的元信息更新到 NameNode上。⑥目標(biāo) DataNode 向 Proxy Source DataNode 確認(rèn)該數(shù)據(jù)塊遷移完成。⑦ Proxy Source DataNode 向數(shù)據(jù)均衡服務(wù)確認(rèn)本次數(shù)據(jù)塊遷移完成, 然后繼續(xù)執(zhí)行這個(gè)過(guò)程, 直至集群達(dá)到數(shù)據(jù)均衡標(biāo)準(zhǔn)。
(7 心跳機(jī)制 (考的幾率不大)
Hadoop 集群節(jié)點(diǎn)之間的通信是通過(guò)心跳機(jī)制實(shí)現(xiàn)的。所謂“心跳”是指的持續(xù)的按照一定頻率在運(yùn)行,執(zhí)行請(qǐng)求和響應(yīng)。當(dāng)長(zhǎng)時(shí)間沒(méi)有發(fā)送心跳時(shí),NameNode 就判斷 DataNode 的連接已經(jīng)中斷,不能繼續(xù)工作了,就被定性為”dead node”。NameNode 會(huì)檢查"dead node"中的副本數(shù)據(jù),復(fù)制到其他的 DataNode 中。
Hadoop 的心跳機(jī)制的具體實(shí)現(xiàn)思路是:
(1) 當(dāng) master 節(jié)點(diǎn)啟動(dòng)時(shí),會(huì)開(kāi)一個(gè) rpc server,等待 slave 的心跳連接。
(2) slave 節(jié)點(diǎn)啟動(dòng)時(shí),會(huì)連接到 master,并開(kāi)始每隔 3 秒鐘主動(dòng)向 master 發(fā)送一個(gè)“心跳”,這個(gè)時(shí)間間隔可以通過(guò) heartbeat.recheck.interval 屬性來(lái)設(shè)置。
(3) slave 通過(guò)“心跳”將自己的狀態(tài)告訴 master,master 返回“心跳”值,向 slave 節(jié)點(diǎn)傳達(dá)指令。
(4) Hadoop 集群中各個(gè)進(jìn)程之間的通信,都是通過(guò)“心跳”這種 RPC 通信來(lái)完成的。
(5) 當(dāng) NameNode 長(zhǎng)時(shí)間沒(méi)有接收到 DataNode 發(fā)送的“心跳”時(shí),NameNode 就判斷DataNode 的連接已經(jīng)中斷,就被定性為”dead node”。NameNode 會(huì)檢查 dead node中的副本數(shù)據(jù),復(fù)制到其他的 DataNode 中。
7.HDFS體系結(jié)構(gòu)(選擇,填空,簡(jiǎn)答) (這里無(wú)論如何都要背過(guò),不然后面無(wú)法學(xué))
(1 單NameNode節(jié)點(diǎn)集群架構(gòu):
單NameNode節(jié)點(diǎn)的HDFS集群是由一個(gè)NameNode和一定數(shù)目的DataNode組成。
NameNode是一個(gè)中心服務(wù)器,負(fù)責(zé)管理文件系統(tǒng)的命名空間和客戶端對(duì)文件的訪問(wèn)。
NameNode執(zhí)行文件系統(tǒng)的命名空間操作,例如打開(kāi)、關(guān)閉、重命名文件和目錄,同時(shí)決定Block到DataNode節(jié)點(diǎn)的映射。
DataNode負(fù)責(zé)處理文件系統(tǒng)的讀寫(xiě)請(qǐng)求,在NameNode的指揮下進(jìn)行Block的創(chuàng)建、刪除等。
一個(gè)文件被分成一個(gè)或多個(gè)Block,這些Block存儲(chǔ)在DataNode集合里。
(2 一個(gè)典型的 HDFS 集群通常由 NameNode、SecondaryNameNode 和 DataNode 三個(gè)節(jié)點(diǎn)組 成,其實(shí)就是運(yùn)行在這些節(jié)點(diǎn)服務(wù)器上的進(jìn)程。
節(jié)點(diǎn)名 | 主要功能 | 容錯(cuò)機(jī)制 |
---|---|---|
NameNode(命名節(jié)點(diǎn)) (一個(gè)集群通常只有一個(gè)活動(dòng)的NameNode節(jié)點(diǎn)) (決定是否將文件映射到DataNode的副本上) | 1. 提供名稱查詢服務(wù),是一個(gè) Jetty服務(wù)器。 2. 保存元數(shù)據(jù)信息,包括文件的所有者和權(quán)限、文件包含的塊和塊在 DataNode 的位置(通過(guò)“心跳”機(jī)制上報(bào))。 3. 啟動(dòng)時(shí)加載元數(shù)據(jù)信息到內(nèi)存。 | 1. 使用 SecondaryNameNode 恢復(fù) NameNode。 2. 利用 NameNode 的高可用(HA)機(jī)制,包括自動(dòng)故障轉(zhuǎn)移和多個(gè)NameNode的配置。 |
SecondaryNameNode | 1. 定期將 Edits 文件中的操作合并到 FsImage 文件中,并清空 Edits 文件。 2. NameNode 重啟時(shí)加載最新的 FsImage 文件,并重新創(chuàng)建 Edits 文件,記錄自上次 FsImage以來(lái)的操作。此機(jī)制減少了重啟時(shí)間并確保 HDFS 系統(tǒng)完整性。 | |
DataNode(數(shù)據(jù)節(jié)點(diǎn)) (負(fù)責(zé)數(shù)據(jù)存儲(chǔ)計(jì)算) | 1. 保存數(shù)據(jù)塊,每個(gè)塊對(duì)應(yīng)一個(gè)元數(shù)據(jù)信息文件,描述該塊屬于哪個(gè)文件及其序號(hào)。 2. 啟動(dòng)時(shí)向 NameNode 匯報(bào)塊信息。 3. 通過(guò)發(fā)送心跳保持與 NameNode 的聯(lián)系;若 NameNode 10 分鐘未收到心跳,則認(rèn)為該 DataNode 已失效,并將塊信息復(fù)制到其他 DataNode,以保證副本數(shù)量。 | 數(shù)據(jù)塊副本在多個(gè) DataNode 上存儲(chǔ),提供數(shù)據(jù)冗余。如果一個(gè) DataNode 失效,其他 DataNode 上的副本可以被用來(lái)恢復(fù)數(shù)據(jù)。 |
補(bǔ)充例:
1)HDFS 的 NameNode 負(fù)責(zé)管理文件系統(tǒng)的命名空間,將所有的文件和文件夾的元數(shù)據(jù) 保存在一個(gè)文件系統(tǒng)樹(shù)中,這些信息也會(huì)在硬盤(pán)上保存成以下文件(C)
A.日志 B.命名空間鏡像 C.兩者都是
2)下面哪個(gè)節(jié)點(diǎn)負(fù)責(zé) HDFS 的數(shù)據(jù)存儲(chǔ)(C)。
A、NameNode B、ResourceManager
C、DataNode D、SecondaryNameNode
3)HDFS 的 NameNode 負(fù)責(zé)管理文件系統(tǒng)的命名空間,將所有的文件和文件夾的元數(shù)據(jù) 保存在一個(gè)文件系統(tǒng)樹(shù)中,這些信息也會(huì)在硬盤(pán)上保存成以下文件(C)
A.日志 B.命名空間鏡像 C.兩者都是
4)在Hadoop中,下列哪個(gè)進(jìn)程通常與NameNode在同一節(jié)點(diǎn)上啟動(dòng)(B)。
A、SecondaryNameNode B、Jobtracker
C、DataNode D、TaskTracker
5)在Hadoop中,集群會(huì)啟動(dòng)哪些進(jìn)程,他們的作用分別是什么?
NameNode:這是Hadoop的主節(jié)點(diǎn),負(fù)責(zé)管理HDFS(Hadoop分布式文件系統(tǒng))的元數(shù)據(jù),包括文件系統(tǒng)的目錄結(jié)構(gòu)、文件到數(shù)據(jù)塊的映射以及數(shù)據(jù)塊的位置等。NameNode不存儲(chǔ)數(shù)據(jù)塊的實(shí)際內(nèi)容。
DataNode:這些是HDFS的工作節(jié)點(diǎn),負(fù)責(zé)存儲(chǔ)實(shí)際的數(shù)據(jù)塊。DataNode周期性地向NameNode發(fā)送心跳信號(hào)和數(shù)據(jù)塊報(bào)告,以確保它們的健康狀態(tài)和數(shù)據(jù)的一致性。
ResourceManager:這是YARN(Yet Another Resource Negotiator)的主節(jié)點(diǎn),負(fù)責(zé)全局資源管理與調(diào)度。它管理集群資源并協(xié)調(diào)各個(gè)應(yīng)用程序的運(yùn)行。
NodeManager:這是YARN的工作節(jié)點(diǎn),負(fù)責(zé)具體的資源管理,會(huì)在本地節(jié)點(diǎn)上監(jiān)控容器(Containers)的資源使用情況。NodeManager也負(fù)責(zé)啟動(dòng)和管理應(yīng)用程序的容器。
Secondary NameNode:雖然這個(gè)進(jìn)程的名字包含“NameNode”,但它并不是一個(gè)備份的NameNode。它的主要作用是定期合并NameNode的元數(shù)據(jù)(fsimage和edits文件),以減少NameNode的內(nèi)存使用和提高容錯(cuò)能力。
四 HDFS運(yùn)行機(jī)制(核心)
1.RPC遠(yuǎn)程過(guò)程調(diào)用協(xié)議:(選擇,填空,簡(jiǎn)答)TCP/IP 協(xié)議(目前網(wǎng)上聊天?)或 UDP(客戶端可靠協(xié)議但是信息傳輸效率不高)。
在OSI網(wǎng)絡(luò)通信模型中,RPC跨域了傳輸層和應(yīng)用層。
(1 一個(gè)完整的RPC架構(gòu)里面包含了四個(gè)核心的組件:(相對(duì)不是那么重要)
1.客戶端(Client):服務(wù)的調(diào)用方。2.客戶端存根(Client Stub):存放服務(wù)端的地址消息,再將客戶端的請(qǐng)求參數(shù)打包成網(wǎng)絡(luò)消息,然后通過(guò)網(wǎng)絡(luò)遠(yuǎn)程發(fā)送給服務(wù)方。3.服務(wù)端(Server):真正的服務(wù)提供者。4.服務(wù)端存根(Server Stub):接收客戶端發(fā)送過(guò)來(lái)的消息,將消息解包,并調(diào)用本地的方法。
(2 Hadoop的RPC機(jī)制(分為四部分):(必須背過(guò))
序列化層:Client與Server端通信傳遞的信息采用Hadoop提供的序列化類或自定義的Writable類型。
函數(shù)調(diào)用層:Hadoop RPC通過(guò)動(dòng)態(tài)代理以及Java反射實(shí)現(xiàn)函數(shù)調(diào)用。
網(wǎng)絡(luò)傳輸層:Hadoop RPC采用了基于TCP/IP的Socket機(jī)制。
服務(wù)器端框架層:RPC Server利用Java NIO以及事件驅(qū)動(dòng)的I/O模型,提高RPC Server并發(fā)處理能力。
補(bǔ)充例:
Hadoop的RPC機(jī)制同其他RPC框架一樣,可分為四個(gè)部分,請(qǐng)簡(jiǎn)述這四層的名稱及各自的實(shí)現(xiàn)機(jī)制。
答案就是上方。
Hadoop RPC的實(shí)現(xiàn)模型主要特點(diǎn)有透明性、高性能和可控性。通過(guò)動(dòng)態(tài)代理、反射——?jiǎng)討B(tài)加載類、序列化、非阻塞的異步IO(NIO)實(shí)現(xiàn)。
Hadoop的RPC總體架構(gòu):Hadoop RPC = 動(dòng)態(tài)代理 + 定制的二進(jìn)制流。
(再細(xì)9.9成不會(huì)考,但是就怕萬(wàn)一,想再細(xì)了解看:博客)
2.HDFS文件寫(xiě)入(超級(jí)重要,簡(jiǎn)體題必考,所有圖都要背過(guò)!!!!)
(1 HDFS讀取文件流程
① 使用HDFS 提供的 Client, 向遠(yuǎn)程的NameNode 發(fā)起 RPC 讀文件請(qǐng)求。
② NameNode 會(huì)視情況返回文件的部分或者全部數(shù)據(jù)塊列表, 對(duì)于每個(gè)數(shù)據(jù)塊, NameNode都會(huì)返回有該數(shù)據(jù)塊副本的 DataNode 地址。
③Client會(huì)選取最近的DataNode來(lái)讀取數(shù)據(jù)塊; 如果 Client本身就是 DataNode, 那么將從本地直接獲取數(shù)據(jù)。
④讀取完當(dāng)前數(shù)據(jù)塊后, 關(guān)閉當(dāng)前的 DataNode 連接, 并為讀取下一個(gè)數(shù)據(jù)塊尋找最佳的DataNode。
⑤當(dāng)讀完數(shù)據(jù)塊列表后, 且文件讀取還沒(méi)有結(jié)束, Client會(huì)繼續(xù)向NameNode 獲取下一批數(shù)據(jù)塊列表。
⑥每讀取完一個(gè)數(shù)據(jù)塊, 都會(huì)進(jìn)行校驗(yàn)和驗(yàn)證, 如果讀取 DataNode 時(shí)出現(xiàn)錯(cuò)誤, Client會(huì)通知NameNode, 然后再?gòu)南乱粋€(gè)擁有該數(shù)據(jù)塊副本的DataNode 繼續(xù)讀取。
(2 寫(xiě)入示例
將64M的block1數(shù)據(jù)塊按64k的package為單位劃分。
然后client將第一個(gè)package發(fā)送給Rack1機(jī)架上的host2結(jié)點(diǎn)。
當(dāng)host2結(jié)點(diǎn)接收完成后,將第一個(gè)package發(fā)送給Rack2機(jī)架上的host1與此同時(shí)client向host2發(fā)送第二個(gè)package。
當(dāng)host1結(jié)點(diǎn)接收完成后,將第一個(gè)package發(fā)送給Rack2機(jī)架上的host3,與此同時(shí)host2向host1發(fā)送第二個(gè)pabckage。
以此類推,直到將block1全部發(fā)送完成。
當(dāng)block1全部發(fā)送完成后,host2,host1,host3向NameNode節(jié)點(diǎn)發(fā)送通知,NameNode記錄并將消息發(fā)送給host2,host2再向client發(fā)送消息通知client數(shù)據(jù)塊block1已經(jīng)發(fā)送完成,NameNode需要等待client確認(rèn)。
client收到host2發(fā)送的消息后,向NameNode發(fā)送確認(rèn)消息,至此,block1才真正完成了寫(xiě)入的過(guò)程。
數(shù)據(jù)塊block1發(fā)送完成后,再向host7,host8,host4發(fā)送block2,發(fā)送的過(guò)程與block1相似,直到全部數(shù)據(jù)塊發(fā)送完成。
(3 使用HDFS API寫(xiě)文件:
public class FileSystemCat {public static void main(String[] args) throws Exception {String localPath = args[0];String dfsPath = args[1];InputStream in = null;OutputStream out = null;Configuration conf = new Configuration();FileSystem fs = FileSystem.get(URI.create(dfsPath), conf);try {in = new BufferedInputStream(new FileInputStream(localPath));out = fs.create(new Path(dfsPath), new Progressable() {@Overridepublic void progress() {System.out.print(" . ");}});IOUtils.copyBytes(in, out, 4096, false);} catch (Exception e) {IOUtils.closeStream(in);IOUtils.closeStream(out);}}
}
(4 使用HDFS API讀取文件:
public class FileSystemCat {public static void main(String[] args) throws Exception {String uri = "hdfs://10.10.155.110:9000/output/wordcount/part-r-00000";Configuration conf = new Configuration();FileSystem fs = FileSystem.get(URI.create(uri), conf);InputStream in = null;try {in = fs.open(new Path(uri));IOUtils.copyBytes(in, System.out, 4096, false);} catch (Exception e) {e.printStackTrace();IOUtils.closeStream(in);}}
}
補(bǔ)充例:
1)假設(shè)當(dāng)前環(huán)境有NameNode節(jié)點(diǎn)1個(gè)、DataNode節(jié)點(diǎn)3個(gè)、Client Node節(jié)點(diǎn)1個(gè),請(qǐng)畫(huà)出HDFS文件寫(xiě)入的流程圖。
2)下面代碼片段為使用HDFS API寫(xiě)文件的過(guò)程,請(qǐng)補(bǔ)全代碼的空白處。
public class FileSystemCat {public static void main(String[] args) throws Exception {String localPath = args[0];String dfsPath=args[1];InputStream in = null;OutputStream out=null;__________(1)__________ ;FileSystem fs = ________(2) ________(URI.create(dfsPath), conf);try {in = new BufferedInputStream(________(3) ________);out=fs.create(new Path(dfsPath),new Progressable() {@Overridepublic void progress() {// 反饋寫(xiě)入進(jìn)度 System.out.print(" . ");}});IOUtils. ________(4) ________;} catch (Exception e) {e.printStackTrace();IOUtils.closeStream(in);IOUtils.closeStream(out);}}
}
就是上方代碼
3.HDFS文件的一致模型:(考的概率不大)
所解決的問(wèn)題:寫(xiě)入HDFS的文件內(nèi)容對(duì)其他讀者可能不是立即可見(jiàn)的,即使數(shù)據(jù)已存儲(chǔ),文件長(zhǎng)度可能仍顯示為0??鐗K數(shù)據(jù)寫(xiě)入時(shí),只有完全寫(xiě)入并同步的數(shù)據(jù)塊對(duì)新讀者可見(jiàn),正在寫(xiě)入的塊不可見(jiàn)。
解決方案:要在HDFS中確保數(shù)據(jù)可見(jiàn)性,可以調(diào)用<font style="color:rgb(6, 6, 7);">sync()</font>
方法強(qiáng)制數(shù)據(jù)節(jié)點(diǎn)同步緩存數(shù)據(jù)。關(guān)閉文件時(shí)會(huì)自動(dòng)執(zhí)行<font style="color:rgb(6, 6, 7);">sync()</font>
。不調(diào)用<font style="color:rgb(6, 6, 7);">sync()</font>
可能導(dǎo)致數(shù)據(jù)丟失。需要根據(jù)應(yīng)用需求平衡數(shù)據(jù)一致性和性能,合理調(diào)用<font style="color:rgb(6, 6, 7);">sync()</font>
。例如,寫(xiě)入一定數(shù)據(jù)后調(diào)用<font style="color:rgb(6, 6, 7);">sync()</font>
。創(chuàng)建文件后,需調(diào)用<font style="color:rgb(6, 6, 7);">hsync()</font>
或<font style="color:rgb(6, 6, 7);">close()</font>
才能讀取文件信息。
示例:當(dāng)創(chuàng)建一個(gè)文件后,立即讀取文件信息,此時(shí)文件信息是不存在的。只有當(dāng)調(diào)用hsync()方法或調(diào)用了close()方法后,才能立即讀取到文件信息。
Path p=new Path("/home/temp/a.txt");
FSDataOutputStream out=fs.create(p);
out.write("content".getBytes("UTF-8"));
out.hflush();
out.hsync();
assertThat(fs.getFileStatus(p).getLen(),is(((long)"content".len
gth())));
Path p=new Path("/home/temp/a.txt");
fs.create(p);
assertThat(fs.exists(p),is(true));
Path p=new Path("/home/temp/a.txt");
OutputStream out=fs.create(p);
out.write("content".getBytes("UTF-8"));
out.close();
assertThat(fs.getFileStatus(p).getLen(),is(((long)"content".len
gth())));
- HDFS的HA機(jī)制(簡(jiǎn)答)
HDFS 的 HA 機(jī)制 7*24h 運(yùn)行
在 Hadoop 2.x 及以后版本中,新增了對(duì)高可靠性(HA)的支持,實(shí)現(xiàn)方式是:配置了一對(duì)“活動(dòng)-備?”(active - standby)NameNode。當(dāng)活動(dòng)的 NameNode 失效時(shí),備?的NameNode 就會(huì)接管它的任務(wù)并開(kāi)始服務(wù)于來(lái)自客戶端的請(qǐng)求,而不必中斷整個(gè)服務(wù)。
HDFS NameNode的高可用整體架構(gòu)主要由以下幾個(gè)關(guān)鍵組成部分構(gòu)成:
Active NN 和 Standby NN:主/備 NN,只有主 NN 才能對(duì)外提供讀寫(xiě)服務(wù)。
主備切換控制器 ZKFailoverController:作為獨(dú)立進(jìn)程運(yùn)行,對(duì) NN 的主備切換進(jìn)行總體控制。
ZooKeeper 集群:為主備切換控制器提供主備選舉支持。
共享存儲(chǔ)系統(tǒng):主備 NN 通過(guò)共享存儲(chǔ)系統(tǒng)實(shí)現(xiàn)元數(shù)據(jù)同步。
DN 節(jié)點(diǎn):DN 會(huì)同時(shí)向主 NN 和備 NN 上報(bào)數(shù)據(jù)塊的位置信息。
(5 NameNode 的主備切換實(shí)現(xiàn):(了解即可)
補(bǔ)充例:下面關(guān)于Hadoop HA機(jī)制描述錯(cuò)誤的是(D)。
A、通常由兩個(gè)NameNode組成,一個(gè)處于active狀態(tài),另一個(gè)處于standby狀態(tài)
B、Active NameNode對(duì)外提供服務(wù),而Standby NameNode則不對(duì)外提供服務(wù),僅同步Active NameNode的狀態(tài)
C、需要配合Zookeeper才能實(shí)現(xiàn)HA
D、在NameNode節(jié)點(diǎn)失敗時(shí),可以快速手動(dòng)進(jìn)行切換
6 Federation機(jī)制(最好背過(guò),考的概率也不大)
(1 優(yōu)點(diǎn):
擴(kuò)展性和隔離性:支持多個(gè)NameNode水平擴(kuò)展整個(gè)文件系統(tǒng)的namespace??砂凑諔?yīng)用程序的用戶和種類分離namespace volume,進(jìn)而增強(qiáng)了隔離性。
通用存儲(chǔ)服務(wù):Block Pool抽象層為HDFS的架構(gòu)開(kāi)啟了創(chuàng)新之門(mén)。分離block storage layer使得:
新的文件系統(tǒng)(non-HDFS)可以在block storage上構(gòu)建
新的應(yīng)用程序(如HBase)可以直接使用block storage層
分離的block storage層為將來(lái)完全分布式namespace打下基礎(chǔ)
設(shè)計(jì)簡(jiǎn)單:Federation 整個(gè)核心設(shè)計(jì)的大部分改變是在DataNode、Config和Tools中,而NameNode本身的改動(dòng)非常少,這樣NameNode原先的健壯性不會(huì)受到影響。可以迅速滿足需求,另外Federation具有良好的向后兼容性,已有的單NameNode的部署配置不需要任何改變就可以繼續(xù)工作。、
(2 不足:
單點(diǎn)故障問(wèn)題:HDFS Federation并沒(méi)有完全解決單點(diǎn)故障問(wèn)題。如果某個(gè)NameNode掛掉了,其管理的相應(yīng)的文件便不可以訪問(wèn)。Federation中每個(gè)NameNode仍然像之前HDFS上實(shí)現(xiàn)一樣,配有一個(gè)SecondaryNameNode,以便主NameNode掛掉一下,用于還原元數(shù)據(jù)信息。
負(fù)載均衡問(wèn)題:HDFS Federation采用Client Side Mount Table分?jǐn)偽募拓?fù)載,該方法需要人工介入以達(dá)到理想的負(fù)載均衡。
五 訪問(wèn)HDFS文件系統(tǒng)(核心)
1.HDFS命令行接口:(選擇,填空,簡(jiǎn)答)又一超級(jí)重點(diǎn)hadoop fs … / hadoop dfs …
hdfs dfs …(兩種皆可)
下面是常用命令:(黃色背景的一定要記住)
<font style="background-color:#FBDE28;">hadoop dfs -ls <path></font> | 列出指定路徑的文件或目錄內(nèi)容 |
---|---|
hadoop dfs -lsr <path> | 遞歸地列出指定路徑的目錄內(nèi)容 |
hadoop dfs -df <path> | 查看指定路徑的目錄使用情況 |
hadoop dfs -du <path> | 顯示指定目錄中所有文件及子目錄的大小 |
<font style="background-color:#FBDE28;">hadoop dfs -count [-q] <path></font> | 顯示指定目錄下的目錄數(shù)及文件數(shù),添加<font style="background-color:#FBDE28;">-q</font> 可查看文件索引情況 |
<font style="background-color:#FBDE28;">hadoop dfs -mv <src> <dst></font> | 將HDFS上的文件移動(dòng)到目標(biāo)文件夾 |
<font style="background-color:#FBDE28;">hadoop dfs -rm [-skipTrash] <path></font> | 刪除HDFS上的文件,移動(dòng)到回收站;<font style="background-color:#FBDE28;">-skipTrash</font> 則直接刪除 |
hadoop dfs -rmr [-skipTrash] <path> | 刪除HDFS上的目錄及其下文件,移動(dòng)到回收站;-skipTrash 則直接刪除 |
hadoop dfs -expunge | 清空HDFS回收站 |
<font style="background-color:#FBDE28;">hadoop dfs -put <localsrc> <dst></font> | 將本地文件上傳到HDFS的指定目錄 |
<font style="background-color:#FBDE28;">hadoop dfs -get [-ignoreCrc] [-crc] <src> <localdst></font> | 將HDFS文件下載到本地,<font style="background-color:#FBDE28;">-ignoreCrc</font> 復(fù)制CRC檢驗(yàn)失敗的文件, <font style="background-color:#FBDE28;">-crc</font> 復(fù)制CRC信息 |
hadoop dfs -copyToLocal [-ignoreCrc] [-crc] <src> <localdst> | 功能類似于get |
hadoop dfs -moveToLocal [-crc] <src> <localdst> | 將HDFS文件移動(dòng)到本地目錄,-crc 移動(dòng)文件及CRC信息 |
<font style="background-color:#FBDE28;">hadoop dfs -mkdir <path></font> | 在HDFS上創(chuàng)建目錄 |
hadoop dfs -touchz <path> | 在HDFS上創(chuàng)建一個(gè)0字節(jié)的空文件 |
hadoop dfs -text <path> | 輸出HDFS上指定文本文件的內(nèi)容 |
<font style="background-color:#FBDE28;">hadoop dfs -cat <path></font> | 瀏覽HDFS上指定文件的內(nèi)容 |
hadoop dfs -setrep [-R] [-w] <rep> <path> | 設(shè)置文件的復(fù)制因子,-R 表示遞歸 |
hadoop dfs -test -[ezd] <path> | 檢查HDFS上的文件:-e 檢查文件是否存在, -z 檢查文件是否0字節(jié), -d 檢查是否是目錄 |
hadoop dfs -stat [format] <path> | 顯示HDFS上文件或目錄的統(tǒng)計(jì)信息 |
<font style="background-color:#FBDE28;">hadoop dfs -chmod [-R] <MODE> <path></font> | 改變HDFS上指定文件的權(quán)限,<font style="background-color:#FBDE28;">-R</font> 表示遞歸執(zhí)行 |
hadoop dfs -chown [-R] [OWNER][:[GROUP]] <path> | 改變HDFS上指定文件的所屬用戶,-R 表示遞歸執(zhí)行 |
hadoop dfs -chgrp [-R] GROUP <path> | 改變HDFS上指定文件的所屬組別,-R 表示遞歸執(zhí)行 |
<font style="background-color:#FBDE28;">hadoop dfs -help</font> | 顯示所有<font style="background-color:#FBDE28;">dfs</font> 命令的幫助信息 |
hadoop dfs -copyFromLocal <localsrc> <dst> | 功能類似于put |
hadoop dfs -moveFromLocal <localsrc> <dst> | 將本地文件移動(dòng)到HDFS指定目錄 |
注意事項(xiàng)- hadoop
和hdfs
命令在功能上是相似的,但推薦使用hdfs dfs ...
命令,因?yàn)樗鼘iT(mén)用于HDFS,更加明確。
2.常用API:(簡(jiǎn)答,編程,紅字必背)
(1 Hadoop有一個(gè)抽象的文件系統(tǒng)概念,HDFS只是其中的一個(gè)實(shí)現(xiàn)。類org.apache.hadoop.fs.FileSystem定義了Hadoop中的一個(gè)文件系統(tǒng)接口,并且該抽象類有幾個(gè)具體實(shí)現(xiàn)。
文件系統(tǒng) | URL方案 | Java 實(shí)現(xiàn)類 | 描述 |
---|---|---|---|
Local file | fs | fs.LocalFileSystem | 使用了客戶端校驗(yàn)的本地磁盤(pán)文件系統(tǒng)。 |
HDFS | hdfs | hdfs.DistributedFileSystem | Hadoop 的分布式文件系統(tǒng)。 |
HFTP | hftp | hdfs.HftpFileSystem | 在 HTTP 上提供對(duì) HDFS只讀訪問(wèn)的文件系統(tǒng)。 |
HSFTP | hsftp | hdfs.HsftpFileSystem | 在 HTTPS 上提供對(duì) HDFS只讀訪問(wèn)的文件系統(tǒng)。 |
WebHDFS | Webhdfs | hdfs.web.WebHdfsFileSystem | 基于 HTTP 對(duì) HDFS 提供安全讀寫(xiě)訪問(wèn)的文件系統(tǒng)。 |
HAR | har | fs.HarFileSystem | 一個(gè)構(gòu)建在其他文件系統(tǒng)之上用于文件存檔的文件系統(tǒng)。 |
HFS (KFS) | kfs | fs.kfs.KosmosFileSystem | CloudStore 是類似于 HDFS 或 Google 的 GFS 的文件系統(tǒng),用 C++ 編寫(xiě)。 |
FTP | ftp | fs.ftp.FTPFileSystem | 由 FTP服務(wù)器支持的文件系統(tǒng)。 |
S3(原生) | S3n | fs.s3native.NativeS3FileSystem | 由 Amazon S3 支持的文件系統(tǒng)。 |
(2 從Hadoop URL中讀取數(shù)據(jù):
例:以標(biāo)準(zhǔn)輸出方式顯示Hadoop文件系統(tǒng)中的文件。(類似于Unix中的cat命令)
public class URLCat {// 靜態(tài)塊:設(shè)置 URL 的流處理工廠,用于處理 HDFS URLstatic {// 將 Hadoop 的 FsUrlStreamHandlerFactory 綁定到 java.net.URLURL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());}public static void main(String[] args) throws Exception {InputStream in = null; // 定義輸入流,用于讀取數(shù)據(jù)try {// 打開(kāi) HDFS 上的文件,URL 是從命令行參數(shù)傳入的in = new URL(args[0]).openStream();// 使用 IOUtils 工具類,將輸入流內(nèi)容復(fù)制到標(biāo)準(zhǔn)輸出IOUtils.copyBytes(in, System.out, 4096, false);} finally {// 關(guān)閉輸入流,防止內(nèi)存泄漏IOUtils.closeStream(in);}}
}
編譯上述代碼,導(dǎo)出為URLCat.jar文件,拷貝到/home/files目錄下,執(zhí)行下面的命令:
# hadoop jar /home/files/URLCat.jar com.hdfsclient.URLCat hdfs://master:9000/input/sample.txt
(3 通過(guò)FileSystem API讀取數(shù)據(jù):
雖然從Hadoop URL中讀取數(shù)據(jù)是最簡(jiǎn)單的方式,但是有時(shí)可能無(wú)法在應(yīng)用中設(shè)置URLStreamHandlerFactory實(shí)例,在實(shí)際開(kāi)發(fā)中,訪問(wèn)HDFS最常用的方式還是使用FileSystem API來(lái)讀取數(shù)據(jù)。
public class FileSystemCat {public static void main(String[] args) throws Exception {String uri = "hdfs://master:9000/input/sample.txt";Configuration conf = new Configuration();FileSystem fs = FileSystem.get(URI.create(uri), conf);InputStream in = null;try {in = fs.open(new Path(uri));IOUtils.copyBytes(in, System.out, 4096, false);} finally {IOUtils.closeStream(in);}}
}
編譯上述代碼,導(dǎo)出為FileSystemCat.jar文件,拷貝到/home/files目錄下,執(zhí)行下面的命令:
# hadoop jar /home/files/FileSystemCat.jar com.hdfsclient.FileSystemCat
(4 寫(xiě)入數(shù)據(jù)
FileSystem類創(chuàng)建文件的方法,常用的有兩類:create()和append()方法。
例:將本地文件復(fù)制到HDFS文件系統(tǒng)。
public class FileCopyFromLocal {public static void main(String[] args) {String localSrc = "/home/hadoop/files/sample.txt";String dst = "hdfs://master:9000/input/hadoop/sample.txt";InputStream in = null;OutputStream out = null;try {in = new BufferedInputStream(new FileInputStream(localSrc));Configuration conf = new Configuration();FileSystem fs = FileSystem.get(URI.create(dst), conf);out = fs.create(new Path(dst), new Progressable() {@Overridepublic void progress() {System.out.print(" . ");}});IOUtils.copyBytes(in, out, 4096, true);} catch (IOException e) {e.printStackTrace();} finally {IOUtils.closeStream(in);IOUtils.closeStream(out);}}
}
編譯上述代碼,導(dǎo)出為xxx.jar文件,拷貝到/home/files目錄下,執(zhí)行下面的命令:
# hadoop jar /home/files/xxx.jarcom.hdfsclient.FileCopyFromLocal
(5 刪除數(shù)據(jù)
使用FileSystem類的delete方法可以永久刪除文件或目錄。例:刪除HDFS上的文件或目錄。
public class DeleteFile {public static void main(String[] args) {String uri = "hdfs://master:9000/input/hadoop/sample.txt";Configuration conf = new Configuration();try {FileSystem fs = FileSystem.get(URI.create(uri), conf);Path delete = new Path(uri);boolean isDeleted = fs.delete(delete, false);// 是否遞歸刪除文件夾及文件夾下的文件// boolean isDeleted = fs.delete(delete, true);System.out.println(isDeleted == true ? "刪除成功" : "刪除失敗");} catch (Exception e) {e.printStackTrace();}}
}
編譯上述代碼,導(dǎo)出為xxx.jar文件,拷貝到/home/files目錄下,執(zhí)行下面的命令:
# hadoop jar /home/files/xxx.jar com.hdfsclient.DeleteFile
(6 HDFS創(chuàng)建目錄
FileSystem提供了一個(gè)實(shí)例方法mkdirs()來(lái)創(chuàng)建目錄,該方法可以一次性創(chuàng)建除父目錄之外所有必要的。如果目錄都已經(jīng)創(chuàng)建成功,則返回true。例:顯示在HDFS上創(chuàng)建一個(gè)目錄。
public class CreateDir {public static void main(String[] args) {String uri = "hdfs://master:9000/input/hadoop/tmp";Configuration conf = new Configuration();try {FileSystem fs = FileSystem.get(URI.create(uri), conf);Path dfs = new Path(uri);fs.mkdirs(dfs);} catch (Exception e) {e.printStackTrace();}}
}
編譯上述代碼,導(dǎo)出為xxx.jar文件,拷貝到/home/files目錄下,執(zhí)行下面的命令:
# hadoop jar /home/files/xxx.jar com.hdfsclient.CreateDir
(7 查詢文件系統(tǒng)
文件元數(shù)據(jù)類FileStatus封裝了文件系統(tǒng)中文件和目錄的元數(shù)據(jù),包括文件長(zhǎng)度、塊大小、備份、修改時(shí)間、所有者以及權(quán)限信息等。
1) 查看HDFS中某個(gè)文件是否存在。
public class CheckFileIsExist {public static void main(String[] args) {String uri = "hdfs://master:9000/input/hadoop/sample.txt";Configuration conf = new Configuration();try {FileSystem fs = FileSystem.get(URI.create(uri), conf);Path path = new Path(uri);boolean isExists = fs.exists(path);System.out.println(isExists == true ? "文件存在" : "文件不存在");} catch (Exception e) {e.printStackTrace();}}
}
編譯上述代碼,導(dǎo)出為xxx.jar文件,拷貝到/home/files目錄下,執(zhí)行下面的命令:
# hadoop jar /home/files/xxx.jar com.hdfsclient.CheckFileIsExist
2) 列出HDFS中某個(gè)目錄下的文件或目錄名稱。
public class ListFiles {public static void main(String[] args) {String uri = "hdfs://192.168.52.25:9000/gl";Configuration conf = new Configuration();try {FileSystem fs = FileSystem.get(URI.create(uri), conf);Path path = new Path(uri);FileStatus[] status = fs.listStatus(path);for (FileStatus s : status) {System.out.println(s.getPath().toString());}fs.close();} catch (Exception e) {e.printStackTrace();}}
}
編譯上述代碼,導(dǎo)出為xxx.jar文件,拷貝到/home/files目錄下,執(zhí)行下面的命令:
# hadoop jar /home/files/xxx.jar com.hdfsclient.ListFiles
3) 查看HDFS中文件存儲(chǔ)位置信息。
public class LocationFile {public static void main(String[] args) {String uri = "hdfs://192.168.52.25:9000/gl/sample.txt";Configuration conf = new Configuration();try {FileSystem fs = FileSystem.get(URI.create(uri), conf);Path path = new Path(uri);FileStatus status = fs.getFileStatus(path);BlockLocation[] blocks = fs.getFileBlockLocations(status, 0, status.getLen());for (int i = 0; i < blocks.length; i++) {String[] hosts = blocks[i].getHosts();System.out.println("block_" + i + "_location:" + hosts[0]);}fs.close();} catch (Exception e) {e.printStackTrace();}}
}
編譯上述代碼,導(dǎo)出為xxx.jar文件,拷貝到/home/files目錄下,執(zhí)行下面的命令:
# hadoop jar /home/files/xxx.jar com.hdfsclient.LocationFile
補(bǔ)充例:請(qǐng)編寫(xiě)代碼完成使用HDFS API讀取文件并打印到控制臺(tái)輸出,提示:可使用FileSystem讀取文件,使用IOUtils工具類,將讀取的文件流直接寫(xiě)入到system.out輸出流。
public class FileSystemCat {public static void main(String[] args) throws Exception {String uri = "hdfs://master:9000/output/wordcount/part-r-00000";//…// 在此處編寫(xiě)代碼//…}
}
答案再上面。
03 使?其他常?接口 (了解就好,紅色必備)
Hadoop文件系統(tǒng)的接口是通過(guò)Java API提供的,所以其他非Java應(yīng)用程序訪問(wèn)Hadoop文件系統(tǒng)會(huì)比較麻煩。Thriftfs定制功能模塊中的Thrift API通過(guò)把Hadoop文件系統(tǒng)包裝成一個(gè)Apache Thrift服務(wù)來(lái)彌補(bǔ)這個(gè)不足,從而使任何具有Thrift綁定的語(yǔ)言都能輕松地與Hadoop文件系統(tǒng)(例如HDFS)進(jìn)行交互。Thrift是一個(gè)軟件框架,最初由Facebook開(kāi)發(fā)用作系統(tǒng)內(nèi)各語(yǔ)言之間的RPC通信。
非常注意點(diǎn):其他語(yǔ)言也可以編譯Hadoop,不是僅java。
補(bǔ)充例:
下列關(guān)于 Hadoop API 的說(shuō)法錯(cuò)誤的是 (A)
A.Hadoop 的文件 API 不是通?的,只?于 HDFS 文件系統(tǒng)
B.Configuration 類的默認(rèn)實(shí)例化方法是以 HDFS 系統(tǒng)的資源配置為基礎(chǔ)的
C.FileStatus 對(duì)象存儲(chǔ)文件和目錄的元數(shù)據(jù)
D.FSDataInputStream 是 java.io.DataInputStream 的子類
六 Hadoop I/O詳解(重點(diǎn))
1 數(shù)據(jù)完整性(不畫(huà)紅的了解就行)(簡(jiǎn)答)(1 常用錯(cuò)誤檢驗(yàn)碼:CRC-32(循環(huán)冗余檢驗(yàn)),任何大小的數(shù)據(jù)輸入均計(jì)算得到一個(gè)32位的證書(shū)校驗(yàn)和。HDFS會(huì)對(duì)寫(xiě)入的所有數(shù)據(jù)計(jì)算校驗(yàn)和,并在讀取數(shù)據(jù)時(shí)驗(yàn)證校驗(yàn)和。(特注:校驗(yàn)和的計(jì)算代價(jià)是相當(dāng)?shù)偷?#xff0c;一般只是增加少許額外的讀/寫(xiě)文件時(shí)間。對(duì)于大多數(shù)應(yīng)用來(lái)說(shuō),這樣的額外開(kāi)銷可以保證數(shù)據(jù)完整性是可以接受的。)
本地文件上傳到HDFS集群時(shí)的校驗(yàn)
將HDFS集群文件讀取到本地時(shí)的校驗(yàn):客戶端讀取HDFS數(shù)據(jù)時(shí),NameNode指定數(shù)據(jù)塊位置。DataNode用CRC-32校驗(yàn)讀出的數(shù)據(jù),如校驗(yàn)和不匹配,表明數(shù)據(jù)損壞,DataNode通知NameNode。NameNode隨后指引客戶端從其他副本讀取數(shù)據(jù),確保數(shù)據(jù)完整性。
(2 檢驗(yàn)數(shù)據(jù)完整性:(背過(guò))
核心問(wèn)題1:HDFS是如何驗(yàn)證數(shù)據(jù)完整性的?
1.DataNode負(fù)責(zé)在收到數(shù)據(jù)后存儲(chǔ)該數(shù)據(jù)及其驗(yàn)證校驗(yàn)和。在收到客戶端的數(shù)據(jù)或復(fù)制其他DataNode的數(shù)據(jù)時(shí)執(zhí)行這個(gè)操作。正在進(jìn)行寫(xiě)操作的客戶端將數(shù)據(jù)及其檢驗(yàn)和發(fā)送到由一系列DataNode線成的管線,管線中最后一個(gè)DataNode負(fù)責(zé)驗(yàn)證校驗(yàn)和,如果檢測(cè)到錯(cuò)誤,客戶端便會(huì)收到一個(gè)ChecksumException異常,該異常是IOException異常子類??蛻舳藨?yīng)以應(yīng)用程序特定的方式來(lái)處理,例如重試這個(gè)操作。
2.客戶端從DataNode讀取數(shù)據(jù)時(shí),也會(huì)計(jì)算校驗(yàn)和,將會(huì)與DataNode中存儲(chǔ)的校驗(yàn)和進(jìn)行比較。每個(gè)DataNode均持久保存有一個(gè)用于驗(yàn)證的校驗(yàn)和日志,所以它知道每個(gè)數(shù)據(jù)塊的最后一次驗(yàn)證時(shí)間。客戶端驗(yàn)證完之后會(huì)告訴DataNode并更新日志。保存這些統(tǒng)計(jì)信息對(duì)于檢測(cè)損壞的磁盤(pán)很有價(jià)值。
3.客戶端在讀取數(shù)據(jù)塊時(shí)會(huì)驗(yàn)證校驗(yàn)和,每個(gè)DataNode也會(huì)在后臺(tái)線程中運(yùn)行一個(gè)DataBlockScanner進(jìn)程,從而定期驗(yàn)證存儲(chǔ)在這個(gè)DataNode上的所有的數(shù)據(jù)塊。這也是解決物理存儲(chǔ)媒體上位損壞(位衰減)的有效措施。
核心問(wèn)題2:客戶端發(fā)現(xiàn)有Block壞掉了,該如何來(lái)恢復(fù)這個(gè)損壞的Block呢?
客戶端在讀取Block時(shí),如果檢測(cè)到錯(cuò)誤,首先向NameNode報(bào)告已損壞的Block及其正在嘗試讀操作的這個(gè)DataNode,再拋出ChecksumException異常。
NameNode將這個(gè)Block副本標(biāo)記為已損壞,這樣NameNode就不會(huì)把客戶端指向這個(gè)Block,也不會(huì)復(fù)制這個(gè)Block到其他的DataNode。
NameNode會(huì)安排這個(gè)Block的一個(gè)完好的副本復(fù)制到另外一個(gè)DataNode上,恢復(fù)副本因子的水平。
最后,NameNode將已損壞的Block副本刪除。
2.文件壓縮(選擇,填空,簡(jiǎn)答)(除(6以外 必須全部背過(guò),必考)
(1 壓縮好處:減少存儲(chǔ)文件所需要的磁盤(pán)空間;加速數(shù)據(jù)在網(wǎng)絡(luò)和磁盤(pán)上的傳輸。
(2 壓縮基本原則:計(jì)算密集型的job,少用壓縮;IO密集型的job,多用壓縮。
(3 壓縮 MapReduce 的一種優(yōu)化策略:通過(guò)壓縮編碼對(duì) Mapper 或者 Reducer 的輸出進(jìn)行壓縮,以減少磁盤(pán) IO, 提高 MR 程序運(yùn)行速度(但相應(yīng)增加了 cpu 運(yùn)算負(fù)擔(dān)) 。
(4 常見(jiàn)Hadoop不同壓縮格式特性:
壓縮工具 | 壓縮能力 | 壓縮速度 | 解壓縮速度 | 備注 |
---|---|---|---|---|
gzip | 一般 | 一般 | 一般 | 空間/時(shí)間性能平衡 |
bzip2 | 強(qiáng) | 慢 | 一般 | 壓縮能力強(qiáng),速度慢 |
LZO | 較弱 | 快 | 快 | 壓縮速度優(yōu)化 |
LZ4 | 較弱 | 非???/td> | 非???/td> | 壓縮速度和解壓縮速度均優(yōu) |
Snappy | 較弱 | 非???/td> | 非???/td> | 解壓縮速度比LZO高 |
(5 常見(jiàn)的4種壓縮格式比較:(注:在MapReduce處理壓縮的數(shù)據(jù)時(shí),壓縮格式是否支持切分(splitting)是非常重要的。)
格式 | 壓縮率 | 速度 | Split支持 | 應(yīng)用場(chǎng)景 |
---|---|---|---|---|
gzip壓縮 | 中 | 快 | 否 | 文件壓縮之后在130M以內(nèi)的(1個(gè)塊大小內(nèi)),可以考慮用gzip壓縮格式.例如:一天或者一個(gè)小時(shí)的日志壓縮成一個(gè)gzip文件,運(yùn)行MapReduce程序時(shí)通過(guò)多個(gè)gzip文件達(dá)到并發(fā)。Hive、Streaming和MapReduce程序的處理方式和文本處理完全一樣,壓縮之后原來(lái)的程序不需要做任何修改。 |
lzo壓縮 | 低 | 中 | 否 | 壓縮后大于200M的文件,適合大文件壓縮,優(yōu)點(diǎn)隨文件大小增加而更明顯。 |
snappy壓縮 | 低 | 中 | 否 | 當(dāng)MapReduce作業(yè)的map輸出的數(shù)據(jù)比較大的時(shí)候,作為map到reduce的中間數(shù)據(jù)的壓縮格式;或者作為一個(gè)MapReduce作業(yè)的輸出和另外一個(gè)MapReduce作業(yè)的輸入。 |
bzip2壓縮 | 高 | 慢 | 是 | 適合對(duì)速度要求不高,但對(duì)壓縮率要求較高的時(shí)候,可以作為MapReduce作業(yè)的輸出格式;或者輸出之后的數(shù)據(jù)比較大,處理之后的數(shù)據(jù)需要壓縮存檔減少磁盤(pán)空間并且以后數(shù)據(jù)用得比較少的情況;或者對(duì)單個(gè)很大的文本文件想壓縮減少存儲(chǔ)空間,同時(shí)又需要支持split,而且兼容之前的應(yīng)用程序(即應(yīng)用程序不需要修改)的情況。 |
補(bǔ)充例:Hadoop壓縮格式中,bzip壓縮的優(yōu)缺點(diǎn)及應(yīng)用場(chǎng)景?
答案在表格4中.
(6 壓縮格式選取:(了解,不大可能考)
使用容器文件格式,例如順序文件(SequenceFile)、RCFile或者Avro數(shù)據(jù)文件,所有這些文件格式同時(shí)支持壓縮和切分。通常最好與一個(gè)快速壓縮工具聯(lián)合使用,例如LZO、LZ4,或者Snappy。
使用支持切分的壓縮格式,例如bzip2,或者使用通過(guò)索引實(shí)現(xiàn)切分的壓縮格式,例如LZO。
在應(yīng)用中將文件切分成塊,并使用任意一種壓縮格式為每個(gè)數(shù)據(jù)塊建立壓縮文件。這種情況下, 需要合理選擇數(shù)據(jù)塊的大小,以確保壓縮后數(shù)據(jù)塊的大小近似于HDFS塊的大小。
存儲(chǔ)未經(jīng)壓縮的文件。
(對(duì)于大文件不要使用不支持切分整個(gè)文件的壓縮格式,因?yàn)闀?huì)失去數(shù)據(jù)的本地特性,進(jìn)而造成MapReduce應(yīng)用的效率低下。)
3 文件序列化和反序列化:(選擇)(考不多)
(1 理解就看下圖即可。
(2 序列化原因:因?yàn)橐鐧C(jī)器 RPC(進(jìn)程間通訊)1. 保證安全 2. 序列值傳輸速)快,體積變小
(3 常見(jiàn) writable 實(shí)現(xiàn)類
類型 | Writable類 | 描述 |
---|---|---|
基本數(shù)據(jù)類型 | BooleanWritable | 存儲(chǔ)單個(gè)布爾值 |
ByteWritable | 存儲(chǔ)單個(gè)字節(jié) | |
ShortWritable | 存儲(chǔ)單個(gè)短整型 | |
IntWritable | 存儲(chǔ)單個(gè)整型 | |
VIntWritable | 存儲(chǔ)可變長(zhǎng)度的整型,優(yōu)化存儲(chǔ)空間 | |
FloatWritable | 存儲(chǔ)單個(gè)浮點(diǎn)數(shù) | |
LongWritable | 存儲(chǔ)單個(gè)長(zhǎng)整型 | |
VLongWritable | 存儲(chǔ)可變長(zhǎng)度的長(zhǎng)整型,優(yōu)化存儲(chǔ)空間 | |
DoubleWritable | 存儲(chǔ)單個(gè)雙精度浮點(diǎn)數(shù) | |
文本和字符串 | Text | 存儲(chǔ)字符串,使用UTF-8編碼 |
Writable集合類 | ArrayWritable | 存儲(chǔ)Writable 對(duì)象的數(shù)組 |
ArrayPrimitiveWritable | 存儲(chǔ)基本類型的數(shù)組,例如整型數(shù)組 | |
TwoDArrayWritable | 存儲(chǔ)二維Writable 對(duì)象數(shù)組 | |
MapWritable | 存儲(chǔ)鍵值對(duì)映射,鍵和值都是Writable 對(duì)象 | |
SortedMapWritable | 類似于MapWritable ,但保持有序 | |
EnumMapWritable | 存儲(chǔ)枚舉類型的鍵和Writable 值的映射 |
(4 序列化框架(了解,不重要)
MapReduce支持除Writable類型外的任何鍵值類型,條件是必須提供方式來(lái)轉(zhuǎn)換這些類型與二進(jìn)制表示。
特性 | 序列化IDL | Avro框架 |
---|---|---|
定義方式 | IDL文件 | JSON模式 |
語(yǔ)言支持 | 多語(yǔ)言 | 多語(yǔ)言 |
模式演變 | 復(fù)雜 | 易于管理 |
序列化性能 | 較高 | 高效 |
數(shù)據(jù)壓縮 | 需額外實(shí)現(xiàn) | 內(nèi)置支持 |
數(shù)據(jù)格式 | 二進(jìn)制/文本 | 二進(jìn)制/JSON |
默認(rèn)值支持 | 支持 | 支持 |
使用場(chǎng)景 | RPC通信 | 大數(shù)據(jù)處理 |
補(bǔ)充例:以下關(guān)于序列化Writable的說(shuō)法正確的是?(ABCD)
A、反序列化也稱反串行化,它是指將字節(jié)流轉(zhuǎn)回結(jié)構(gòu)化對(duì)象的逆過(guò)程。
B、Hadoop中使用自己開(kāi)發(fā)的類:IntWritable、FloatWritable、Text等,都是Writable的實(shí)現(xiàn)類。
C、序列化和反序列化在分布式數(shù)據(jù)處理中,主要于進(jìn)程間通信和永久存儲(chǔ)兩個(gè)領(lǐng)域。
D、Writable接口是一個(gè)序列化對(duì)象的接口,能夠?qū)?shù)據(jù)寫(xiě)入流或者從流中讀出。
4.Hadoop基于文件的數(shù)據(jù)結(jié)構(gòu)(了解即可)
(1 HDFS上的小文件問(wèn)題:文件由許多記錄(Records)組成,可以通過(guò)調(diào)用HDFS的<font style="color:rgba(6, 8, 31, 0.88);">sync()</font>
方法(與<font style="color:rgba(6, 8, 31, 0.88);">append()</font>
方法結(jié)合使用)定期生成一個(gè)大文件。也可以編寫(xiě)程序合并這些小文件。
(2 MapReduce上的小文件問(wèn)題:需要通過(guò)某種容器將文件分組,Hadoop提供了幾種選擇:HAR File、SequenceFile、MapFile,以及HBase。
(3 SequenceFile 存儲(chǔ)
特性 | 描述 |
---|---|
概述 | 存儲(chǔ)二進(jìn)制鍵值對(duì)(key-value pairs),用于高效數(shù)據(jù)序列化和壓縮 |
鍵值對(duì)存儲(chǔ) | 每個(gè)記錄由鍵(key)和值(value)組成,支持不同類型的數(shù)據(jù) |
壓縮支持 | 可選擇數(shù)據(jù)壓縮以減少存儲(chǔ)空間和提高I/O性能,下面是兩種壓縮模式。 |
- 記錄壓縮:對(duì)每條記錄的值進(jìn)行壓縮 | |
- 塊壓縮:將一連串記錄統(tǒng)一壓縮成一個(gè)塊 | |
分割支持 | 支持Hadoop輸入格式,可被MapReduce作業(yè)讀取,易于并行處理 |
寫(xiě)入和讀取 | 支持隨機(jī)訪問(wèn),適合高效讀取大規(guī)模數(shù)據(jù)集 |
類型安全 | 通過(guò)指定序列化和反序列化的類,實(shí)現(xiàn)類型安全 |
七 MapReduce編程模型(核心)
1.MapReduce基礎(chǔ)(選擇,填空) (必考)(1 MapReduce:采用分而治之的思想,將數(shù)據(jù)處理過(guò)程拆分為主要的Map(映射)和Reduce(化簡(jiǎn))兩步。
(2 MapReduce優(yōu)點(diǎn):易于編程;良好的擴(kuò)展性;高容錯(cuò)性;適合PB級(jí)別以上的大數(shù)據(jù)的分布式離線批處理
(3 MapReduce缺點(diǎn):MapReduce的執(zhí)行速度慢(這里補(bǔ)充一句:MapReduce的瓶頸主要在磁盤(pán)的I/O);MapReduce過(guò)于底層;不是所有算法都能用MapReduce實(shí)現(xiàn),不是所有算法都能實(shí)現(xiàn)并行。
2.WordCount實(shí)例分析(所有提都考)(超級(jí)重點(diǎn))
(1 Hadoop的MapReduce中,map和reduce函數(shù)遵循如下常規(guī)格式:
map:(k1,v1)–> list(k2,v2)
reduce:(k2,list(v2))–> list(k3,v3)
一般來(lái)說(shuō),map函數(shù)輸入的鍵/值類型(k1和v1)不同于輸出類型(k2和v2)。reduce函數(shù)的輸入類型必須與map函數(shù)的輸出類型相同,但是reduce函數(shù)的輸出類型(k3和v3)可以不同于輸入類型。
如果使用了combine函數(shù),它與reduce函數(shù)的形式相同,不同之處是它的輸出類型是中間的鍵值對(duì)類型(k2,v2),這些中間值可以輸入reduce函數(shù):
map:(k1,v1)–> list(k2,v2)
combine:(k2,list(v2))–> list(k2,v2)
reduce:(k2,list(v2))–> list(k3,v3)
combine函數(shù)與reduce函數(shù)通常是一樣的,在這種情況下,k3與k2類型相同,v3與v2類型相同。
補(bǔ)充例:1.MapReduce數(shù)據(jù)處理模型非常簡(jiǎn)單,map和reduce函數(shù)的輸入和輸出是鍵/值對(duì),下面選項(xiàng)中關(guān)于map和reduce輸入和輸出描述錯(cuò)誤的是()。
A、map:(k1,v1)–> list(k2,v2)
B、combine:(k2,list(v2))–> k2,list(v2)
C、reduce:(k2,list(v2))–> list(k3,v3)
D、以上都不對(duì)
2.在MapReduce編程模型中,鍵值對(duì)<key,value>的key必須實(shí)現(xiàn)下列哪個(gè)接口?(A)
A、WritableComparable B、Comparable
C、Writable D、LongWritable
補(bǔ)充:
接口 | 描述 | 是否符合鍵的要求 |
---|---|---|
WritableComparable | 繼承自 Writable 和 Comparable ,提供讀寫(xiě)序列化功能和比較功能。 | 是 |
Comparable | 僅提供比較功能,不具備序列化能力。 | 否 |
Writable | 提供讀寫(xiě)序列化功能,但不支持比較功能。 | 否 |
LongWritable | 是具體的Writable實(shí)現(xiàn),封裝了long 類型的值,但不代表所有可能的鍵類型。 | 否(但需要實(shí)現(xiàn)WritableComparable) |
(2 編寫(xiě)Mapper類
代碼說(shuō)明:Mapper類讀取輸入并執(zhí)行map函數(shù)。
Mapper類必須繼承org.apache.hadoop.mapreduce.Mapper類,并且實(shí)現(xiàn)map函數(shù)。Mapper類的4個(gè)泛型類型分別代表了:map函數(shù)輸入鍵/值對(duì)的類型和輸出鍵/值對(duì)的類型;map函數(shù)的3個(gè)參數(shù)的作用分別是?
public static class Map extends Mapper<LongWritable,Text,Text,IntWritable>{private final static IntWritable one= new IntWritable(1);private Text word= new Text();//LongWritable是輸入數(shù)據(jù)的鍵,代表行偏移量;//Text是輸入數(shù)據(jù)的值,代表該行的內(nèi)容;//Context為map函數(shù)的輸出域,用于將計(jì)算的中間結(jié)果輸出public void map(LongWritable key,Text value,Context context){StringTokenizer tokenizer= new StringTokenizer(value.toString());while(tokenizer.hasMoreTokens()){word.set(tokenizer.nextToken());try{context.write(word, one);}catch(Exception e){e.printStackTrace();}}}
}
(3 編寫(xiě)Reducer類
代碼說(shuō)明:Reducer類讀取Mapper的輸出作為reduce函數(shù)的輸入并執(zhí)行reduce函數(shù)。
Reducer類必須繼承org.apache.hadoop.mapreduce.Reducer類,并且實(shí)現(xiàn)reduce函數(shù)。Reducer類的4個(gè)泛型類型分別代表:reduce函數(shù)的輸入鍵值對(duì)類型和輸出鍵值對(duì)類型;reduce函數(shù)的3個(gè)參數(shù)的作用分別是?
public static class Reduce extends Reducer<Text, IntWritable, Text, IntWritable>{private IntWritable result= new IntWritable();//Text是輸入數(shù)據(jù)的鍵,代表一個(gè)詞;//Iterable<IntWritable>是輸入數(shù)據(jù)的值,代表該詞的計(jì)數(shù);//Context為reduce函數(shù)的輸出域,用于將計(jì)算的最終結(jié)果輸出public void reduce(Text key,Iterable<IntWritable> values,Context context){int sum=0;for(IntWritable val: values){sum+= val.get();}result.set(sum);try{context.write(key,result);}catch(Exception e){e.printStackTrace();}}
}
(4 編寫(xiě)Driver類
public class WordCount{public static void main(String[] args){Configuration conf = new Configuration();//代碼1Job job = null;//代碼2job = Job.getInstance(conf, "wordcount");//代碼3String[] otherArgs = null;try{otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();if (otherArgs.length != 2){System.err.println("Usage: wordcount <in> <out>");System.exit(1);}} catch(IOException e){e.printStackTrace();}job.setJarByClass(WordCount.class);//代碼4job.setMapperClass(Map.class);//代碼5//job.setCombinerClass(IntSumReducer.class);//代碼6job.setReducerClass(Reduce.class);//代碼7job.setOutputKeyClass(Text.class);//代碼8job.setOutputValueClass(IntWritable.class);//代碼9try{FileInputFormat.addInputPath(job, new Path(otherArgs[0]));//代碼10FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));//代碼11job.submit();} catch(Exception e){e.printStackTrace();}}
}
(5 實(shí)驗(yàn)補(bǔ)充:
Hadoop框架自帶一個(gè)MapReduce作業(yè),用于統(tǒng)計(jì)文檔中單詞出現(xiàn)的次數(shù)。下面代碼是運(yùn)行Hadoop自帶的MapReduce的過(guò)程,請(qǐng)補(bǔ)全下面代碼的空白處。
1) 啟動(dòng)Hadoop
進(jìn)入/home/hadoop/hadoop-3.1.3目錄。 cd /home/hadoop/hadoop-3.1.3
啟動(dòng)Hadoop集群。
使用jps查看集群守護(hù)進(jìn)程是否已經(jīng)全部啟動(dòng)。
2) 在本地創(chuàng)建一個(gè)測(cè)試文件
在/home/hadoop下創(chuàng)建目錄files,并進(jìn)入該目錄。
創(chuàng)建并寫(xiě)入一個(gè)文件file.txt。
3) 將本地測(cè)試文件上傳到HDFS
轉(zhuǎn)到/home/hadoop/hadoop-3.1.3目錄下。cd /home/hadoop/hadoop-3.1.3
在HDFS文件系統(tǒng)中創(chuàng)建 /input/wordcount目錄。
將第3步創(chuàng)建的一個(gè)文件,上傳到HDFS文件系統(tǒng)中。
查看文件是否上傳成功。
4) 運(yùn)行系統(tǒng)自帶的MapReduce作業(yè)
步驟 1:啟動(dòng)Hadoop
進(jìn)入Hadoop目錄并啟動(dòng)集群的命令:
# cd /home/hadoop/hadoop-3.1.3
# sbin/start-dfs.sh
# sbin/start-yarn.sh
使用jps查看集群守護(hù)進(jìn)程是否已經(jīng)全部啟動(dòng):
# jps 步驟 2:在本地創(chuàng)建一個(gè)測(cè)試文件
在/home/hadoop下創(chuàng)建目錄files并進(jìn)入該目錄:
# mkdir files
# cd files
創(chuàng)建并寫(xiě)入一個(gè)文件file.txt:
# echo "Hello Hadoop World" > file.txt 步驟 3:將本地測(cè)試文件上傳到HDFS
轉(zhuǎn)到/home/hadoop/hadoop-3.1.3目錄下:
# cd /home/hadoop/hadoop-3.1.3
在HDFS文件系統(tǒng)中創(chuàng)建/input/wordcount目錄:
# bin/hdfs dfs -mkdir -p /input/wordcount
將第2步創(chuàng)建的文件上傳到HDFS文件系統(tǒng)中:
# bin/hdfs dfs -put /home/hadoop/files/file.txt /input/wordcount/ 查看文件是否上傳成功:
# bin/hdfs dfs -ls /input/wordcount/ 步驟 4:運(yùn)行系統(tǒng)自帶的MapReduce作業(yè)
運(yùn)行MapReduce作業(yè)統(tǒng)計(jì)單詞出現(xiàn)的次數(shù):
# bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar wordcount /input/wordcount/file.txt /output/wordcount_result
查看作業(yè)輸出的結(jié)果:
# bin/hdfs dfs -cat /output/wordcount_result/part-r-00000
補(bǔ)充例:
1)下列選項(xiàng)中,Hadoop 集群的主要瓶頸是(B)。
A、CPU B、磁盤(pán) IO C、網(wǎng)絡(luò) D、內(nèi)存
2)下列關(guān)于 MapReduce 說(shuō)法不正確的是__C_。
A. MapReduce 是一種計(jì)算框架
B.MapReduce 來(lái)源于 google 的學(xué)術(shù)論文
C. MapReduce 程序只能? java 語(yǔ)言編寫(xiě)
D. MapReduce 隱藏了并行計(jì)算的細(xì)節(jié),方便使?
3)MapReduce 框架提供了一種序列化鍵/值對(duì)的方法,支持這種序列化的類能夠在 Map 和Reduce 過(guò)程中充當(dāng)鍵或值,以下說(shuō)法錯(cuò)誤的是(C)
A. 實(shí)現(xiàn) Writable 接口的類是值
B. 實(shí)現(xiàn) WritableComparable接口的類可以是值或鍵
C. Hadoop 的基本類型 Text 并不實(shí)現(xiàn) WritableComparable接口
D. 鍵和值的數(shù)據(jù)類型可以超出 Hadoop 自身支持的基本類型
- Hadoop非常擅長(zhǎng)處理非結(jié)構(gòu)化文本數(shù)據(jù),Hadoop提供了用于處理文本的不同的InputFormat類,以下說(shuō)法中錯(cuò)誤的是(A)。
A、TextInputFormat是默認(rèn)InputFormat,每條記錄是一行輸入,鍵是TextWritable類型
B、通常情況下,文件中的每一行的鍵/值對(duì),使用某個(gè)分界符進(jìn)行分隔,比如制表符。如果要正確處理這類文件,可以使用KeyValueTextInputFormat比較合適
C、通過(guò)TextInputFormat和KeyValueTextInputFormat,每個(gè)mapper收到的輸入行數(shù)不同。行數(shù)取決于輸入分片的大小和行的長(zhǎng)度
D、如果希望mapper收到固定行數(shù)的輸入,需要將NLineInputFormat作為InputFormat
5)Hadoop Streaming 支持腳本語(yǔ)言編寫(xiě)簡(jiǎn)單 MapReduce 程序,以下是一個(gè)例子:
bin/hadoop jar contrib/streaming/hadoop-0.20-streaming.jar—input input/filename—output output—mapper ‘dosth.py 5’—file dosth.py—D mapred.reduce.tasks=1
以下說(shuō)法不正確的是(D)
A. Hadoop Streaming 使? Unix 中的流與程序交互
B. Hadoop Streaming 允許我們使?任何可執(zhí)行腳本語(yǔ)言處理數(shù)據(jù)流
C. 采?腳本語(yǔ)言時(shí)必須遵從 UNIX 的標(biāo)準(zhǔn)輸入 STDIN,并輸出到 STDOUT
D. Reduce 沒(méi)有設(shè)定,上述命令運(yùn)行會(huì)出現(xiàn)問(wèn)題(補(bǔ)充:沒(méi)有設(shè)定特殊的 reducer,默認(rèn)使? IdentityReducer)
八 MapReduce的工作機(jī)制與YARN平臺(tái)(重點(diǎn))
1 YARN平臺(tái)解析(選擇、簡(jiǎn)答) (了解有印象即可,不大考)(1 YARN架構(gòu)分析(極簡(jiǎn)版):
YARN是為了處理HDFS上的數(shù)據(jù)而設(shè)計(jì)的,它把資源管理從JobTracker分離成ResourceManager(RM)和ApplicationMaster(AM)。RM負(fù)責(zé)整個(gè)集群的資源監(jiān)控、分配和管理,NM(NodeManager)負(fù)責(zé)維護(hù)單個(gè)節(jié)點(diǎn)上的資源和任務(wù)執(zhí)行,AM負(fù)責(zé)單個(gè)應(yīng)用程序的調(diào)度、協(xié)調(diào)和與RM協(xié)商資源。這使得YARN靈活且可擴(kuò)展。
(2 ResourceManager(RM):
RM主要由兩個(gè)組件構(gòu)成:調(diào)度器(Scheduler)和應(yīng)用程序管理器(ASM)。調(diào)度器:根據(jù)資源需求和限制條件,將資源以Container形式分配給應(yīng)用程序,但不處理具體應(yīng)用任務(wù)。應(yīng)用程序管理器:管理應(yīng)用程序的生命周期,包括提交、資源協(xié)商、監(jiān)控和故障重啟。
(3 ApplicationMaster(AM):
詳細(xì)功能:與調(diào)度器協(xié)商資源;與NodeManager合作,在合適的Container中運(yùn)行對(duì)應(yīng)的組件task,并監(jiān)控這些task執(zhí)行;如果Container出現(xiàn)故障,ApplicationMaster會(huì)重新向調(diào)度器申請(qǐng)其他資源;計(jì)算應(yīng)用程序所需的資源量,并轉(zhuǎn)化成調(diào)度器可識(shí)別的協(xié)議信息包
特點(diǎn):
在AM出現(xiàn)故障后,應(yīng)用管理器會(huì)負(fù)責(zé)重啟它,但由AM自己從之前保存的應(yīng)用程序執(zhí)行狀態(tài)中恢復(fù)應(yīng)用程序。
一個(gè)應(yīng)用通過(guò)ApplicationMaster可以請(qǐng)求非常具體的資源:資源名稱(包括主機(jī)名稱、機(jī)架名稱,以及可能的復(fù)雜的網(wǎng)絡(luò)拓?fù)?#xff09;;內(nèi)存量;CPU(核數(shù)/類型);其他資源,如disk/network、I/O、CPU等資源。
(4 基于YARN的MapReduce 2運(yùn)行機(jī)制(不清楚考不考,有空閑自己去了解,說(shuō)實(shí)話考的話,很過(guò)分)
補(bǔ)充例:
YARN的基本思想是將hadoop中哪個(gè)進(jìn)程,拆分成為兩個(gè)獨(dú)立的進(jìn)程:ResourceManager和ApplicationMaster。(B)
A、TaskTracker B、JobTracker C、NameNode D、DataNode
在Hadoop中,下面哪個(gè)進(jìn)程負(fù)責(zé)MapReduce任務(wù)調(diào)度(B)。
A、NameNode B、Jobtracker C、SecondaryNameNode D、TaskTracker
2.Shuffle和排序
(1 Shuffle:MapReduce 確保每個(gè) Reducer 的輸入都是按鍵排序的。系統(tǒng)執(zhí)行排序的過(guò)程,即將 map 輸出作為輸入傳給 Reducer 的過(guò)程,稱為 Shuffle。
(2 Shuffle 過(guò)程:
Map 端:
1、 每個(gè)輸入分片由一個(gè)Map任務(wù)處理,默認(rèn)分片大小為HDFS的塊大小(一般為128M),可調(diào)整。
2、 數(shù)據(jù)在寫(xiě)入磁盤(pán)前,按Reduce任務(wù)數(shù)量劃分為相應(yīng)的分區(qū),保證每個(gè)Reduce任務(wù)對(duì)應(yīng)一個(gè)分區(qū)。
3、 當(dāng) Map 任務(wù)輸出最后一個(gè)記錄時(shí),可能會(huì)有很多的溢出文件,這時(shí)需要將這些文件合并。
4、 將分區(qū)中的數(shù)據(jù)拷貝給相對(duì)應(yīng)的 Reduce 任務(wù)。
Reduce 端:
1、 Reduce 會(huì)接收到不同 Map 任務(wù)傳來(lái)的數(shù)據(jù),并且每個(gè) Map 傳來(lái)的數(shù)據(jù)都是有序的。
2、 隨著溢寫(xiě)文件的增多,后臺(tái)線程會(huì)將這些文件合并成一個(gè)更大的有序的文件,這樣做是為了給后面的合并節(jié)省時(shí)間。
3、 合并的過(guò)程中會(huì)產(chǎn)生許多的中間文件(寫(xiě)入磁盤(pán)了),但 MapReduce 會(huì)讓寫(xiě)入磁盤(pán)的數(shù)據(jù)盡可能地少,并且最后一次合并的結(jié)果并沒(méi)有寫(xiě)入磁盤(pán),而是直接輸入到 Reduce 函數(shù)。
4、 在 Reduce 階段,對(duì)已排序輸出中的每個(gè)鍵調(diào)? Reduce 函數(shù)。
(2 Shuffle過(guò)程配置調(diào)優(yōu):(了解,不大可能考,)
總的原則是給Shuffle過(guò)程盡量多提供內(nèi)存空間。但是,有一個(gè)平衡問(wèn)題,也就是要確保map函數(shù)和reduce函數(shù)能得到足夠的內(nèi)存來(lái)運(yùn)行。這就是為什么編寫(xiě)map函數(shù)和reduce函數(shù)時(shí)盡量少用內(nèi)存的原因,它們不應(yīng)該無(wú)限使用內(nèi)存,例如,應(yīng)避免在Map中堆積數(shù)據(jù)。
運(yùn)行Map任務(wù)和Reduce任務(wù)的JVM,其內(nèi)存大小由mapred.child.java.opts屬性設(shè)置。任務(wù)節(jié)點(diǎn)上的內(nèi)存大小應(yīng)該盡量大。
在跨節(jié)點(diǎn)拉取數(shù)據(jù)時(shí),盡可能地減少對(duì)帶寬的不必要消耗;
在Map端,可以通過(guò)避免多次溢出寫(xiě)磁盤(pán)來(lái)獲得最佳性能,一次是最佳的情況。如果能估算Map輸出大小,可以合理地設(shè)置ip.sort.*屬性來(lái)盡可能減少溢出寫(xiě)的次數(shù)。如果可以,就要增加io.sort.mb的值。
(3 在MapReduce計(jì)算框架中,主要使用兩種排序算法:快速排序和歸并排序。
在Map任務(wù)和Reduce任務(wù)的Shuffle過(guò)程中,共發(fā)生三次排序操作:
第一次排序:當(dāng)map函數(shù)輸出時(shí),數(shù)據(jù)首先寫(xiě)入內(nèi)存環(huán)形緩沖區(qū)。達(dá)到閥值后,后臺(tái)線程將數(shù)據(jù)劃分為分區(qū)并按鍵進(jìn)行內(nèi)排序(使用快速排序)。
第二次排序:在Map任務(wù)完成前,磁盤(pán)上存在多份已分區(qū)和排序好的溢寫(xiě)文件。這些溢寫(xiě)文件被合并為一個(gè)已分區(qū)且已排序的輸出文件,只需進(jìn)行一次排序,以保持整體有序。
第三次排序:在Shuffle的Reduce階段,多個(gè)Map任務(wù)的輸出文件被合并。由于經(jīng)過(guò)第二次排序,此時(shí)只需再做一次排序,確保最終輸出文件整體有序。
補(bǔ):速記:
第一次排序:內(nèi)存緩沖區(qū)內(nèi)排序(快速排序)。
第二次排序:文件合并階段(歸并排序)。
第三次排序:仍在文件合并階段(歸并排序)。
例:在MapReduce任務(wù)的shuffle過(guò)程中,一共發(fā)生了3次排序操作,其中第2次排序和第3次排序都是在文件合并階段發(fā)生的,使用的是下列哪種排序算法(C)。
A、快速排序 B、冒泡排序 C、歸并排序 D、倒序排序
九 MapReduce的高級(jí)概念(了解)
1. 計(jì)數(shù)器與排序(選擇)(1 內(nèi)置計(jì)數(shù)器:
常見(jiàn)MapReduce內(nèi)置計(jì)數(shù)器如下:(標(biāo)紅背過(guò))
計(jì)數(shù)器類別 | 描述 |
---|---|
File System Counters | 監(jiān)控文件系統(tǒng)相關(guān)的操作和使用情況,如讀取和寫(xiě)入的字節(jié)數(shù)。 |
Job Counters | 詳細(xì)記錄作業(yè)執(zhí)行過(guò)程中各種統(tǒng)計(jì)信息,包括輸入輸出記錄數(shù)量、總Map和Reduce任務(wù)數(shù)等。 |
Map-Reduce Framework | 監(jiān)控MapReduce框架內(nèi)部的統(tǒng)計(jì)信息,包括分片數(shù)量、Shuffle和Sort過(guò)程中的各種狀態(tài)。 |
Shuffle Errors | 記錄在Shuffle過(guò)程中發(fā)生的錯(cuò)誤數(shù)量,幫助識(shí)別和排查數(shù)據(jù)傳輸問(wèn)題。 |
File Input Format Counters | 監(jiān)控與輸入文件格式相關(guān)的統(tǒng)計(jì)信息,如讀取記錄的數(shù)量、處理錯(cuò)誤等。 |
File Output Format Counters | 監(jiān)控與輸出文件格式相關(guān)的統(tǒng)計(jì)信息,例如成功寫(xiě)入的記錄數(shù)量和字節(jié)數(shù)等。 |
補(bǔ)充例:MapReduce任務(wù)內(nèi)置了大量計(jì)數(shù)器,其中不包括(D)。
A、文件系統(tǒng)計(jì)數(shù)器(File System Counters) B、作業(yè)計(jì)算器
C、Shuffle計(jì)算器 D、詞頻計(jì)算器
(2 用戶自定義的Java計(jì)數(shù)器
計(jì)數(shù)器常見(jiàn)的方法有以下幾個(gè):
String getName():Get the name of the counter
String getDisplayName():Get the display name of the counter
long getValue():Get the current value
void setValue(long value):Set this counter by the given value
void increment(long incr):Increment this counter by the given value
(3 用戶自定義的Streaming計(jì)數(shù)器
(4 二次排序?qū)崿F(xiàn):
自定義Key:所有自定義key應(yīng)該實(shí)現(xiàn)接口WritableComparable,因?yàn)樗强尚蛄谢⑶铱杀容^的。
自定義分區(qū):自定義分區(qū)函數(shù)類DefinedPartition,是key的第一次比較,完成對(duì)所有key的排序。
自定義比較器:這是Key的第二次比較,對(duì)所有的Key進(jìn)行排序,即同時(shí)完成IntPair中的first和second排序。在Job中通過(guò)setSortComparatorClass()方法來(lái)設(shè)置key的比較器。如果沒(méi)有使用自定義的DefinedComaparator類,則默認(rèn)使用Key中compareTo()方法對(duì)Key排序。
自定義分組:在Reduce階段,構(gòu)造一個(gè)與 Key 相對(duì)應(yīng)的 Value 迭代器的時(shí)候,只要first相同就屬于同一個(gè)組,放在一個(gè)Value迭代器。
主體程序?qū)崿F(xiàn)
2.聯(lián)接:
(1 reduce side join
reduce side join 是一種最簡(jiǎn)單的 join 方式,其主要思想如下: 在 Map 階段,map 函數(shù)同時(shí)讀取兩個(gè)文件 File1 和 File2,為了區(qū)分兩種來(lái)源的 key/value 數(shù)據(jù)對(duì),對(duì)每條數(shù)據(jù)打一個(gè)標(biāo)簽(tag),比如:tag=1 表示來(lái)自文件 File1,tag=2 表示來(lái)自文件 File2。即:Map 階段的主要任務(wù)是對(duì)不同文件中的數(shù)據(jù)打標(biāo)簽。在 Reduce 階段,reduce 函數(shù)獲取 key 相同的來(lái)自File1 和 File2 文件的 value list, 然后對(duì)于同一個(gè) key,對(duì) File1 和 File2 中的數(shù)據(jù)進(jìn)行 join(笛卡爾乘積)。即:Reduce 階段進(jìn)行實(shí)際的連接操作。之所以存在 reduce side join,是因?yàn)樵?map 階段不能獲取所有需要的 join 字段,即:同一個(gè) key 對(duì)應(yīng)的字段可能位于不同 map中。reduce side join 是非常價(jià)效的,因?yàn)?Shuffle 階段要進(jìn)行大量的數(shù)據(jù)傳輸。
(2 map side join
map side join 是針對(duì)以下場(chǎng)景進(jìn)行的優(yōu)化:兩個(gè)待連接表中,有一個(gè)表非常大,而另一個(gè)表非常小,以至于小表可以直接存放到內(nèi)存中。這樣,我們可以將小表復(fù)制多份,讓每個(gè) map task 內(nèi)存中存在一份(比如存放到 hashtable 中),然后只掃描大表:對(duì)于大表中的每一條記錄 key/value,在 hash table 中查找是否有相同的 key 的記錄,如果有,則連接后輸出即可。
核心思想:將小表進(jìn)行分布式存存,在 map-task 階段讀取存存文件數(shù)據(jù)存儲(chǔ)到內(nèi)存數(shù)據(jù)結(jié)構(gòu)中,以供 reduce 階段連接查找。
適?場(chǎng)景:有一個(gè)或者多個(gè)小表(文件)
優(yōu)點(diǎn):將小表存存,可以高效查詢;由于在 map 階段進(jìn)行連接,所以將會(huì)大大減小 map到 reduce 端的數(shù)據(jù)傳輸,從而減少不必要的 shuffle 耗時(shí),提高整個(gè) mr 的執(zhí)行效率
缺點(diǎn):如果業(yè)務(wù)全是大表不適合
(3 SemiJoin
SemiJoin,也叫半連接,是從分布式數(shù)據(jù)庫(kù)中借鑒過(guò)來(lái)的方法。它的產(chǎn)生動(dòng)機(jī)是:對(duì)于 reduce side join,跨機(jī)器的數(shù)據(jù)傳輸量非常大,這成了 join 操作的一個(gè)瓶頸,如果能夠在 Map 端過(guò)濾掉不會(huì)參加 join 操作的數(shù)據(jù),則可以大大節(jié)省網(wǎng)絡(luò) IO。簡(jiǎn)單來(lái)說(shuō):就是將小表中參與join 的 key 單獨(dú)抽出來(lái)通過(guò) DistributedCach 分發(fā)到相關(guān)節(jié)點(diǎn),然后將其取出放到內(nèi)存中(可以放到 HashSet 中),在 map 階段掃描連接表,將 join key 不在內(nèi)存 HashSet 中的記錄過(guò)濾掉,讓那些參與 join 的記錄通過(guò) shuffle 傳輸?shù)?reduce 端進(jìn)行 join 操作,其他的和 reduce join 都是一樣的。
補(bǔ)充例:
1.在兩個(gè)待連接表中,有一個(gè)表非常大,而另一個(gè)表非常小,以至于小表可以直接存放到內(nèi)存中。這樣,我們可以將小表復(fù)制多份,讓每個(gè)map task內(nèi)存中存在一份(比如存放到hash table中),然后只掃描大表。在這種場(chǎng)景下可以考慮使用以下哪種join方式(A)。
A、map side join B、reduce side join
C、semiJoin D、map to reduce join
2.Hadoop中有一個(gè)distcp程序,以下說(shuō)法正確的是(D)。
A、distcp一般用于在兩個(gè)HDFS集群中傳輸數(shù)據(jù)
B、distcp可用于Hadoop文件系統(tǒng)并行復(fù)制大量數(shù)據(jù)
C、distcp復(fù)制數(shù)據(jù)時(shí)會(huì)跳過(guò)目標(biāo)路徑已有的文件,但是可通過(guò)-overwrite選項(xiàng)進(jìn)行覆蓋
D、以上說(shuō)法都是正確的
定義 | distcp (Distributed Copy)是Hadoop提供的工具,用于在HDFS集群之間進(jìn)行大規(guī)模并行數(shù)據(jù)復(fù)制。 |
---|---|
功能特性 | - 并行處理:利用MapReduce框架的分布式架構(gòu)進(jìn)行數(shù)據(jù)復(fù)制。 - 目標(biāo)路徑處理: 默認(rèn)情況下跳過(guò)目標(biāo)路徑中已存在的文件,使用 -overwrite 選項(xiàng)可強(qiáng)制覆蓋。 |
使用場(chǎng)景 | - 跨集群數(shù)據(jù)遷移 - 大數(shù)據(jù)集復(fù)制 |
常用選項(xiàng) | - -overwrite 強(qiáng)制覆蓋已有文件 其他參數(shù):可指定源路徑和目標(biāo)路徑、設(shè)置副本數(shù)量等。 |