第1章 HDFS概述
1.1 HDFS產(chǎn)出背景及定義
1.1.1 HDFS產(chǎn)生背景
隨著數(shù)據(jù)量越來越大逞姿,在一個操作系統(tǒng)存不下所有的數(shù)據(jù),那么就分配到更多的操作系統(tǒng)管理的磁盤中汰蓉,但是不方便管理和維護(hù)泛源,迫切需要一種系統(tǒng)來管理多臺機器上的文件究珊,這就是分布式文件管理系統(tǒng)婴氮。HDFS只是分布式文件管理系統(tǒng)中的一種只洒。
1.1.2 HDFS定義
HDFS(Hadoop Distributed File System)许帐,它是一個文件系統(tǒng),用于存儲文件毕谴,通過目錄樹來定位文件成畦;其次,它是分布式的涝开,由很多服務(wù)器聯(lián)合起來實現(xiàn)其功能循帐,集群中的服務(wù)器有各自的角色。
HDFS的使用場景:適合一次寫入舀武,多次讀出的場景拄养,且不支持文件的修改。適合用來做數(shù)據(jù)分析银舱,并不適合用來做網(wǎng)盤應(yīng)用瘪匿。
1.2 HDFS優(yōu)缺點
1.2.1 優(yōu)點
1)高容錯性
(1)數(shù)據(jù)自動保存多個副本。它通過增加副本的形式寻馏,提高容錯性柿顶。
(2)某一個副本丟失以后,它可以自動恢復(fù)操软。
2)適合處理大數(shù)據(jù)
(1)數(shù)據(jù)規(guī)模:能夠處理數(shù)據(jù)規(guī)模達(dá)到GB嘁锯、TB、甚至PB級別的數(shù)據(jù)聂薪;
(2)文件規(guī)模:能夠處理百萬規(guī)模以上的文件數(shù)量家乘,數(shù)量相當(dāng)之大。
3)可構(gòu)建在廉價機器上藏澳,通過多副本機制仁锯,提高可靠性。
1.2.2 缺點
1)不適合低延時數(shù)據(jù)訪問翔悠,比如毫秒級的存儲數(shù)據(jù)业崖,是做不到的。
2)無法高效的對大量小文件進(jìn)行存儲蓄愁。
(1)存儲大量小文件的話双炕,它會占用NameNode大量的內(nèi)存來存儲文件目錄和塊信息。這樣是不可取的撮抓,因為NameNode的內(nèi)存總是有限的妇斤;
(2)小文件存儲的尋址時間會超過讀取時間,它違反了HDFS的設(shè)計目標(biāo)。
3)不支持并發(fā)寫入站超、文件隨機修改荸恕。
(1)一個文件只能有一個寫,不允許多個線程同時寫死相;
(2)僅支持?jǐn)?shù)據(jù)append(追加)融求,不支持文件的隨機修改。
1.3 HDFS組成架構(gòu)
1.4 HDFS文件塊大小
HDFS中的文件在物理上是分塊存儲(Block)算撮,塊的大小可以通過配置參數(shù)( dfs.blocksize)來規(guī)定生宛,默認(rèn)大小在Hadoop2.x版本中是128M,老版本中是64M钮惠。
HDFS的塊設(shè)置太小,會增加尋址時間七芭,程序一直在找塊的開始位置素挽;
如果塊設(shè)置的太大,從磁盤傳輸數(shù)據(jù)的時間會明顯大于定位這個塊開始位置所需的時間狸驳。導(dǎo)致程序在處理這塊數(shù)據(jù)時预明,會非常慢。
HDFS塊的大小設(shè)置主要取決于磁盤傳輸速率耙箍。
第2章 HDFS的Shell操作
2.1 基本語法
bin/hadoop fs 具體命令 OR bin/hdfs dfs 具體命令
dfs是fs的實現(xiàn)類撰糠。
2.2 命令大全
[hadoop@hadoop101 hadoop-2.7.2]$ bin/hadoop fs
[-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] <localsrc> ... <dst>]
[-copyToLocal [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]
[-count [-q] <path> ...]
[-cp [-f] [-p] <src> ... <dst>]
[-createSnapshot <snapshotDir> [<snapshotName>]]
[-deleteSnapshot <snapshotDir> <snapshotName>]
[-df [-h] [<path> ...]]
[-du [-s] [-h] <path> ...]
[-expunge]
[-get [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]
[-getfacl [-R] <path>]
[-getmerge [-nl] <src> <localdst>]
[-help [cmd ...]]
[-ls [-d] [-h] [-R] [<path> ...]]
[-mkdir [-p] <path> ...]
[-moveFromLocal <localsrc> ... <dst>]
[-moveToLocal <src> <localdst>]
[-mv <src> ... <dst>]
[-put [-f] [-p] <localsrc> ... <dst>]
[-renameSnapshot <snapshotDir> <oldName> <newName>]
[-rm [-f] [-r|-R] [-skipTrash] <src> ...]
[-rmdir [--ignore-fail-on-non-empty] <dir> ...]
[-setfacl [-R] [{-b|-k} {-m|-x <acl_spec>} <path>]|[--set <acl_spec> <path>]]
[-setrep [-R] [-w] <rep> <path> ...]
[-stat [format] <path> ...]
[-tail [-f] <file>]
[-test -[defsz] <path>]
[-text [-ignoreCrc] <src> ...]
[-touchz <path> ...]
[-usage [cmd ...]]
2.3 常用命令實操
(0)啟動Hadoop集群
[hadoop@hadoop101 hadoop-2.7.2]$ sbin/start-dfs.sh
[hadoop@hadoop102 hadoop-2.7.2]$ sbin/start-yarn.sh
(1)-help:輸出這個命令參數(shù)
[hadoop@hadoop101 hadoop-2.7.2]$ hadoop fs -help rm
(2)-ls: 顯示目錄信息
[hadoop@hadoop101 hadoop-2.7.2]$ hadoop fs -ls /
(3)-mkdir:在HDFS上創(chuàng)建目錄
[hadoop@hadoop101 hadoop-2.7.2]$ hadoop fs -mkdir -p /user/hadoop/test
(4)-moveFromLocal:從本地剪切粘貼到HDFS
[hadoop@hadoop101 hadoop-2.7.2]$ touch test.txt
[hadoop@hadoop101 hadoop-2.7.2]$ hadoop fs -moveFromLocal ./test.txt /user/hadoop/test
(5)-appendToFile:追加一個文件到已經(jīng)存在的文件末尾
[hadoop@hadoop101 hadoop-2.7.2]$ touch test1.txt
[hadoop@hadoop101 hadoop-2.7.2]$ vi test1.txt
輸入
test file
hello world
[hadoop@hadoop101 hadoop-2.7.2]$ hadoop fs -appendToFile test1.txt /user/hadoop/test/test.txt
(6)-cat:顯示文件內(nèi)容
[hadoop@hadoop101 hadoop-2.7.2]$ hadoop fs -cat /user/hadoop/test/test.txt
(7)-chgrp 、-chmod辩昆、-chown:Linux文件系統(tǒng)中的用法一樣阅酪,修改文件所屬權(quán)限
[hadoop@hadoop101 hadoop-2.7.2]$ hadoop fs -chmod 666 /user/hadoop/test/test.txt
[hadoop@hadoop101 hadoop-2.7.2]$ hadoop fs -chown hadoop:hadoop /user/hadoop/test/test.txt
(8)-copyFromLocal:從本地文件系統(tǒng)中拷貝文件到HDFS路徑去
[hadoop@hadoop101 hadoop-2.7.2]$ hadoop fs -copyFromLocal README.txt /
(9)-copyToLocal:從HDFS拷貝到本地
[hadoop@hadoop101 hadoop-2.7.2]$ hadoop fs -copyToLocal /user/hadoop/test.txt ./
(10)-cp :從HDFS的一個路徑拷貝到HDFS的另一個路徑
[hadoop@hadoop101 hadoop-2.7.2]$ hadoop fs -cp /user/hadoop/test/test.txt /test3.txt
(11)-mv:在HDFS目錄中移動文件
[hadoop@hadoop101 hadoop-2.7.2]$ hadoop fs -mv /test3.txt /user/hadoop/test
(12)-get:等同于copyToLocal,就是從HDFS下載文件到本地
[hadoop@hadoop101 hadoop-2.7.2]$ hadoop fs -get /user/hadoop/test/test.txt ./
(13)-getmerge:合并下載多個文件汁针,比如HDFS的目錄 /user/hadoop/test下有多個文件:log.1, log.2,log.3,...
[hadoop@hadoop101 hadoop-2.7.2]$ hadoop fs -getmerge /user/hadoop/test/* ./test4.txt
(14)-put:等同于copyFromLocal
[hadoop@hadoop101 hadoop-2.7.2]$ hadoop fs -put ./test4.txt /user/hadoop/test/
(15)-tail:顯示一個文件的末尾
[hadoop@hadoop101 hadoop-2.7.2]$ hadoop fs -tail /user/hadoop/test/test.txt
(16)-rm:刪除文件或文件夾
[hadoop@hadoop101 hadoop-2.7.2]$ hadoop fs -rm /user/hadoop/test/test3.txt
(17)-rmdir:刪除空目錄
[hadoop@hadoop101 hadoop-2.7.2]$ hadoop fs -mkdir /test
[hadoop@hadoop101 hadoop-2.7.2]$ hadoop fs -rmdir /test
(18)-du統(tǒng)計文件夾的大小信息
[hadoop@hadoop101 hadoop-2.7.2]$ hadoop fs -du -s -h /user/hadoop/test
2.7 K /user/hadoop/test
[hadoop@hadoop101 hadoop-2.7.2]$ hadoop fs -du -h /user/hadoop/test
1.3 K /user/hadoop/test/README.txt
15 /user/hadoop/test/test1.txt
1.4 K /user/hadoop/test/test3.txt
(19)-setrep:設(shè)置HDFS中文件的副本數(shù)量
[hadoop@hadoop101 hadoop-2.7.2]$ hadoop fs -setrep 10 /user/hadoopkongming.txt
這里設(shè)置的副本數(shù)只是記錄在NameNode的元數(shù)據(jù)中术辐,是否真的會有這么多副本,還得看DataNode的數(shù)量施无。因為目前只有3臺設(shè)備辉词,最多也就3個副本,只有節(jié)點數(shù)的增加到10臺時猾骡,副本數(shù)才能達(dá)到10瑞躺。
第3章 HDFS客戶端操作
3.1 HDFS客戶端環(huán)境準(zhǔn)備
1 根據(jù)自己電腦的操作系統(tǒng)拷貝對應(yīng)的編譯后的hadoop jar包到非中文路徑(例如:H:\hadoop-2.7.2)
2 配置HADOOP_HOME環(huán)境變量
3 配置Path環(huán)境變量
4 創(chuàng)建一個Maven工程hdfs
5 導(dǎo)入相應(yīng)的依賴坐標(biāo)+日志添加
<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>
</dependencies>
6 在項目的src/main/resources目錄下,新建一個文件兴想,命名為“l(fā)og4j.properties”幢哨,在文件中填入
log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=target/spring.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n
7 創(chuàng)建包名:com.jackyan.hadoop.hdfs
8 創(chuàng)建HdfsClient類
public class HdfsClient{
@Test
public void testMkdirs() throws IOException, InterruptedException, URISyntaxException{
// 1 獲取文件系統(tǒng)
Configuration configuration = new Configuration();
// 配置在集群上運行
// configuration.set("fs.defaultFS", "hdfs://hadoop101:9000");
// FileSystem fs = FileSystem.get(configuration);
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop101:9000"), configuration, "hadoop");
// 2 創(chuàng)建目錄
fs.mkdirs(new Path("/1108/daxian/banzhang"));
// 3 關(guān)閉資源
fs.close();
}
}
9 執(zhí)行程序
3.2 HDFS的API操作
3.2.1 HDFS文件上傳
1 在電腦上編寫測試文件H:\hadoop-2.7.2\test.txt,內(nèi)容如下:
hello hadoop
hello hdfs
hello world
2 編寫源代碼
@Test
public void testCopyFromLocalFile() throws IOException, InterruptedException, URISyntaxException {
// 1 獲取文件系統(tǒng)
Configuration configuration = new Configuration();
configuration.set("dfs.replication", "2");
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop101:9000"), configuration, "hadoop");
// 2 上傳文件
fs.copyFromLocalFile(new Path("H:\\hadoop-2.7.2\\test.txt"), new Path("/test.txt"));
// 3 關(guān)閉資源
fs.close();
System.out.println("over");
}
3 將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>
4 參數(shù)優(yōu)先級
參數(shù)優(yōu)先級排序:(1)客戶端代碼中設(shè)置的值 >(2)ClassPath下的用戶自定義配置文件 >(3)然后是服務(wù)器的默認(rèn)配置
3.2.2 HDFS文件下載
@Test
public void testCopyToLocalFile() throws IOException, InterruptedException, URISyntaxException{
// 1 獲取文件系統(tǒng)
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop101:9000"), configuration, "hadoop");
// 2 執(zhí)行下載操作
// boolean delSrc 指是否將原文件刪除
// Path src 指要下載的文件路徑
// Path dst 指將文件下載到的路徑
// boolean useRawLocalFileSystem 是否開啟文件校驗
fs.copyToLocalFile(false, new Path("/test.txt"), new Path("h:/test.txt"), true);
// 3 關(guān)閉資源
fs.close();
}
3.2.3 HDFS文件夾刪除
@Test
public void testDelete() throws IOException, InterruptedException, URISyntaxException{
// 1 獲取文件系統(tǒng)
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop101:9000"), configuration, "hadoop");
// 2 執(zhí)行刪除
fs.delete(new Path("/user/"), true);
// 3 關(guān)閉資源
fs.close();
}
3.2.4 HDFS文件名更改
@Test
public void testRename() throws IOException, InterruptedException, URISyntaxException{
// 1 獲取文件系統(tǒng)
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop101:9000"), configuration, "hadoop");
// 2 修改文件名稱
fs.rename(new Path("/test.txt"), new Path("/test1.txt"));
// 3 關(guān)閉資源
fs.close();
}
3.2.5 HDFS文件詳情查看
查看文件名稱嫂便、權(quán)限嘱么、長度、塊信息
@Test
public void testListFiles() throws IOException, InterruptedException, URISyntaxException{
// 1獲取文件系統(tǒng)
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop101: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();
}
3.2.6 HDFS文件和文件夾判斷
@Test
public void testListStatus() throws IOException, InterruptedException, URISyntaxException{
// 1 獲取文件配置信息
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop101:9000"), configuration, "hadoop");
// 2 判斷是文件還是文件夾
FileStatus[] listStatus = fs.listStatus(new Path("/"));
for (FileStatus fileStatus : listStatus) {
// 如果是文件
if (fileStatus.isFile()) {
System.out.println("f:"+fileStatus.getPath().getName());
}else {
System.out.println("d:"+fileStatus.getPath().getName());
}
}
// 3 關(guān)閉資源
fs.close();
}
3.3 HDFS的I/O流操作
以上API操作HDFS系統(tǒng)都是框架封裝好的,還可以采用IO流的方式實現(xiàn)數(shù)據(jù)的上傳和下載曼振。
3.3.1 HDFS文件上傳
1.需求:把本地h盤上的test.txt文件上傳到HDFS根目錄
2.編寫代碼
@Test
public void putFileToHDFS() throws IOException, InterruptedException, URISyntaxException {
// 1 獲取文件系統(tǒng)
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop101:9000"), configuration, "hadoop");
// 2 創(chuàng)建輸入流
FileInputStream fis = new FileInputStream(new File("h:/test.txt"));
// 3 獲取輸出流
FSDataOutputStream fos = fs.create(new Path("/test.txt"));
// 4 流對拷
IOUtils.copyBytes(fis, fos, configuration);
// 5 關(guān)閉資源
IOUtils.closeStream(fos);
IOUtils.closeStream(fis);
fs.close();
}
3.3.2 HDFS文件下載
1.需求:從HDFS上下載test.txt文件到本地h盤上
2.編寫代碼
// 文件下載
@Test
public void getFileFromHDFS() throws IOException, InterruptedException, URISyntaxException{
// 1 獲取文件系統(tǒng)
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop101:9000"), configuration, "hadoop");
// 2 獲取輸入流
FSDataInputStream fis = fs.open(new Path("/test.txt"));
// 3 獲取輸出流
FileOutputStream fos = new FileOutputStream(new File("h:/test1.txt"));
// 4 流的對拷
IOUtils.copyBytes(fis, fos, configuration);
// 5 關(guān)閉資源
IOUtils.closeStream(fos);
IOUtils.closeStream(fis);
fs.close();
}
3.3.3 定位文件讀取
1.需求:分塊讀取HDFS上的大文件几迄,比如根目錄下的/hadoop-2.7.2.tar.gz
2.編寫代碼
(1)下載第一塊
@Test
public void readFileSeek1() throws IOException, InterruptedException, URISyntaxException{
// 1 獲取文件系統(tǒng)
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop101:9000"), configuration, "hadoop");
// 2 獲取輸入流
FSDataInputStream fis = fs.open(new Path("/hadoop-2.7.2.tar.gz"));
// 3 創(chuàng)建輸出流
FileOutputStream fos = new FileOutputStream(new File("h:/hadoop-2.7.2.tar.gz.part1"));
// 4 流的拷貝
byte[] buf = new byte[1024];
for(int i =0 ; i < 1024 * 128; i++){
fis.read(buf);
fos.write(buf);
}
// 5關(guān)閉資源
IOUtils.closeStream(fis);
IOUtils.closeStream(fos);
fs.close();
}
(2)下載第二塊
@Test
public void readFileSeek2() throws IOException, InterruptedException, URISyntaxException{
// 1 獲取文件系統(tǒng)
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop101:9000"), configuration, "hadoop");
// 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命令窗口中進(jìn)入到目錄H:\,然后執(zhí)行如下命令冰评,對數(shù)據(jù)進(jìn)行合并
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包非常完整甲雅。
第4章 HDFS的數(shù)據(jù)流
4.1 HDFS寫數(shù)據(jù)流程
1)客戶端通過Distributed FileSystem模塊向NameNode請求上傳文件解孙,NameNode檢查目標(biāo)文件是否已存在,父目錄是否存在抛人。
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)當(dāng)一個Block傳輸完成之后焦蘑,客戶端再次請求NameNode上傳第二個Block的服務(wù)器。(重復(fù)執(zhí)行3-7步)盒发。
4.1.1 網(wǎng)絡(luò)拓?fù)?節(jié)點距離計算
在HDFS寫數(shù)據(jù)的過程中例嘱,NameNode會選擇距離待上傳數(shù)據(jù)最近距離的DataNode接收數(shù)據(jù)。那么這個最近距離怎么計算呢?
節(jié)點距離:兩個節(jié)點到達(dá)最近的共同祖先的距離總和。
例如撵幽,假設(shè)有數(shù)據(jù)中心d1機架r1中的節(jié)點n1郑什。該節(jié)點可以表示為/d1/r1/n1棚点。利用這種標(biāo)記,給出四種距離描述
4.1.2 機架感知(副本存儲節(jié)點選擇)
For the common case, when the replication factor is three, HDFS’s placement policy is to put one replica on one node in the local rack, another on a different node in the local rack, and the last on a different node in a different rack.
4.2 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為單位接收墩蔓,先在本地緩存梢莽,然后寫入目標(biāo)文件。
第5章 NameNode和SecondaryNameNode
5.1 NN和2NN工作機制
思考:NameNode中的元數(shù)據(jù)是存儲在哪里的奸披?
首先昏名,我們做個假設(shè),如果存儲在NameNode節(jié)點的磁盤中阵面,因為經(jīng)常需要進(jìn)行隨機訪問轻局,還有響應(yīng)客戶請求,必然是效率過低膜钓。因此嗽交,元數(shù)據(jù)需要存放在內(nèi)存中卿嘲。但如果只存在內(nèi)存中颂斜,一旦斷電,元數(shù)據(jù)丟失拾枣,整個集群就無法工作了沃疮。因此產(chǎn)生在磁盤中備份元數(shù)據(jù)的FsImage。
這樣又會帶來新的問題梅肤,當(dāng)在內(nèi)存中的元數(shù)據(jù)更新時司蔬,如果同時更新FsImage,就會導(dǎo)致效率過低姨蝴,但如果不更新俊啼,就會發(fā)生一致性問題,一旦NameNode節(jié)點斷電左医,就會產(chǎn)生數(shù)據(jù)丟失授帕。因此,引入Edits文件(只進(jìn)行追加操作浮梢,效率很高)跛十。每當(dāng)元數(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ù)需要的時間過長唁盏。因此内狸,需要定期進(jìn)行FsImage和Edits的合并,如果這個操作由NameNode節(jié)點完成厘擂,又會效率過低昆淡。因此,引入一個新的節(jié)點SecondaryNamenode刽严,專門用于FsImage和Edits的合并昂灵。
NN和2NN工作機制如下:
1 第一階段:NameNode啟動
(1)第一次啟動NameNode格式化后,創(chuàng)建Fsimage和Edits文件舞萄。如果不是第一次啟動眨补,直接加載編輯日志和鏡像文件到內(nèi)存。
(2)客戶端對元數(shù)據(jù)進(jìn)行增刪改的請求倒脓。
(3)NameNode記錄操作日志撑螺,更新滾動日志。
(4)NameNode在內(nèi)存中對元數(shù)據(jù)進(jìn)行增刪改崎弃。
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進(jìn)行合并(所謂合并,就是將Edits和Fsimage加載到內(nèi)存中渠啊,照著Edits中的操作一步步執(zhí)行输吏,最終形成新的Fsimage)。SecondaryNameNode的作用就是幫助NameNode進(jìn)行Edits和Fsimage的合并工作替蛉。
SecondaryNameNode首先會詢問NameNode是否需要CheckPoint(觸發(fā)CheckPoint需要滿足兩個條件中的任意一個贯溅,定時時間到和Edits中數(shù)據(jù)寫滿了)。直接帶回NameNode是否檢查結(jié)果躲查。SecondaryNameNode執(zhí)行CheckPoint操作它浅,首先會讓NameNode滾動Edits并生成一個空的edits.inprogress,滾動Edits的目的是給Edits打個標(biāo)記镣煮,以后所有新的操作都寫入edits.inprogress姐霍,其他未合并的Edits和Fsimage會拷貝到SecondaryNameNode的本地,然后將拷貝的Edits和Fsimage加載到內(nèi)存中進(jìn)行合并怎静,生成fsimage.chkpoint邮弹,然后將fsimage.chkpoint拷貝給NameNode黔衡,重命名為Fsimage后替換掉原來的Fsimage蚓聘。NameNode在啟動時就只需要加載之前未合并的Edits和Fsimage即可,因為合并過的Edits中的元數(shù)據(jù)信息已經(jīng)被記錄在Fsimage中盟劫。
5.2 Fsimage和Edits解析
1 概念
NameNode被格式化之后夜牡,將在/opt/modules/hadoop-2.7.2/datas/tmp/dfs/name/current目錄中產(chǎn)生如下文件
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文件進(jìn)行了合并勺阐。
2 oiv查看Fsimage文件
(1)查看oiv和oev命令
[hadoop@hadoop101 current]$ hdfs
oiv apply the offline fsimage viewer to an fsimage
oev apply the offline edits viewer to an edits file
(2)基本語法
hdfs oiv -p 文件類型 -i鏡像文件 -o 轉(zhuǎn)換后文件輸出路徑
(3)案例實操
[hadoop@hadoop101 current]$ pwd
/opt/modules/hadoop-2.7.2/data/tmp/dfs/name/current
[hadoop@hadoop101 current]$ hdfs oiv -p XML -i fsimage_0000000000000000025 -o /opt/modules/hadoop-2.7.2/fsimage.xml
[hadoop@hadoop101 current]$ cat /opt/modules/hadoop-2.7.2/fsimage.xml
將顯示的xml文件內(nèi)容拷貝到Eclipse中創(chuàng)建的xml文件中,并格式化矛双。部分顯示結(jié)果如下渊抽。
<inode>
<id>16386</id>
<type>DIRECTORY</type>
<name>user</name>
<mtime>1512722284477</mtime>
<permission>hadoop:supergroup:rwxr-xr-x</permission>
<nsquota>-1</nsquota>
<dsquota>-1</dsquota>
</inode>
<inode>
<id>16387</id>
<type>DIRECTORY</type>
<name>hadoop</name>
<mtime>1512790549080</mtime>
<permission>hadoop:supergroup:rwxr-xr-x</permission>
<nsquota>-1</nsquota>
<dsquota>-1</dsquota>
</inode>
<inode>
<id>16389</id>
<type>FILE</type>
<name>wc.input</name>
<replication>3</replication>
<mtime>1512722322219</mtime>
<atime>1512722321610</atime>
<perferredBlockSize>134217728</perferredBlockSize>
<permission>hadoop:supergroup:rw-r--r--</permission>
<blocks>
<block>
<id>1073741825</id>
<genstamp>1001</genstamp>
<numBytes>59</numBytes>
</block>
</blocks>
</inode >
在集群啟動后,要求DataNode上報數(shù)據(jù)塊信息议忽,并間隔一段時間后再次上報
3 oev查看Edits文件
(1)基本語法
hdfs oev -p 文件類型 -i編輯日志 -o 轉(zhuǎn)換后文件輸出路徑
(2)案例實操
[hadoop@hadoop101 current]$ hdfs oev -p XML -i edits_0000000000000000012-0000000000000000013 -o /opt/modules/hadoop-2.7.2/edits.xml
[hadoop@hadoop101 current]$ cat /opt/modules/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.56.103</CLIENT_MACHINE>
<OVERWRITE>true</OVERWRITE>
<PERMISSION_STATUS>
<USERNAME>hadoop</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>hadoop</USERNAME>
<GROUPNAME>supergroup</GROUPNAME>
<MODE>420</MODE>
</PERMISSION_STATUS>
</DATA>
</RECORD>
</EDITS >
5.3 CheckPoint時間設(shè)置
(1)通常情況下愤估,SecondaryNameNode每隔一小時執(zhí)行一次。
[hdfs-default.xml]
<property>
<name>dfs.namenode.checkpoint.period</name>
<value>3600</value>
</property>
(2)一分鐘檢查一次操作次數(shù)速址,當(dāng)操作次數(shù)達(dá)到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 >
5.4 NameNode故障處理
NameNode故障后壳繁,可以采用如下兩種方法恢復(fù)數(shù)據(jù)震捣。
方法一:將SecondaryNameNode中數(shù)據(jù)拷貝到NameNode存儲數(shù)據(jù)的目錄;
1 kill -9 NameNode進(jìn)程
2 刪除NameNode存儲的數(shù)據(jù)(/opt/modules/hadoop-2.7.2/data/tmp/dfs/name)
[hadoop@hadoop101 hadoop-2.7.2]$ rm -rf /opt/modules/hadoop-2.7.2/data/tmp/dfs/name/*
3 拷貝SecondaryNameNode中數(shù)據(jù)到原NameNode存儲數(shù)據(jù)目錄
[hadoop@hadoop101 dfs]$ scp -r hadoop@hadoop103:/opt/modules/hadoop-2.7.2/data/tmp/dfs/namesecondary/* ./name/
4 重新啟動NameNode
[hadoop@hadoop101 hadoop-2.7.2]$ sbin/hadoop-daemon.sh start namenode
方法二:使用-importCheckpoint選項啟動NameNode守護(hù)進(jìn)程闹炉,從而將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/modules/hadoop-2.7.2/data/tmp/dfs/name</value>
</property>
2 kill -9 NameNode進(jìn)程
3 刪除NameNode存儲的數(shù)據(jù)(/opt/modules/hadoop-2.7.2/data/tmp/dfs/name)
[hadoop@hadoop101 hadoop-2.7.2]$ rm -rf /opt/modules/hadoop-2.7.2/data/tmp/dfs/name/*
4 如果SecondaryNameNode不和NameNode在一個主機節(jié)點上,需要將SecondaryNameNode存儲數(shù)據(jù)的目錄拷貝到NameNode存儲數(shù)據(jù)的平級目錄渣触,并刪除in_use.lock文件
[hadoop@hadoop101 dfs]$ scp -r hadoop@hadoop103:/opt/modules/hadoop-2.7.2/data/tmp/dfs/namesecondary ./
[hadoop@hadoop101 namesecondary]$ rm -rf in_use.lock
[hadoop@hadoop101 dfs]$ pwd
/opt/modules/hadoop-2.7.2/data/tmp/dfs
[hadoop@hadoop101 dfs]$ ls
data name namesecondary
5 導(dǎo)入檢查點數(shù)據(jù)(等待一會ctrl+c結(jié)束掉)
[hadoop@hadoop101 hadoop-2.7.2]$ bin/hdfs namenode -importCheckpoint
6 啟動NameNode
[hadoop@hadoop101 hadoop-2.7.2]$ sbin/hadoop-daemon.sh start namenode
5.5 集群安全模式
1 概述
(1)NameNode啟動
NameNode啟動時羡棵,首先將鏡像文件(Fsimage)載入內(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維護(hù)的,而是以塊列表的形式存儲在DataNode中碧注。在系統(tǒng)的正常操作期間嚣伐,NameNode會在內(nèi)存中保留所有塊位置的映射信息。在安全模式下萍丐,各個DataNode會向NameNode發(fā)送最新的塊列表信息轩端,NameNode了解到足夠多的塊位置信息之后,即可高效運行文件系統(tǒng)逝变。
(3)安全模式退出判斷
如果滿足“最小副本條件”基茵,NameNode會在30秒鐘之后就退出安全模式刻撒。所謂的最小副本條件指的是在整個文件系統(tǒng)中99.9%的塊滿足最小副本級別(默認(rèn)值:dfs.replication.min=1)。在啟動一個剛剛格式化的HDFS集群時耿导,因為系統(tǒng)中還沒有任何塊声怔,所以NameNode不會進(jìn)入安全模式。
2 基本語法
集群處于安全模式舱呻,不能執(zhí)行重要操作(寫操作)醋火。集群啟動完成后,自動退出安全模式箱吕。
(1)bin/hdfs dfsadmin -safemode get (功能描述:查看安全模式狀態(tài))
(2)bin/hdfs dfsadmin -safemode enter (功能描述:進(jìn)入安全模式狀態(tài))
(3)bin/hdfs dfsadmin -safemode leave (功能描述:離開安全模式狀態(tài))
(4)bin/hdfs dfsadmin -safemode wait (功能描述:等待安全模式狀態(tài))
3 測試
(1)查看當(dāng)前模式
[hadoop@hadoop101 ~]$ hdfs dfsadmin -safemode get
Safe mode is OFF
(2)先進(jìn)入安全模式
[hadoop@hadoop101 ~]$ hdfs dfsadmin -safemode enter
Safe mode is ON
(3)執(zhí)行創(chuàng)建目錄的命令
[hadoop@hadoop101 ~]$ hdfs dfs -mkdir /test1
mkdir: Cannot create directory /test1. Name node is in safe mode.
(4)關(guān)閉安全模式
[hadoop@hadoop101 ~]$ hdfs dfsadmin -safemode leave
Safe mode is OFF
第6章 DataNode
6.1 DataNode工作機制
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的心跳妈经,則認(rèn)為該節(jié)點不可用淮野。
4)集群運行中可以安全加入和退出一些機器捧书。
6.2 數(shù)據(jù)完整性
思考:如果電腦磁盤里面存儲的數(shù)據(jù)是控制高鐵信號燈的紅燈信號(1)和綠燈信號(0)吹泡,但是存儲該數(shù)據(jù)的磁盤壞了,一直顯示是綠燈经瓷,是否很危險爆哑?同理DataNode節(jié)點上的數(shù)據(jù)損壞了,卻沒有發(fā)現(xiàn)舆吮,是否也很危險揭朝,那么如何解決呢队贱?
如下是DataNode節(jié)點保證數(shù)據(jù)完整性的方法。
1)當(dāng)DataNode讀取Block的時候,它會計算CheckSum嘉抓。
2)如果計算后的CheckSum,與Block創(chuàng)建時值不一樣,說明Block已經(jīng)損壞渺尘。
3)Client讀取其他DataNode上的Block。
4)DataNode在其文件創(chuàng)建后周期驗證CheckSum。
6.3 掉線時限參數(shù)設(shè)置
1拟淮、DataNode進(jìn)程死亡或者網(wǎng)絡(luò)故障造成DataNode無法與NameNode通信
2沾谓、NameNode不會立即把該節(jié)點判定為死亡昏兆,要經(jīng)過一段時間隶债,這段時間暫稱作超時時長曲梗。
3仅颇、HDFS默認(rèn)的超時時長為10分鐘+30秒。
4、如果定義超時時間為TimeOut凌停,則超時時長的計算公式為:
TimeOut = 2 * dfs.namenode.heartbeat.recheck-interval + 10 * dfs.heartbeat.interval。
而默認(rèn)的dfs.namenode.heartbeat.recheck-interval 大小為5分鐘,dfs.heartbeat.interval默認(rèn)為3秒阻逮。
需要注意的是hdfs-site.xml 配置文件中的heartbeat.recheck.interval的單位為毫秒,dfs.heartbeat.interval的單位為秒。
<property>
<name>dfs.namenode.heartbeat.recheck-interval</name>
<value>300000</value>
</property>
<property>
<name>dfs.heartbeat.interval</name>
<value>3</value>
</property>
6.4 服役新數(shù)據(jù)節(jié)點
隨著公司業(yè)務(wù)的增長食呻,數(shù)據(jù)量越來越大,原有的數(shù)據(jù)節(jié)點的容量已經(jīng)不能滿足存儲數(shù)據(jù)的需求剑辫,需要在原有集群基礎(chǔ)上動態(tài)添加新的數(shù)據(jù)節(jié)點椎眯。
1 環(huán)境準(zhǔn)備
(1)準(zhǔn)備一臺hadoop104主機
(2)配置JAVA環(huán)境(安裝jdk及配置環(huán)境變量)
(3)將hadoop101上的/opt/modules/hadoop-2.7.2拷貝到hadoop104上
(4)刪除原來HDFS文件系統(tǒng)留存的文件(/opt/modules/hadoop-2.7.2/datas和logs)
rm -rf /opt/modules/hadoop-2.7.2/datas/*
rm -rf /opt/modules/hadoop-2.7.2/logs/*
2 服役新節(jié)點具體步驟
(1)直接啟動DataNode,即可關(guān)聯(lián)到集群
[hadoop@hadoop104 hadoop-2.7.2]$ sbin/hadoop-daemon.sh start datanode
[hadoop@hadoop104 hadoop-2.7.2]$ sbin/yarn-daemon.sh start nodemanager
(2)在hadoop104上上傳文件
[hadoop@hadoop hadoop-2.7.2]$ hdfs dfs -put LICENSE.txt /
(3)如果數(shù)據(jù)不均衡,可以用命令實現(xiàn)集群的再平衡
[hadoop@hadoop sbin]$ start-balancer.sh
starting balancer, logging to /opt/modules/hadoop-2.7.2/logs/hadoop-hadoop-balancer-hadoop.out
Time Stamp Iteration# Bytes Already Moved Bytes Left To Move Bytes Being Moved
6.5 退役舊數(shù)據(jù)節(jié)點
6.5.1 添加白名單
添加到白名單的主機節(jié)點,都允許訪問NameNode粘勒,不在白名單的主機節(jié)點,都會被退出埃撵。
配置白名單的具體步驟如下:
(1)在NameNode的/opt/modules/hadoop-2.7.2/etc/hadoop目錄下創(chuàng)建dfs.hosts文件
[hadoop@hadoop101 hadoop]$ pwd
/opt/modules/hadoop-2.7.2/etc/hadoop
[hadoop@hadoop101 hadoop]$ touch dfs.hosts
[hadoop@hadoop101 hadoop]$ vi dfs.hosts
添加如下主機名稱(不添加hadoop104)
hadoop101
hadoop102
hadoop103
(2)在NameNode的hdfs-site.xml配置文件中增加dfs.hosts屬性
<property>
<name>dfs.hosts</name>
<value>/opt/modules/hadoop-2.7.2/etc/hadoop/dfs.hosts</value>
</property>
(3)配置文件分發(fā)
[hadoop@hadoop101 hadoop]$ xsync hdfs-site.xml
(4)刷新NameNode
[hadoop@hadoop101 hadoop-2.7.2]$ hdfs dfsadmin -refreshNodes
Refresh nodes successful
(5)更新ResourceManager節(jié)點
[hadoop@hadoop101 hadoop-2.7.2]$ yarn rmadmin -refreshNodes
6.5.2 黑名單退役
在黑名單上面的主機都會被強制退出谣拣。
1 在NameNode的/opt/modules/hadoop-2.7.2/etc/hadoop目錄下創(chuàng)建dfs.hosts.exclude文件
[hadoop@hadoop101 hadoop]$ pwd
/opt/modules/hadoop-2.7.2/etc/hadoop
[hadoop@hadoop101 hadoop]$ touch dfs.hosts.exclude
[hadoop@hadoop101 hadoop]$ vi dfs.hosts.exclude
添加如下主機名稱(要退役的節(jié)點)
hadoop104
2 在NameNode的hdfs-site.xml配置文件中增加dfs.hosts.exclude屬性
<property>
<name>dfs.hosts.exclude</name>
<value>/opt/modules/hadoop-2.7.2/etc/hadoop/dfs.hosts.exclude</value>
</property>
3 刷新NameNode、刷新ResourceManager
[hadoop@hadoop101 hadoop-2.7.2]$ hdfs dfsadmin -refreshNodes
[hadoop@hadoop101 hadoop-2.7.2]$ yarn rmadmin -refreshNodes
4 檢查Web瀏覽器,退役節(jié)點的狀態(tài)為decommission in progress(退役中)宾茂,說明數(shù)據(jù)節(jié)點正在復(fù)制塊到其他節(jié)點
5 等待退役節(jié)點狀態(tài)為decommissioned(所有塊已經(jīng)復(fù)制完成),停止該節(jié)點及節(jié)點資源管理器怀骤。
注意:如果副本數(shù)是3,服役的節(jié)點小于等于3,是不能退役成功的爷抓,需要修改副本數(shù)后才能退役
[hadoop@hadoop104 hadoop-2.7.2]$ sbin/hadoop-daemon.sh stop datanode
[hadoop@hadoop104 hadoop-2.7.2]$ sbin/yarn-daemon.sh stop nodemanager
6 如果數(shù)據(jù)不均衡陈莽,可以用命令實現(xiàn)集群的再平衡
[hadoop@hadoop101 hadoop-2.7.2]$ sbin/start-balancer.sh
starting balancer, logging to /opt/modules/hadoop-2.7.2/logs/hadoop-hadoop-balancer-hadoop101.out
Time Stamp Iteration# Bytes Already Moved Bytes Left To Move Bytes Being Moved
注意:不允許白名單和黑名單中同時出現(xiàn)同一個主機名稱独柑。
6.6 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>
第7章 HDFS 2.X新特性
7.1 集群間數(shù)據(jù)拷貝
1 scp實現(xiàn)兩個遠(yuǎn)程主機之間的文件復(fù)制
scp -r hello.txt root@hadoop101:/user/hadoop/hello.txt // 推 push
scp -r root@hadoop101:/user/hadoop/hello.txt hello.txt // 拉 pull
//是通過本地主機中轉(zhuǎn)實現(xiàn)兩個遠(yuǎn)程主機的文件復(fù)制唤反;如果在兩個遠(yuǎn)程主機之間ssh沒有配置的情況下可以使用該方式肠缨。
scp -r root@hadoop101:/user/hadoop/hello.txt root@hadoop102:/user/hadoop
2 采用distcp命令實現(xiàn)兩個Hadoop集群之間的遞歸數(shù)據(jù)復(fù)制
[hadoop@hadoop101 hadoop-2.7.2]$ bin/hadoop distcp
hdfs://haoop102:9000/user/hadoop/hello.txt hdfs://hadoop102:9000/user/hadoop/hello.txt
7.2 小文件存檔
1 HDFS存儲小文件弊端
每個文件均按塊存儲般哼,每個塊的元數(shù)據(jù)存儲在NameNode的內(nèi)存中,因此HDFS存儲小文件會非常低效。因為大量的小文件會耗盡NameNode中的大部分內(nèi)存蒋腮。但注意激况,存儲小文件所需要的磁盤容量和數(shù)據(jù)塊的大小無關(guān)竭讳。例如洛波,一個1MB的文件設(shè)置為128MB的塊存儲思瘟,實際使用的是1MB的磁盤空間,而不是128MB。
2 解決存儲小文件辦法之一
HDFS存檔文件或HAR文件,是一個更高效的文件存檔工具愕鼓,它將文件存入HDFS塊磺送,在減少NameNode內(nèi)存使用的同時,允許對文件進(jìn)行透明的訪問。具體說來,HDFS存檔文件對內(nèi)還是一個一個獨立文件大溜,對NameNode而言卻是一個整體,減少了NameNode的內(nèi)存估脆。
3.案例實操
(1)需要啟動YARN進(jìn)程
[hadoop@hadoop101 hadoop-2.7.2]$ start-yarn.sh
(2)歸檔文件
把/user/hadoop/input目錄里面的所有文件歸檔成一個叫input.har的歸檔文件钦奋,并把歸檔后文件存儲到/user/hadoop/output路徑下。
[hadoop@hadoop101 hadoop-2.7.2]$ bin/hadoop archive -archiveName input.har –p /user/hadoop/input /user/hadoop/output
(3)查看歸檔
[hadoop@hadoop101 hadoop-2.7.2]$ hadoop fs -lsr /user/hadoop/output/input.har
[hadoop@hadoop101 hadoop-2.7.2]$ hadoop fs -lsr har:///user/hadoop/output/input.har
(4)解歸檔文件
[hadoop@hadoop101 hadoop-2.7.2]$ hadoop fs -cp har:/// user/hadoop/output/input.har/* /user/hadoop
第8章 HDFS HA高可用
8.1 HA概述
1)所謂HA(High Available)疙赠,即高可用(7*24小時不中斷服務(wù))付材。
2)實現(xiàn)高可用最關(guān)鍵的策略是消除單點故障。HA嚴(yán)格來說應(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)故障番捂,如機器崩潰或機器需要升級維護(hù)灭翔,這時可通過此種方式將NameNode很快的切換到另外一臺機器。
8.2 HDFS-HA工作機制
通過雙NameNode消除單點故障
8.2.1 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負(fù)責(zé)監(jiān)控自己所在NameNode節(jié)點,利用zk進(jìn)行狀態(tài)標(biāo)識辽故,當(dāng)需要進(jìn)行狀態(tài)切換時秒咐,由zkfailover來負(fù)責(zé)切換,切換時需要防止brain split現(xiàn)象的發(fā)生碘裕。
3 必須保證兩個NameNode之間能夠ssh無密碼登錄
4 隔離(Fence)携取,即同一時刻僅僅有一個NameNode對外提供服務(wù)
8.2.2 HDFS-HA自動故障轉(zhuǎn)移工作機制
手動故障轉(zhuǎn)移:
使用命令hdfs haadmin -failover手動進(jìn)行故障轉(zhuǎn)移,在該模式下帮孔,即使現(xiàn)役NameNode已經(jīng)失效雷滋,系統(tǒng)也不會自動從現(xiàn)役NameNode轉(zhuǎn)移到待機NameNode。
自動故障轉(zhuǎn)移:
自動故障轉(zhuǎn)移為HDFS部署增加了兩個新組件:ZooKeeper和ZKFailoverController(ZKFC)進(jìn)程文兢,ZooKeeper是維護(hù)少量協(xié)調(diào)數(shù)據(jù)晤斩,通知客戶端這些數(shù)據(jù)的改變和監(jiān)視客戶端故障的高可用服務(wù)。
HA的自動故障轉(zhuǎn)移依賴于ZooKeeper的以下功能:
1)故障檢測:集群中的每個NameNode在ZooKeeper中維護(hù)了一個持久會話姆坚,如果機器崩潰澳泵,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進(jìn)程介时,ZKFC負(fù)責(zé):
1)健康監(jiān)測:ZKFC使用一個健康檢查命令定期地ping與之在相同主機的NameNode,只要該NameNode及時地回復(fù)健康狀態(tài),ZKFC認(rèn)為該節(jié)點是健康的沸柔。如果該節(jié)點崩潰循衰,凍結(jié)或進(jìn)入不健康狀態(tài),健康監(jiān)測器標(biāo)識該節(jié)點為非健康的勉失。
2)ZooKeeper會話管理:當(dāng)本地NameNode是健康的羹蚣,ZKFC保持一個在ZooKeeper中打開的會話。如果本地NameNode處于active狀態(tài)乱凿,ZKFC也保持一個特殊的znode鎖顽素,該鎖使用了ZooKeeper對短暫節(jié)點的支持,如果會話終止徒蟆,鎖節(jié)點將自動刪除胁出。
3)基于ZooKeeper的選擇:如果本地NameNode是健康的,且ZKFC發(fā)現(xiàn)沒有其它的節(jié)點當(dāng)前持有znode鎖段审,它將為自己獲取該鎖全蝶。如果成功,則它已經(jīng)贏得了選擇寺枉,并負(fù)責(zé)運行故障轉(zhuǎn)移進(jìn)程以使它的本地NameNode為Active抑淫。故障轉(zhuǎn)移進(jìn)程與前面描述的手動故障轉(zhuǎn)移相似,首先如果必要保護(hù)之前的現(xiàn)役NameNode姥闪,然后本地NameNode轉(zhuǎn)換為Active狀態(tài)始苇。
8.3 HDFS-HA集群配置
8.3.1 集群規(guī)劃
hadoop101 | hadoop102 | hadoop103 |
---|---|---|
NameNode | NameNode | |
JournalNode | JournalNode | JournalNode |
DataNode | DataNode | DataNode |
ZK | ZK | ZK |
ResourceManager | ||
NodeManager | NodeManager | NodeManager |
8.3.2 配置Zookeeper集群
集群規(guī)劃
在hadoop101、hadoop102和hadoop103三個節(jié)點上部署Zookeeper筐喳。
解壓安裝
(1)解壓Zookeeper安裝包到/opt/modules/目錄下
[hadoop@hadoop101 softwares]$ tar -zxvf zookeeper-3.4.10.tar.gz -C /opt/modules/
(2)在/opt/modules/zookeeper-3.4.10/這個目錄下創(chuàng)建zkData
mkdir -p zkData
(3)重命名/opt/modules/zookeeper-3.4.10/conf這個目錄下的zoo_sample.cfg為zoo.cfg
mv zoo_sample.cfg zoo.cfg
配置zoo.cfg文件
(1)具體配置
dataDir=/opt/modules/zookeeper-3.4.10/zkData
增加如下配置
#######################cluster##########################
server.1=hadoop101:2888:3888
server.2=hadoop102:2888:3888
server.3=hadoop103:2888:3888
(2)配置參數(shù)解讀
Server.A=B:C:D催式。
A是一個數(shù)字,表示這個是第幾號服務(wù)器避归;
B是這個服務(wù)器的IP地址荣月;
C是這個服務(wù)器與集群中的Leader服務(wù)器交換信息的端口;
D是萬一集群中的Leader服務(wù)器掛了梳毙,需要一個端口來重新進(jìn)行選舉哺窄,選出一個新的Leader,而這個端口就是用來執(zhí)行選舉時服務(wù)器相互通信的端口账锹。
集群模式下配置一個文件myid堂氯,這個文件在dataDir目錄下,這個文件里面有一個數(shù)據(jù)就是A的值牌废,Zookeeper啟動時讀取此文件,拿到里面的數(shù)據(jù)與zoo.cfg里面的配置信息比較從而判斷到底是哪個server啤握。
配置log4j.properties鸟缕,并創(chuàng)建logs目錄
zookeeper.log.dir=/opt/modules/zookeeper-3.4.10/logs
zookeeper.tracelog.dir=/opt/modules/zookeeper-3.4.10/logs
[hadoop@hadoop101 zookeeper-3.4.10]$ mkdir logs
集群操作
(1)在/opt/modules/zookeeper-3.4.10/zkData目錄下創(chuàng)建一個myid的文件
touch myid
(2)編輯myid文件
[hadoop@hadoop101 zkData]$ vim myid
1
(3)同步zookeeper到其他機器
[hadoop@hadoop101 modules]$ xsync zookeeper-3.4.10/
并分別修改myid文件中內(nèi)容為2、3
(4)分別啟動zookeeper
[root@hadoop101 zookeeper-3.4.10]# bin/zkServer.sh start
[root@hadoop102 zookeeper-3.4.10]# bin/zkServer.sh start
[root@hadoop103 zookeeper-3.4.10]# bin/zkServer.sh start
(5)查看狀態(tài)
[root@hadoop101 zookeeper-3.4.10]# bin/zkServer.sh status
JMX enabled by default
Using config: /opt/modules/zookeeper-3.4.10/bin/../conf/zoo.cfg
Mode: follower
[root@hadoop102 zookeeper-3.4.10]# bin/zkServer.sh status
JMX enabled by default
Using config: /opt/modules/zookeeper-3.4.10/bin/../conf/zoo.cfg
Mode: leader
[root@hadoop103 zookeeper-3.4.5]# bin/zkServer.sh status
JMX enabled by default
Using config: /opt/modules/zookeeper-3.4.10/bin/../conf/zoo.cfg
Mode: follower
8.3.3 配置HDFS-HA集群
官方地址:http://hadoop.apache.org/
在/opt/目錄下創(chuàng)建一個hadoop-ha文件夾
[hadoop@hadoop101 opt]$ mkdir hadoop-ha
將/opt/sofewares下的 hadoop-2.7.2.tar.gz拷貝到/opt/hadoop-ha目錄下
[hadoop@hadoop101 softwares]$ tar -xf hahadoop-2.7.2.tar.gz -C /opt/hadoop-ha/
分發(fā)到hadoop102, hadoop103
[hadoop@hadoop101 opt]$ xsync hadoop-ha/
配置hadoop-env.sh
export JAVA_HOME=/opt/modules/jdk1.8.0_144
配置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/hadoop-ha/hadoop-2.7.2/datas/tmp</value>
</property>
</configuration>
配置hdfs-site.xml
<configuration>
<!-- 完全分布式集群名稱 -->
<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>
<!-- 集群中NameNode節(jié)點都有哪些 -->
<property>
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value>
</property>
<!-- nn1的RPC通信地址 -->
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>hadoop101:9000</value>
</property>
<!-- nn2的RPC通信地址 -->
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>hadoop102:9000</value>
</property>
<!-- nn1的http通信地址 -->
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>hadoop101:50070</value>
</property>
<!-- nn2的http通信地址 -->
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>hadoop102:50070</value>
</property>
<!-- 指定NameNode元數(shù)據(jù)在JournalNode上的存放位置 -->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://hadoop101:8485;hadoop102:8485;hadoop103:8485/mycluster</value>
</property>
<!-- 配置隔離機制,即同一時刻只能有一臺服務(wù)器對外響應(yīng) -->
<property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
</property>
<!-- 使用隔離機制時需要ssh無秘鑰登錄-->
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/hadoop/.ssh/id_rsa</value>
</property>
<!-- 聲明journalnode服務(wù)器存儲目錄-->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/opt/hadoop-ha/hadoop-2.7.2/datas/jn</value>
</property>
<!-- 關(guān)閉權(quán)限檢查-->
<property>
<name>dfs.permissions.enable</name>
<value>false</value>
</property>
<!-- 訪問代理類:client懂从,mycluster授段,active配置失敗自動切換實現(xiàn)方式-->
<property>
<name>dfs.client.failover.proxy.provider.mycluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
</configuration>
配置slaves
hadoop101
hadoop102
hadoop103
拷貝配置好的hadoop環(huán)境到其他節(jié)點
8.3.4 啟動HDFS-HA集群
在各個JournalNode節(jié)點上,輸入以下命令啟動journalnode服務(wù)
sbin/hadoop-daemon.sh start journalnode
在[nn1]上番甩,對其進(jìn)行格式化侵贵,并啟動
bin/hdfs namenode -format
sbin/hadoop-daemon.sh start namenode
在[nn2]上,同步nn1的元數(shù)據(jù)信息
bin/hdfs namenode -bootstrapStandby
啟動[nn2]
sbin/hadoop-daemon.sh start namenode
在[nn1]上缘薛,啟動所有datanode
sbin/hadoop-daemons.sh start datanode
將[nn1]切換為Active
bin/hdfs haadmin -transitionToActive nn1
查看是否Active
bin/hdfs haadmin -getServiceState nn1
8.3.5 配置HDFS-HA自動故障轉(zhuǎn)移
具體配置
(1)在hdfs-site.xml中增加
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
(2)在core-site.xml文件中增加
<property>
<name>ha.zookeeper.quorum</name>
<value>hadoop101:2181,hadoop102:2181,hadoop103:2181</value>
</property>
(3)同步配置到其他機器
[hadoop@hadoop101 hadoop-2.7.2]$ xsync etc
啟動
(1)關(guān)閉所有HDFS服務(wù):
[hadoop@hadoop101 hadoop-2.7.2]$ sbin/stop-dfs.sh
(2)啟動Zookeeper集群:
bin/zkServer.sh start
(3)初始化HA在Zookeeper中狀態(tài):
bin/hdfs zkfc -formatZK
(4)啟動HDFS服務(wù):
sbin/start-dfs.sh
驗證
(1)將Active NameNode進(jìn)程kill
kill -9 namenode的進(jìn)程id
(2)將Active NameNode機器斷開網(wǎng)絡(luò)
service network stop
8.4 YARN-HA配置
8.4.1 YARN-HA工作機制
官方文檔:http://hadoop.apache.org/docs/r2.7.2/hadoop-yarn/hadoop-yarn-site/ResourceManagerHA.html
YARN-HA工作機制
8.4.2 配置YARN-HA集群
規(guī)劃集群
hadoop101 | hadoop102 | hadoop103 |
---|---|---|
NameNode | NameNode | |
JournalNode | JournalNode | JournalNode |
DataNode | DataNode | DataNode |
ZK | ZK | ZK |
ResourceManager | ResourceManager | |
NodeManager | NodeManager | NodeManager |
具體配置
(1)yarn-site.xml
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!--啟用resourcemanager ha-->
<property>
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>
<!--聲明兩臺resourcemanager的地址-->
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>cluster-yarn1</value>
</property>
<property>
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm1</name>
<value>hadoop101</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>hadoop102</value>
</property>
<!--指定zookeeper集群的地址-->
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>hadoop101:2181,hadoop102:2181,hadoop103:2181</value>
</property>
<!--啟用自動恢復(fù)-->
<property>
<name>yarn.resourcemanager.recovery.enabled</name>
<value>true</value>
</property>
<!--指定resourcemanager的狀態(tài)信息存儲在zookeeper集群-->
<property>
<name>yarn.resourcemanager.store.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
</property>
(2)配置mapred-env.sh,yarn-env.sh的JAVA_HOME
JAVA_HOME=/opt/modules/jdk1.8.0_144
(3)配置mapred-site.xml
<!-- 指定MR運行在Yarn上 -->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
(2)同步更新配置到其他節(jié)點的配置信息
[hadoop@hadoop101 hadoop-2.7.2]$ xsync etc
停止之前啟動的hdfs集群并刪除datas、logs目錄下的文件
[hadoop@hadoop101 hadoop-2.7.2]$ sbin/stop-dfs.sh
[hadoop@hadoop101 hadoop-2.7.2]$ rm -rf datas/* logs/*
[hadoop@hadoop102 hadoop-2.7.2]$ rm -rf datas/* logs/*
[hadoop@hadoop103 hadoop-2.7.2]$ rm -rf datas/* logs/*
啟動hdfs
sbin/start-dfs.sh
啟動YARN
(1)在hadoop101中執(zhí)行:
sbin/start-yarn.sh
(2)在hadoop102中執(zhí)行:
sbin/yarn-daemon.sh start resourcemanager
(3)查看服務(wù)狀態(tài)爬泥,如圖3-24所示
bin/yarn rmadmin -getServiceState rm1
8.5 HDFS Federation架構(gòu)設(shè)計
NameNode架構(gòu)的局限性
(1)Namespace(命名空間)的限制
由于NameNode在內(nèi)存中存儲所有的元數(shù)據(jù)(metadata)童番,因此單個NameNode所能存儲的對象(文件+塊)數(shù)目受到NameNode所在JVM的heap size的限制。50G的heap能夠存儲20億(200million)個對象恕齐,這20億個對象支持4000個DataNode乞娄,12PB的存儲(假設(shè)文件平均大小為40MB)。隨著數(shù)據(jù)的飛速增長显歧,存儲的需求也隨之增長仪或。單個DataNode從4T增長到36T,集群的尺寸增長到8000個DataNode士骤。存儲的需求從12PB增長到大于100PB范删。
(2)隔離問題
由于HDFS僅有一個NameNode,無法隔離各個程序敦间,因此HDFS上的一個實驗程序就很有可能影響整個HDFS上運行的程序瓶逃。
(3)性能的瓶頸
由于是單個NameNode的HDFS架構(gòu),因此整個HDFS文件系統(tǒng)的吞吐量受限于單個NameNode的吞吐量廓块。
HDFS Federation架構(gòu)設(shè)計
能不能有多個NameNode厢绝,例如:
NameNode | NameNode | NameNode |
---|---|---|
元數(shù)據(jù) | 元數(shù)據(jù) | 元數(shù)據(jù) |
Log | machine | 電商數(shù)據(jù)/話單數(shù)據(jù) |
HDFS Federation應(yīng)用
不同應(yīng)用可以使用不同NameNode進(jìn)行數(shù)據(jù)管理:圖片業(yè)務(wù)、爬蟲業(yè)務(wù)带猴、日志審計業(yè)務(wù)
Hadoop生態(tài)系統(tǒng)中昔汉,不同的框架使用不同的NameNode進(jìn)行管理NameSpace(隔離性)。