HDFS概述HDFS產(chǎn)生背景 隨著數(shù)據(jù)量越來越大,在一個操作系統(tǒng)存不下所有的數(shù)據(jù),,那么就分配到更多的操作系統(tǒng)管理的磁盤中,,但是不方便管理和維護,,迫切需要一種系統(tǒng)來管理多臺機器上的文件,,這就是分布式文件管理系統(tǒng),。HDFS只是分布式文件管理系統(tǒng)的一種,。 HDFS定義 HDFS(Hadoop Distributed File System),它是一個文件系統(tǒng),,用于存儲文件,,通過目錄樹來定位文件,其次,,它是分布式的,,由很多服務(wù)器聯(lián)合起來來實現(xiàn)其功能,集群中的服務(wù)器有各自的角色,。 HDFS的使用場景:適合一次寫入,多次讀出的場景,,且不支持文件的修改,,適合用來做數(shù)據(jù)分析,并不適合用來網(wǎng)盤應(yīng)用,。 HDFS優(yōu)缺點優(yōu)點: 1.高容錯性 (1)數(shù)據(jù)自動保存多個副本,,它通過增加副本的形式,提高容錯性,。 (2)某一個副本丟失以后,,它可以自動恢復(fù)。 2.適合處理大數(shù)據(jù) (1)數(shù)據(jù)規(guī)模:能夠處理數(shù)據(jù)規(guī)模達到GB,,TB甚至PB級別的數(shù)據(jù) (2)文件規(guī)模:能夠處理百萬規(guī)模以上的文件數(shù)量,,數(shù)量相當之大,。 3.可構(gòu)建在廉價的機器上,通過多副本機制,,提高可靠性,。 缺點: 1.不適合低延時數(shù)據(jù)訪問,比如毫秒級的存儲數(shù)據(jù),,是做不到的,。 2.無法高效的對大量小文件進行存儲。 (1)存儲大量的小文件的話,,它只會占用NameNode大量的內(nèi)存來存儲文件目錄和塊信息,。這樣是不可取的,因為NameNode的內(nèi)存總是有限的,。 (2)小文件存儲的是尋址時間會超過讀取時間,,它違反了HDFS的設(shè)計目標。 (3)不支持并發(fā)寫入,,文件隨機修改 一個文件只能有一個寫,,不允許多個線程同時寫。 僅支持數(shù)據(jù)的append(追加),,不支持文件的隨機修改,。 HDFS組成架構(gòu)1.NameNode(nn):就是Master,它是一個主管,,管理者,。 (1)管理HDFS的名稱空間 (2)配置副本策略 (3)管理數(shù)據(jù)塊(Block)映射信息 (4)處理客戶端讀寫請求 2.DataNode:就是Slave,NameNode下達命令,,DataNode執(zhí)行實際的操作,。 (1)存儲實際的數(shù)據(jù)塊 (2)執(zhí)行數(shù)據(jù)塊的讀/寫操作 3.Client:就是客戶端 (1)文件切分,文件上傳HDFS的時候,,Client將文件切分成一個一個的Block,,然后上傳。 (2)與NameNode交互,,獲取文件的位置信息 (3)與DataNode交互,,讀取或者寫入數(shù)據(jù) (4)Client提供一些命令來管理HDFS,比如NameNode格式化 (5)Client可以通過一些命令來訪問HDFS,,比如對HDFS增刪改查操作 4.Secondary NamNode:并非NameNode的熱備,,當NameNode掛掉的時候,它并不能馬上替換NameNode并提供服務(wù),。 (1)輔助NameNode,,分擔其工作量,比如定期合并Fsimage和Edits,,并推送給NameNode,。 (2)在緊急情況下,,可輔助恢復(fù)NameNode。 HDFS文件塊大小HDFS中的文件在物理上是分塊存儲(Block),,塊的大小可以通過配置參數(shù)(dfs.blocksize)來規(guī)定,,默認大小在Hadoop2.x版本中是128M,在老版本是64M,。 為什么塊的大小不能設(shè)置太小,,也不能設(shè)置太大? (1)HDFS的塊設(shè)置太小,,會增加尋址時間,,程序一直在找塊的開始位置 (2)如果塊設(shè)置的太大,從磁盤傳輸數(shù)據(jù)的時間會明顯大于定位這個塊的開始位置所需的時間,,導(dǎo)致程序在處理這塊數(shù)據(jù)時,,會非常的慢。 HDFS塊的大小設(shè)置主要取決于磁盤的傳輸速率,。 HDFS的Shell操作bin/hadoop fs 具體命令 OR bin/hdfs dfs 具體命令 dfs是fs的實現(xiàn)類,。 常用命令實操 (1)啟動Hadoop集群 sbin/start-dfs.shsbin/start-yarn.sh (2)-help:輸出這個命令參數(shù)
(3)-ls: 顯示目錄信息 hadoop fs -ls / (4)-mkdir:在HDFS上創(chuàng)建目錄
(5)-moveFromLocal:從本地剪切粘貼到HDFS touch 111.txthadoop fs -moveFromLocal ./111.txt /test/my (6)-appendToFile:追加一個文件到已經(jīng)存在的文件末尾
(7) -cat:顯示文件內(nèi)容 hadoop fs -cat /test/my/111.txt (8) -chgrp 、-chmod,、-chown:Linux文件系統(tǒng)中的用法一樣,,修改文件所屬權(quán)限
(9)-copyFromLocal:從本地文件系統(tǒng)中拷貝文件到HDFS路徑去 hadoop fs -copyFromLocal README.txt / (10)-copyToLocal:從HDFS拷貝到本地
(11)-cp :從HDFS的一個路徑拷貝到HDFS的另一個路徑 hadoop fs -cp /test/my/111.txt /333.txt (12)-mv:在HDFS目錄中移動文件
(13)-get:等同于copyToLocal,就是從HDFS下載文件到本地 hadoop fs -get /test/my/111.txt ./ (14)-getmerge:合并下載多個文件,,比如HDFS的目錄 /user/hadoop/test下有多個文件:log.1, log.2,log.3,...
(15)-put:等同于copyFromLocal hadoop fs -put ./444.txt /user/hadoop/test/ (16)-tail:顯示一個文件的末尾
(17)-rm:刪除文件或文件夾 hadoop fs -rm /user/hadoop/test/444.txt (18)-rmdir:刪除空目錄
(19)-du統(tǒng)計文件夾的大小信息 hadoop fs -du -s -h /user/hadoop/test2.7 K /user/hadoop/test (20)-setrep:設(shè)置HDFS中文件的副本數(shù)量
這里設(shè)置的副本數(shù)只是記錄在NameNode的元數(shù)據(jù)中,,是否真的會有這么多副本,還得看DataNode的數(shù)量,。因為目前只有3臺設(shè)備,,最多也就3個副本,只有節(jié)點數(shù)的增加到10臺時,,副本數(shù)才能達到10,。 HDFS客戶端操作下載Hadoopjar包,配置環(huán)境變量,。 創(chuàng)建一個Maven工程HdfsClientDemo 導(dǎo)入相應(yīng)的依賴坐標 日志添加 <dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>RELEASE</version></dependency><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.8.2</version></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-common</artifactId><version>2.7.2</version></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-client</artifactId><version>2.7.2</version></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-hdfs</artifactId><version>2.7.2</version></dependency><dependency><groupId>jdk.tools</groupId><artifactId>jdk.tools</artifactId><version>1.8</version><scope>system</scope><systemPath>${JAVA_HOME}/lib/tools.jar</systemPath></dependency></dependencies> 在項目的src/main/resources目錄下,,新建一個文件,命名為“l(fā)og4j.properties”
創(chuàng)建包,,創(chuàng)建HdfsClient類 public class HdfsClient{@Testpublic void testMkdirs() throws IOException, InterruptedException, URISyntaxException{ // 1 獲取文件系統(tǒng)Configuration configuration = new Configuration();// 配置在集群上運行// configuration.set('fs.defaultFS', 'hdfs://hadoop102:9000');// FileSystem fs = FileSystem.get(configuration);FileSystem fs = FileSystem.get(new URI('hdfs://hadoop102:9000'), configuration, 'hadoop');// 2 創(chuàng)建目錄fs.mkdirs(new Path('/1108/daxian/banzhang'));// 3 關(guān)閉資源fs.close();}} 運行時需要配置用戶名稱 客戶端去操作HDFS時,是有一個用戶身份的,。默認情況下,,HDFS客戶端API會從JVM中獲取一個參數(shù)來作為自己的用戶身份:-DHADOOP_USER_NAME=hadoop,hadoop為用戶名稱,。 HDFS文件上傳(測試參數(shù)優(yōu)先級) 1.編寫源代碼
2.將hdfs-site.xml拷貝到項目的根目錄下 <?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet type='text/xsl' href='configuration.xsl'?><configuration><property><name>dfs.replication</name> <value>1</value></property></configuration> 3.參數(shù)優(yōu)先級 參數(shù)優(yōu)先級排序:(1)客戶端代碼中設(shè)置的值 >(2)ClassPath下的用戶自定義配置文件 >(3)然后是服務(wù)器的默認配置 HDFS文件下載
HDFS文件夾刪除 @Testpublic void testDelete() throws IOException, InterruptedException, URISyntaxException{// 1 獲取文件系統(tǒng)Configuration configuration = new Configuration();FileSystem fs = FileSystem.get(new URI('hdfs://hadoop102:9000'), configuration, 'hadoop');// 2 執(zhí)行刪除fs.delete(new Path('/0508/'), true);// 3 關(guān)閉資源fs.close();} HDFS文件名更改
HDFS文件詳情查看 查看文件名稱,、權(quán)限,、長度、塊信息 @Testpublic void testListFiles() throws IOException, InterruptedException, URISyntaxException{// 1獲取文件系統(tǒng)Configuration configuration = new Configuration();FileSystem fs = FileSystem.get(new URI('hdfs://hadoop102:9000'), configuration, 'hadoop'); // 2 獲取文件詳情RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path('/'), true);while(listFiles.hasNext()){LocatedFileStatus status = listFiles.next();// 輸出詳情// 文件名稱System.out.println(status.getPath().getName());// 長度System.out.println(status.getLen());// 權(quán)限System.out.println(status.getPermission());// 分組System.out.println(status.getGroup());// 獲取存儲的塊信息BlockLocation[] blockLocations = status.getBlockLocations();for (BlockLocation blockLocation : blockLocations) {// 獲取塊存儲的主機節(jié)點String[] hosts = blockLocation.getHosts();for (String host : hosts) {System.out.println(host);}}System.out.println('-----------班長的分割線----------');}// 3 關(guān)閉資源fs.close();} HDFS文件和文件夾判斷
HDFS的I/O流操作(擴展) API操作HDFS系統(tǒng)都是框架封裝好的,。那么如果我們想自己實現(xiàn)上述API的操作該怎么實現(xiàn)呢,? 我們可以采用IO流的方式實現(xiàn)數(shù)據(jù)的上傳和下載。 HDFS文件上傳 需求:把本地e盤上的banhua.txt文件上傳到HDFS根目錄 @Testpublic void putFileToHDFS() throws IOException, InterruptedException, URISyntaxException {// 1 獲取文件系統(tǒng)Configuration configuration = new Configuration();FileSystem fs = FileSystem.get(new URI('hdfs://hadoop102:9000'), configuration, 'hadoop');// 2 創(chuàng)建輸入流FileInputStream fis = new FileInputStream(new File('e:/banhua.txt'));// 3 獲取輸出流FSDataOutputStream fos = fs.create(new Path('/banhua.txt'));// 4 流對拷IOUtils.copyBytes(fis, fos, configuration);// 5 關(guān)閉資源IOUtils.closeStream(fos);IOUtils.closeStream(fis); fs.close();} 定位文件讀取 需求:分塊讀取HDFS上的大文件,,比如根目錄下的/hadoop-2.7.2.tar.gz (1)下載第一塊
(2)下載第二塊 @Testpublic void readFileSeek2() throws IOException, InterruptedException, URISyntaxException{// 1 獲取文件系統(tǒng)Configuration configuration = new Configuration();FileSystem fs = FileSystem.get(new URI('hdfs://hadoop102:9000'), configuration, 'atguigu');// 2 打開輸入流FSDataInputStream fis = fs.open(new Path('/hadoop-2.7.2.tar.gz'));// 3 定位輸入數(shù)據(jù)位置fis.seek(1024*1024*128);// 4 創(chuàng)建輸出流FileOutputStream fos = new FileOutputStream(new File('e:/hadoop-2.7.2.tar.gz.part2'));// 5 流的對拷IOUtils.copyBytes(fis, fos, configuration);// 6 關(guān)閉資源IOUtils.closeStream(fis);IOUtils.closeStream(fos);} (3)合并文件 在Window命令窗口中進入到目錄E:\,,然后執(zhí)行如下命令,對數(shù)據(jù)進行合并 type hadoop-2.7.2.tar.gz.part2 >> hadoop-2.7.2.tar.gz.part1 合并完成后,,將hadoop-2.7.2.tar.gz.part1重新命名為hadoop-2.7.2.tar.gz,。解壓發(fā)現(xiàn)該tar包非常完整。 HDFS的數(shù)據(jù)流HDFS寫數(shù)據(jù)流程 1)客戶端通過Distributed FileSystem模塊向NameNode請求上傳文件,,NameNode檢查目標文件是否已存在,,父目錄是否存在。 2)NameNode返回是否可以上傳,。 3)客戶端請求第一個 Block上傳到哪幾個DataNode服務(wù)器上,。 4)NameNode返回3個DataNode節(jié)點,分別為dn1,、dn2,、dn3。 5)客戶端通過FSDataOutputStream模塊請求dn1上傳數(shù)據(jù),,dn1收到請求會繼續(xù)調(diào)用dn2,,然后dn2調(diào)用dn3,將這個通信管道建立完成,。 6)dn1,、dn2、dn3逐級應(yīng)答客戶端,。 7)客戶端開始往dn1上傳第一個Block(先從磁盤讀取數(shù)據(jù)放到一個本地內(nèi)存緩存),,以Packet為單位,dn1收到一個Packet就會傳給dn2,,dn2傳給dn3,;dn1每傳一個packet會放入一個應(yīng)答隊列等待應(yīng)答。 8)當一個Block傳輸完成之后,,客戶端再次請求NameNode上傳第二個Block的服務(wù)器,。(重復(fù)執(zhí)行3-7步)。 網(wǎng)絡(luò)拓撲-節(jié)點距離計算 在HDFS寫數(shù)據(jù)的過程中,,NameNode會選擇距離待上傳數(shù)據(jù)最近距離的DataNode接收數(shù)據(jù),。那么這個最近距離怎么計算呢? 節(jié)點距離:兩個節(jié)點到達最近的共同祖先的距離總和。 例如,,假設(shè)有數(shù)據(jù)中心d1機架r1中的節(jié)點n1,。該節(jié)點可以表示為/d1/r1/n1。 機架感知 第一個副本在Client所處的節(jié)點上,,如果客戶在集群外,,隨機選一個。 第二個副本和第一個副本位于相同的機架,,隨機節(jié)點,。 第三個副本位于不同的機架,隨機節(jié)點,。 HDFS讀數(shù)據(jù)流程 1)客戶端通過Distributed FileSystem向NameNode請求下載文件,,NameNode通過查詢元數(shù)據(jù),找到文件塊所在的DataNode地址,。 2)挑選一臺DataNode(就近原則,,然后隨機)服務(wù)器,請求讀取數(shù)據(jù),。 3)DataNode開始傳輸數(shù)據(jù)給客戶端(從磁盤里面讀取數(shù)據(jù)輸入流,,以Packet為單位來做校驗)。 4)客戶端以Packet為單位接收,,先在本地緩存,,然后寫入目標文件。 NameNode和SecondaryNameNodeNN和2NN工作機制 思考:NameNode中的元數(shù)據(jù)是存儲在哪里的,? 首先,,我們做個假設(shè),如果存儲在NameNode節(jié)點的磁盤中,,因為經(jīng)常需要進行隨機訪問,,還有響應(yīng)客戶請求,必然是效率過低,。因此,,元數(shù)據(jù)需要存放在內(nèi)存中。但如果只存在內(nèi)存中,,一旦斷電,,元數(shù)據(jù)丟失,整個集群就無法工作了,。因此產(chǎn)生在磁盤中備份元數(shù)據(jù)的FsImage,。 這樣又會帶來新的問題,當在內(nèi)存中的元數(shù)據(jù)更新時,,如果同時更新FsImage,,就會導(dǎo)致效率過低,,但如果不更新,就會發(fā)生一致性問題,,一旦NameNode節(jié)點斷電,就會產(chǎn)生數(shù)據(jù)丟失,。因此,,引入Edits文件(只進行追加操作,效率很高),。每當元數(shù)據(jù)有更新或者添加元數(shù)據(jù)時,,修改內(nèi)存中的元數(shù)據(jù)并追加到Edits中。這樣,,一旦NameNode節(jié)點斷電,,可以通過FsImage和Edits的合并,合成元數(shù)據(jù),。 但是,,如果長時間添加數(shù)據(jù)到Edits中,會導(dǎo)致該文件數(shù)據(jù)過大,,效率降低,,而且一旦斷電,恢復(fù)元數(shù)據(jù)需要的時間過長,。因此,,需要定期進行FsImage和Edits的合并,如果這個操作由NameNode節(jié)點完成,,又會效率過低,。因此,引入一個新的節(jié)點SecondaryNamenode,,專門用于FsImage和Edits的合并,。 1. 第一階段:NameNode啟動 (1)第一次啟動NameNode格式化后,創(chuàng)建Fsimage和Edits文件,。如果不是第一次啟動,,直接加載編輯日志和鏡像文件到內(nèi)存。 (2)客戶端對元數(shù)據(jù)進行增刪改的請求,。 (3)NameNode記錄操作日志,,更新滾動日志。 (4)NameNode在內(nèi)存中對元數(shù)據(jù)進行增刪改,。 2. 第二階段:Secondary NameNode工作 (1)Secondary NameNode詢問NameNode是否需要CheckPoint,。直接帶回NameNode是否檢查結(jié)果。 (2)Secondary NameNode請求執(zhí)行CheckPoint,。 (3)NameNode滾動正在寫的Edits日志,。 (4)將滾動前的編輯日志和鏡像文件拷貝到Secondary NameNode。 (5)Secondary NameNode加載編輯日志和鏡像文件到內(nèi)存,并合并,。 (6)生成新的鏡像文件fsimage.chkpoint,。 (7)拷貝fsimage.chkpoint到NameNode。 (8)NameNode將fsimage.chkpoint重新命名成fsimage,。 NN和2NN工作機制詳解: Fsimage:NameNode內(nèi)存中元數(shù)據(jù)序列化后形成的文件,。 Edits:記錄客戶端更新元數(shù)據(jù)信息的每一步操作(可通過Edits運算出元數(shù)據(jù))。 NameNode啟動時,,先滾動Edits并生成一個空的edits.inprogress,,然后加載Edits和Fsimage到內(nèi)存中,此時NameNode內(nèi)存就持有最新的元數(shù)據(jù)信息,。Client開始對NameNode發(fā)送元數(shù)據(jù)的增刪改的請求,,這些請求的操作首先會被記錄到edits.inprogress中(查詢元數(shù)據(jù)的操作不會被記錄在Edits中,因為查詢操作不會更改元數(shù)據(jù)信息),,如果此時NameNode掛掉,,重啟后會從Edits中讀取元數(shù)據(jù)的信息。然后,,NameNode會在內(nèi)存中執(zhí)行元數(shù)據(jù)的增刪改的操作,。 由于Edits中記錄的操作會越來越多,Edits文件會越來越大,,導(dǎo)致NameNode在啟動加載Edits時會很慢,,所以需要對Edits和Fsimage進行合并(所謂合并,就是將Edits和Fsimage加載到內(nèi)存中,,照著Edits中的操作一步步執(zhí)行,,最終形成新的Fsimage)。SecondaryNameNode的作用就是幫助NameNode進行Edits和Fsimage的合并工作,。 SecondaryNameNode首先會詢問NameNode是否需要CheckPoint(觸發(fā)CheckPoint需要滿足兩個條件中的任意一個,,定時時間到和Edits中數(shù)據(jù)寫滿了)。直接帶回NameNode是否檢查結(jié)果,。SecondaryNameNode執(zhí)行CheckPoint操作,,首先會讓NameNode滾動Edits并生成一個空的edits.inprogress,滾動Edits的目的是給Edits打個標記,,以后所有新的操作都寫入edits.inprogress,,其他未合并的Edits和Fsimage會拷貝到SecondaryNameNode的本地,然后將拷貝的Edits和Fsimage加載到內(nèi)存中進行合并,,生成fsimage.chkpoint,,然后將fsimage.chkpoint拷貝給NameNode,重命名為Fsimage后替換掉原來的Fsimage,。NameNode在啟動時就只需要加載之前未合并的Edits和Fsimage即可,,因為合并過的Edits中的元數(shù)據(jù)信息已經(jīng)被記錄在Fsimage中,。 Fsimage和Edits解析 NameNode被格式化之后,將在 fsimage_0000000000000000000 fsimage_0000000000000000000.md5 seen_txid VERSION (1)Fsimage文件:HDFS文件系統(tǒng)元數(shù)據(jù)的一個永久性檢查點,,其中包含HDFS文件系統(tǒng)的所有目錄和文件inode的序列化信息,。 (2)Edits文件:存放HDFS文件系統(tǒng)的所有更新操作,文件系統(tǒng)客戶端執(zhí)行的所有寫操作首先會記錄到Edits文件中,。 (3)seen_txid文件保存的是一個數(shù)字,,就是最后一個edits_數(shù)字 (4)每次NameNode啟動的時候都會 將Fsimage文件讀入內(nèi)存,加載Edits里面的更新操作,,保證內(nèi)存中的元數(shù)據(jù)信息是最新的,同步的,,可以看成NameNode啟動的時候就將Fsimage和Edits文件進行了合并,。 oiv查看Fsimage文件 (1)查看oiv和oev命令
(2)基本語法 hdfs oiv -p 文件類型 -i鏡像文件 -o 轉(zhuǎn)換后文件輸出路徑 (3)案例實操 pwd/opt/module/hadoop-2.7.2/data/tmp/dfs/name/current
cat /opt/module/hadoop-2.7.2/fsimage.xml 將顯示的xml文件內(nèi)容拷貝到Eclipse中創(chuàng)建的xml文件中,并格式化,。部分顯示結(jié)果如下,。
可以看出,F(xiàn)simage中沒有記錄塊所對應(yīng)DataNode,。因為在集群啟動后,,要求DataNode上報數(shù)據(jù)塊信息,并間隔一段時間后再次上報,。 oev查看Edits文件 (1)基本語法 hdfs oev -p 文件類型 -i編輯日志 -o 轉(zhuǎn)換后文件輸出路徑 (2)案例實操 hdfs oev -p XML -i edits_0000000000000000012-0000000000000000013 -o /opt/module/hadoop-2.7.2/edits.xml
將顯示的xml文件內(nèi)容拷貝到Eclipse中創(chuàng)建的xml文件中,,并格式化。顯示結(jié)果如下,。 <?xml version='1.0' encoding='UTF-8'?><EDITS><EDITS_VERSION>-63</EDITS_VERSION><RECORD><OPCODE>OP_START_LOG_SEGMENT</OPCODE><DATA><TXID>129</TXID></DATA></RECORD><RECORD><OPCODE>OP_ADD</OPCODE><DATA><TXID>130</TXID><LENGTH>0</LENGTH><INODEID>16407</INODEID><PATH>/hello7.txt</PATH><REPLICATION>2</REPLICATION><MTIME>1512943607866</MTIME><ATIME>1512943607866</ATIME><BLOCKSIZE>134217728</BLOCKSIZE><CLIENT_NAME>DFSClient_NONMAPREDUCE_-1544295051_1</CLIENT_NAME><CLIENT_MACHINE>192.168.1.5</CLIENT_MACHINE><OVERWRITE>true</OVERWRITE><PERMISSION_STATUS><USERNAME>atguigu</USERNAME><GROUPNAME>supergroup</GROUPNAME><MODE>420</MODE></PERMISSION_STATUS><RPC_CLIENTID>908eafd4-9aec-4288-96f1-e8011d181561</RPC_CLIENTID><RPC_CALLID>0</RPC_CALLID></DATA></RECORD><RECORD><OPCODE>OP_ALLOCATE_BLOCK_ID</OPCODE><DATA><TXID>131</TXID><BLOCK_ID>1073741839</BLOCK_ID></DATA></RECORD><RECORD><OPCODE>OP_SET_GENSTAMP_V2</OPCODE><DATA><TXID>132</TXID><GENSTAMPV2>1016</GENSTAMPV2></DATA></RECORD><RECORD><OPCODE>OP_ADD_BLOCK</OPCODE><DATA><TXID>133</TXID><PATH>/hello7.txt</PATH><BLOCK><BLOCK_ID>1073741839</BLOCK_ID><NUM_BYTES>0</NUM_BYTES><GENSTAMP>1016</GENSTAMP></BLOCK><RPC_CLIENTID></RPC_CLIENTID><RPC_CALLID>-2</RPC_CALLID></DATA></RECORD><RECORD><OPCODE>OP_CLOSE</OPCODE><DATA><TXID>134</TXID><LENGTH>0</LENGTH><INODEID>0</INODEID><PATH>/hello7.txt</PATH><REPLICATION>2</REPLICATION><MTIME>1512943608761</MTIME><ATIME>1512943607866</ATIME><BLOCKSIZE>134217728</BLOCKSIZE><CLIENT_NAME></CLIENT_NAME><CLIENT_MACHINE></CLIENT_MACHINE><OVERWRITE>false</OVERWRITE><BLOCK><BLOCK_ID>1073741839</BLOCK_ID><NUM_BYTES>25</NUM_BYTES><GENSTAMP>1016</GENSTAMP></BLOCK><PERMISSION_STATUS><USERNAME>atguigu</USERNAME><GROUPNAME>supergroup</GROUPNAME><MODE>420</MODE></PERMISSION_STATUS></DATA></RECORD></EDITS > NameNode如何確定下次開機啟動的時候合并哪些Edits,? CheckPoint時間設(shè)置 (1)通常情況下,SecondaryNameNode每隔一小時執(zhí)行一次,。 [hdfs-default.xml]
(2)一分鐘檢查一次操作次數(shù),,當操作次數(shù)達到1百萬時,SecondaryNameNode執(zhí)行一次,。 <property> <name>dfs.namenode.checkpoint.txns</name> <value>1000000</value><description>操作動作次數(shù)</description></property><property> <name>dfs.namenode.checkpoint.check.period</name> <value>60</value><description> 1分鐘檢查一次操作次數(shù)</description></property > NameNode故障處理 NameNode故障后,,可以采用如下兩種方法恢復(fù)數(shù)據(jù)。 方法一:將SecondaryNameNode中數(shù)據(jù)拷貝到NameNode存儲數(shù)據(jù)的目錄,; 1. kill -9 NameNode進程 2. 刪除NameNode存儲的數(shù)據(jù)(
3. 拷貝SecondaryNameNode中數(shù)據(jù)到原NameNode存儲數(shù)據(jù)目錄 scp -r hadoop@hadoop104:/opt/module/hadoop-2.7.2/data/tmp/dfs/namesecondary/* ./name/ 4. 重新啟動NameNode
方法二:使用-importCheckpoint選項啟動NameNode守護進程,,從而將SecondaryNameNode中數(shù)據(jù)拷貝到NameNode目錄中。 1. 修改hdfs-site.xml中的 <property> <name>dfs.namenode.checkpoint.period</name> <value>120</value></property><property> <name>dfs.namenode.name.dir</name> <value>/opt/module/hadoop-2.7.2/data/tmp/dfs/name</value></property> 2. kill -9 NameNode進程 3. 刪除NameNode存儲的數(shù)據(jù)(
4. 如果SecondaryNameNode不和NameNode在一個主機節(jié)點上,,需要將SecondaryNameNode存儲數(shù)據(jù)的目錄拷貝到NameNode存儲數(shù)據(jù)的平級目錄,,并刪除in_use.lock文件 scp -r atguigu@hadoop104:/opt/module/hadoop-2.7.2/data/tmp/dfs/namesecondary ./ rm -rf in_use.lockpwd/opt/module/hadoop-2.7.2/data/tmp/dfslsdata name namesecondary 5. 導(dǎo)入檢查點數(shù)據(jù)(等待一會ctrl c結(jié)束掉)
6. 啟動NameNode sbin/hadoop-daemon.sh start namenode 集群安全模式 1.NameNode啟動 NameNode啟動時,首先將鏡像文件(Fsiamge)載入內(nèi)存,,并執(zhí)行編輯日志(Edits)中的各項操作,。一旦在內(nèi)存中成功建立文件系統(tǒng)元數(shù)據(jù)的映像,,則創(chuàng)建一個新的Fsimage文件和一個空的編輯日志。此時,,NameNode開始監(jiān)聽DataNode請求,。這個過程期間,NameNode一直運行在安全模式,,即NameNode的文件系統(tǒng)對與客戶端來說只是只讀的,。 2.DataNode啟動 系統(tǒng)中的數(shù)據(jù)塊的位置并不是由NameNode維護的,而是以塊列表的形式存儲在DataNode中,。在系統(tǒng)的正常操作期間,,NameNode會在內(nèi)存中保留所有垮位置的映射信息。在安全模式下,,各個DataNode會向NameNode發(fā)送最新的塊列表信息,。NameNode了解足夠多的塊位置信息之后,即可高效運行文件系統(tǒng),。 3.安全模式退出判斷 如果滿足“最小副本條件”,,NameNode會在30秒鐘之后就退出安全模式。所謂的最小副本條件指的是在整個文件系統(tǒng)中99.9%的塊滿足最小副本級別(默認值:dfs:relication=1),。在啟動一個剛剛格式化的HDFS集群中,,因為系統(tǒng)中還沒有任何塊,所以NameNode不會進入安全模式,。 基本語法 集群處于安全模式,,不能執(zhí)行重要操作(寫操作)。集群啟動完成后,,自動退出安全模式,。 (1)bin/hdfs dfsadmin -safemode get (功能描述:查看安全模式狀態(tài)) (2)bin/hdfs dfsadmin -safemode enter (功能描述:進入安全模式狀態(tài)) (3)bin/hdfs dfsadmin -safemode leave (功能描述:離開安全模式狀態(tài)) (4)bin/hdfs dfsadmin -safemode wait (功能描述:等待安全模式狀態(tài)) 模擬等待安全模式 (1)查看當前模式
(2)先進入安全模式 bin/hdfs dfsadmin -safemode enter (3)創(chuàng)建并執(zhí)行下面的腳本 在/opt/module/hadoop-2.7.2路徑上,編輯一個腳本safemode.sh
chmod 777 safemode.sh./safemode.sh (4)再打開一個窗口,,執(zhí)行
(5)觀察 (a)再觀察上一個窗口 Safe mode is OFF (b)HDFS集群上已經(jīng)有上傳的數(shù)據(jù)了,。 DataNodeDataNode工作機制 1)一個數(shù)據(jù)塊在DataNode上以文件形式存儲在磁盤上,包括兩個文件,,一個是數(shù)據(jù)本身,,一個是元數(shù)據(jù)包括數(shù)據(jù)塊的長度,塊數(shù)據(jù)的校驗和,,以及時間戳,。 2)DataNode啟動后向NameNode注冊,通過后,,周期性(1小時)的向NameNode上報所有的塊信息,。 3)心跳是每3秒一次,心跳返回結(jié)果帶有NameNode給該DataNode的命令如復(fù)制塊數(shù)據(jù)到另一臺機器,,或刪除某個數(shù)據(jù)塊,。如果超過10分鐘沒有收到某個DataNode的心跳,,則認為該節(jié)點不可用。 4)集群運行中可以安全加入和退出一些機器,。 數(shù)據(jù)完整性 思考:如果電腦磁盤里面存儲的數(shù)據(jù)是控制高鐵信號燈的紅燈信號(1)和綠燈信號(0),,但是存儲該數(shù)據(jù)的磁盤壞了,一直顯示是綠燈,,是否很危險,?同理DataNode節(jié)點上的數(shù)據(jù)損壞了,卻沒有發(fā)現(xiàn),,是否也很危險,,那么如何解決呢? 如下是DataNode節(jié)點保證數(shù)據(jù)完整性的方法,。 1)當DataNode讀取Block的時候,,它會計算CheckSum。 2)如果計算后的CheckSum,,與Block創(chuàng)建時值不一樣,說明Block已經(jīng)損壞,。 3)Client讀取其他DataNode上的Block,。 4)DataNode在其文件創(chuàng)建后周期驗證CheckSum,如圖3-16所示,。 掉線時限參數(shù)設(shè)置 需要注意的是hdfs-site.xml 配置文件中的 <property> <name>dfs.namenode.heartbeat.recheck-interval</name> <value>300000</value></property><property> <name>dfs.heartbeat.interval</name> <value>3</value></property> 服役新數(shù)據(jù)節(jié)點 需求 隨著公司業(yè)務(wù)的增長,,數(shù)據(jù)量越來越大,,原有的數(shù)據(jù)節(jié)點的容量已經(jīng)不能滿足存儲數(shù)據(jù)的需求,需要在原有集群基礎(chǔ)上動態(tài)添加新的數(shù)據(jù)節(jié)點,。 1. 環(huán)境準備 (1)在hadoop104主機上再克隆一臺hadoop105主機 (2)修改IP地址和主機名稱 (3)刪除原來HDFS文件系統(tǒng)留存的文件( (4)source一下配置文件,,source /etc/profile 2.服役新節(jié)點具體步驟 (1)直接啟動DataNode,即可關(guān)聯(lián)到集群
(2)在hadoop105上上傳文件 hadoop fs -put /opt/module/hadoop-2.7.2/LICENSE.txt / (3)如果數(shù)據(jù)不均衡,,可以用命令實現(xiàn)集群的再平衡
退役舊數(shù)據(jù)節(jié)點 添加白名單 添加到白名單的主機節(jié)點,,都允許訪問NameNode,不在白名單的主機節(jié)點,,都會被退出,。 配置白名單的具體步驟如下: (1)在NameNode的 pwd/opt/module/hadoop-2.7.2/etc/hadoop touch dfs.hosts vi dfs.hosts 添加如下主機名稱(不添加hadoop105)
(2)在NameNode的hdfs-site.xml配置文件中增加dfs.hosts屬性 <property><name>dfs.hosts</name><value>/opt/module/hadoop-2.7.2/etc/hadoop/dfs.hosts</value></property> (3)配置文件分發(fā)
(4)刷新NameNode hdfs dfsadmin -refreshNodes (5)更新ResourceManager節(jié)點
(6)在web瀏覽器上查看 4. 如果數(shù)據(jù)不均衡,可以用命令實現(xiàn)集群的再平衡 ./start-balancer.sh 黑名單退役 在黑名單上面的主機都會被強制退出,。 1.在NameNode的
添加如下主機名稱(要退役的節(jié)點) hadoop105 2.在NameNode的hdfs-site.xml配置文件中增加dfs.hosts.exclude屬性
3.刷新NameNode、刷新ResourceManager hdfs dfsadmin -refreshNodesRefresh nodes successfulyarn rmadmin -refreshNodes 4. 檢查Web瀏覽器,,退役節(jié)點的狀態(tài)為decommission in progress(退役中),,說明數(shù)據(jù)節(jié)點正在復(fù)制塊到其他節(jié)點 等待退役節(jié)點狀態(tài)為decommissioned(所有塊已經(jīng)復(fù)制完成),,停止該節(jié)點及節(jié)點資源管理器。注意:如果副本數(shù)是3,,服役的節(jié)點小于等于3,,是不能退役成功的,需要修改副本數(shù)后才能退役,。
sbin/yarn-daemon.sh stop nodemanager 6. 如果數(shù)據(jù)不均衡,,可以用命令實現(xiàn)集群的再平衡
Datanode多目錄配置 1. DataNode也可以配置成多個目錄,每個目錄存儲的數(shù)據(jù)不一樣,。即:數(shù)據(jù)不是副本 2.具體配置如下 hdfs-site.xml <property> <name>dfs.datanode.data.dir</name><value>file:///${hadoop.tmp.dir}/dfs/data1,file:///${hadoop.tmp.dir}/dfs/data2</value></property> Hadoop小文件每個文件均按塊存儲,,每個塊的元數(shù)據(jù)存儲在NameNode的內(nèi)存中,因此HDFS存儲小文件會非常低效,。因為大量的小文件會耗盡NameNode中的大部分內(nèi)存,。但注意,存儲小文件所需要的磁盤容量和數(shù)據(jù)塊的大小無關(guān),。例如,,一個1MB的文件設(shè)置為128M的塊存儲,實際使用的是1MB的磁盤空間,。 HDFS存檔文件或HAR文件,,是一個高效的文件存檔工具,它將文件存入HDFS塊,,在減少NameNode內(nèi)存使用的同時,,允許對文件進行透明的訪問。具體來說,,HDFS存檔文件對內(nèi)還是一個一個獨立文件,,對NameNode而言卻是一個整體,減少了NameNode的內(nèi)存,。 (1)需要啟動Yarn進程
(2)歸檔文件 把/user/hadoop/input目錄里面的所有文件歸檔成一個叫input.har的歸檔文件,,并把歸檔后文件存儲到/user/hadoop/output路徑下。 bin/hadoop archive -archiveName input.har –p /user/hadoop/input /user/hadoop/output (3)查看歸檔
(4)解歸檔文件 hadoop fs -cp har:/// user/hadoop/output/input.har/* /user/hadoop HDFS HA高可用HA概述 1)所謂HA(High Available),,即高可用(7*24小時不中斷服務(wù)),。 2)實現(xiàn)高可用最關(guān)鍵的策略是消除單點故障。HA嚴格來說應(yīng)該分成各個組件的HA機制: HDFS的HA和YARN的HA,。 3)Hadoop2.0之前,,在HDFS集群中NameNode存在單點故障(SPOF)。 4)NameNode主要在以下兩個方面影響HDFS集群 NameNode機器發(fā)生意外,,如宕機,,集群將無法使用,直到管理員重啟 NameNode機器需要升級,,包括軟件,、硬件升級,,此時集群也將無法使用 HDFS HA功能通過配置Active/Standby兩個NameNodes實現(xiàn)在集群中對NameNode的熱備來解決上述問題。如果出現(xiàn)故障,,如機器崩潰或機器需要升級維護,,這時可通過此種方式將NameNode很快的切換到另外一臺機器。 HDFS-HA工作機制 通過雙NameNode消除單點故障 HDFS-HA工作要點 1. 元數(shù)據(jù)管理方式需要改變 內(nèi)存中各自保存一份元數(shù)據(jù),; Edits日志只有Active狀態(tài)的NameNode節(jié)點可以做寫操作,; 兩個NameNode都可以讀取Edits; 共享的Edits放在一個共享存儲中管理(qjournal和NFS兩個主流實現(xiàn)),; 2. 需要一個狀態(tài)管理功能模塊 實現(xiàn)了一個zkfailover,,常駐在每一個namenode所在的節(jié)點,每一個zkfailover負責監(jiān)控自己所在NameNode節(jié)點,,利用zk進行狀態(tài)標識,,當需要進行狀態(tài)切換時,由zkfailover來負責切換,,切換時需要防止brain split現(xiàn)象的發(fā)生,。 3. 必須保證兩個NameNode之間能夠ssh無密碼登錄 4. 隔離(Fence),即同一時刻僅僅有一個NameNode對外提供服務(wù) HDFS-HA自動故障轉(zhuǎn)移工作機制 使用命令hdfs haadmin -failover手動進行故障轉(zhuǎn)移,,在該模式下,,即使現(xiàn)役NameNode已經(jīng)失效,系統(tǒng)也不會自動從現(xiàn)役NameNode轉(zhuǎn)移到待機NameNode,。如何配置部署HA自動進行故障轉(zhuǎn)移?自動故障轉(zhuǎn)移為HDFS部署增加了兩個新組件:ZooKeeper和ZKFailoverController(ZKFC)進程,,ZooKeeper是維護少量協(xié)調(diào)數(shù)據(jù),,通知客戶端這些數(shù)據(jù)的改變和監(jiān)視客戶端故障的高可用服務(wù)。HA的自動故障轉(zhuǎn)移依賴于ZooKeeper的以下功能: 1)故障檢測:集群中的每個NameNode在ZooKeeper中維護了一個持久會話,,如果機器崩潰,,ZooKeeper中的會話將終止,ZooKeeper通知另一個NameNode需要觸發(fā)故障轉(zhuǎn)移,。 2)現(xiàn)役NameNode選擇:ZooKeeper提供了一個簡單的機制用于唯一的選擇一個節(jié)點為active狀態(tài),。如果目前現(xiàn)役NameNode崩潰,另一個節(jié)點可能從ZooKeeper獲得特殊的排外鎖以表明它應(yīng)該成為現(xiàn)役NameNode,。 ZKFC是自動故障轉(zhuǎn)移中的另一個新組件,,是ZooKeeper的客戶端,也監(jiān)視和管理NameNode的狀態(tài),。每個運行NameNode的主機也運行了一個ZKFC進程,,ZKFC負責: 1)健康監(jiān)測:ZKFC使用一個健康檢查命令定期地ping與之在相同主機的NameNode,只要該NameNode及時地恢復(fù)康狀態(tài),,ZKFC認為該節(jié)點是健康的,。如果該節(jié)點崩潰,,凍結(jié)或進入不健康狀態(tài),健康監(jiān)測器標識該節(jié)點為非健康的,。 2)ZooKeeper會話管理:當本地NameNode是健康的,,ZKFC保持一個在ZooKeeper中打開的會話。如果本地NameNode處于active狀態(tài),,ZKFC也保持一個特殊的znode鎖,,該鎖使用了ZooKeeper對短暫節(jié)點的支持,如果會話終止,,鎖節(jié)點將自動刪除,。 3)基于ZooKeeper的選擇:如果本地NameNode是健康的,且ZKFC發(fā)現(xiàn)沒有其它的節(jié)點當前持有znode鎖,,它將為自己獲取該鎖,。如果成功,則它已經(jīng)贏得了選擇,,并負責運行故障轉(zhuǎn)移進程以使它的本地NameNode為Active,。故障轉(zhuǎn)移進程與前面描述的手動故障轉(zhuǎn)移相似,首先如果必要保護之前的現(xiàn)役NameNode,,然后本地NameNode轉(zhuǎn)換為Active狀態(tài),。 HDFS-HA集群配置 環(huán)境準備 1. 修改IP 2. 修改主機名及主機名和IP地址的映射 3. 關(guān)閉防火墻 4. ssh免密登錄 5. 安裝JDK,配置環(huán)境變量等 配置Zookeeper集群 1. 集群規(guī)劃 在hadoop102,、hadoop103和hadoop104三個節(jié)點上部署Zookeeper,。 2. 解壓安裝 (1)解壓Zookeeper安裝包到/opt/module/目錄下
(2)在 mkdir -p zkData (3)重命名
3. 配置zoo.cfg文件 (1)具體配置 dataDir=/opt/module/zookeeper-3.4.10/zkData 增加如下配置
(2)配置參數(shù)解讀 Server.A=B:C:D。 A是一個數(shù)字,,表示這個是第幾號服務(wù)器,; B是這個服務(wù)器的IP地址; C是這個服務(wù)器與集群中的Leader服務(wù)器交換信息的端口,; D是萬一集群中的Leader服務(wù)器掛了,,需要一個端口來重新進行選舉,選出一個新的Leader,,而這個端口就是用來執(zhí)行選舉時服務(wù)器相互通信的端口,。 集群模式下配置一個文件myid,這個文件在dataDir目錄下,,這個文件里面有一個數(shù)據(jù)就是A的值,,Zookeeper啟動時讀取此文件,拿到里面的數(shù)據(jù)與zoo.cfg里面的配置信息比較從而判斷到底是哪個server,。 4. 集群操作 (1)在 touch myid 添加myid文件,,注意一定要在linux里面創(chuàng)建,在notepad 里面很可能亂碼 (2)編輯myid文件
在文件中添加與server對應(yīng)的編號:如2 (3)拷貝配置好的zookeeper到其他機器上 scp -r zookeeper-3.4.10/ root@hadoop103.atguigu.com:/opt/app/scp -r zookeeper-3.4.10/ root@hadoop104.atguigu.com:/opt/app/ 并分別修改myid文件中內(nèi)容為3、4 (4)分別啟動zookeeper
(5)查看狀態(tài) bin/zkServer.sh status 配置HDFS-HA集群 1. 官方地址:http://hadoop./ 2. 在opt目錄下創(chuàng)建一個ha文件夾
3. 將/opt/app/下的 hadoop-2.7.2拷貝到/opt/ha目錄下 cp -r hadoop-2.7.2/ /opt/ha/ 4. 配置hadoop-env.sh
5. 配置core-site.xml <configuration><!-- 把兩個NameNode)的地址組裝成一個集群mycluster --><property><name>fs.defaultFS</name> <value>hdfs://mycluster</value></property><!-- 指定hadoop運行時產(chǎn)生文件的存儲目錄 --><property><name>hadoop.tmp.dir</name><value>/opt/ha/hadoop-2.7.2/data/tmp</value></property></configuration> 6. 配置hdfs-site.xml
7. 拷貝配置好的hadoop環(huán)境到其他節(jié)點 啟動HDFS-HA集群 1. 在各個JournalNode節(jié)點上,,輸入以下命令啟動journalnode服務(wù) sbin/hadoop-daemon.sh start journalnode 2. 在[nn1]上,,對其進行格式化,并啟動
3. 在[nn2]上,,同步nn1的元數(shù)據(jù)信息 bin/hdfs namenode -bootstrapStandby 4. 啟動[nn2]
5. 查看web頁面顯示 6. 在[nn1]上,,啟動所有datanode sbin/hadoop-daemons.sh start datanode 7. 將[nn1]切換為Active
8. 查看是否Active bin/hdfs haadmin -getServiceState nn1 配置HDFS-HA自動故障轉(zhuǎn)移 1. 具體配置 (1)在hdfs-site.xml中增加
(2)在core-site.xml文件中增加 <property><name>ha.zookeeper.quorum</name><value>hadoop102:2181,hadoop103:2181,hadoop104:2181</value></property> 2. 啟動 (1)關(guān)閉所有HDFS服務(wù):
(2)啟動Zookeeper集群: bin/zkServer.sh start (3)初始化HA在Zookeeper中狀態(tài):
(4)啟動HDFS服務(wù): sbin/start-dfs.sh 3. 驗證 (1)將Active NameNode進程kill
(2)將Active NameNode機器斷開網(wǎng)絡(luò) service network stop YARN-HA配置 YARN-HA工作機制 1. 官方文檔: http://hadoop./docs/r2.7.2/hadoop-yarn/hadoop-yarn-site/ResourceManagerHA.html 2. YARN-HA工作機制 配置YARN-HA集群 1. 環(huán)境準備 (1)修改IP (2)修改主機名及主機名和IP地址的映射 (3)關(guān)閉防火墻 (4)ssh免密登錄 (5)安裝JDK,配置環(huán)境變量等 (6)配置Zookeeper集群 2. 規(guī)劃集群 3. 具體配置 (1)yarn-site.xml
(2)同步更新其他節(jié)點的配置信息 4. 啟動hdfs (1)在各個JournalNode節(jié)點上,,輸入以下命令啟動journalnode服務(wù): sbin/hadoop-daemon.sh start journalnode (2)在[nn1]上,,對其進行格式化,并啟動:
sbin/hadoop-daemon.sh start namenode (3)在[nn2]上,,同步nn1的元數(shù)據(jù)信息:
(4)啟動[nn2]: sbin/hadoop-daemon.sh start namenode (5)啟動所有DataNode
(6)將[nn1]切換為Active bin/hdfs haadmin -transitionToActive nn1 5. 啟動YARN (1)在hadoop102中執(zhí)行:
(2)在hadoop103中執(zhí)行: sbin/yarn-daemon.sh start resourcemanager (3)查看服務(wù)狀態(tài)
|
|
來自: Fengsq501u81r4 > 《計算機》