隨著互聯(lián)網(wǎng)的快速發(fā)展,互聯(lián)網(wǎng)公司每天產(chǎn)生的用戶數(shù)據(jù)呈現(xiàn)指數(shù)型增長,傳統(tǒng)的單機(jī)存儲(chǔ)方式面對海量數(shù)據(jù)顯得手足無措。全世界最大的搜索引擎公司Google,率先提出了分布式文件系統(tǒng)的概念,GFS(Google File System),其基本思想是:將多個(gè)廉價(jià)的單機(jī)存儲(chǔ)節(jié)點(diǎn)互聯(lián)成為一個(gè)儲(chǔ)存集群,并由一個(gè)中央節(jié)點(diǎn)來管理和維護(hù)。這個(gè)中央節(jié)點(diǎn)不僅可以管理數(shù)據(jù)節(jié)點(diǎn)的刪除和增加,還可以處理用戶的數(shù)據(jù)讀寫請求,理論上這種易擴(kuò)展的儲(chǔ)存集群的容量是無限大的。根據(jù)GFS(谷歌文件系統(tǒng))的思想,Hadoop實(shí)現(xiàn)了自己的分布式文件系統(tǒng)HDFS(Hadoop Distributed File System),并以此來構(gòu)建Hadoop生態(tài)系統(tǒng)的各種應(yīng)用。本節(jié)我們就來介紹一下HDFS的基本思想和工作原理,主要包括兩個(gè)方面的內(nèi)容:(1)數(shù)據(jù)的存儲(chǔ);(2)數(shù)據(jù)的訪問。
1.HDFS的工作原理

如圖所示,HDFS主要有三個(gè)組成部分:NameNode(名稱節(jié)點(diǎn))、SecondaryNameNode(第二名稱節(jié)點(diǎn))和DataNode(數(shù)據(jù)節(jié)點(diǎn))。
1.1 NameNode的作用
NameNode主要作用有三個(gè):
(1)維護(hù)全部DataNode信息:如果有DataNode死掉了,則將它從DataNode列表中移除;如果增加了新的DataNode,則記錄新的DataNode的信息,包括機(jī)架、hosts信息等。
(2)維護(hù)數(shù)據(jù)元信息fsimage和操作日志edits:數(shù)據(jù)元信息包括數(shù)據(jù)的名稱、塊數(shù)、存儲(chǔ)位置、冗余度、權(quán)限等等;操作日志包括對數(shù)據(jù)的增刪改查等等。
(3)處理用戶請求:用戶請求包括對數(shù)據(jù)的創(chuàng)建、修改、查詢、設(shè)置權(quán)限等等。
1.2 SecondaryNameNode的作用
SecondaryNameNode默認(rèn)是與NameNode位于同一節(jié)點(diǎn)上,但是對于某些情況,如NameNode節(jié)點(diǎn)壓力過大,則會(huì)將SecondaryNameNode單獨(dú)放到另一節(jié)點(diǎn)上。SecondaryNameNode的作用主要是定期合并由NameNode節(jié)點(diǎn)產(chǎn)生的數(shù)據(jù)元信息fsimage和操作日志edits。比如將前一天的數(shù)據(jù)元信息fsimage_old,加上當(dāng)天的操作日志edits_new,就等于現(xiàn)在的數(shù)據(jù)元信息fsimage_new,即fsimage = fsimage_old + edits_new。這樣做的目的是減少日志的存量,優(yōu)化HDFS的讀寫速度。
1.3 DataNode的作用
(1)維持心跳:DataNode會(huì)定期(如每隔3秒)向NameNode報(bào)告自己的狀態(tài),包括剩余存儲(chǔ)空間大小、是否由數(shù)據(jù)損壞等等。如果NameNode超過這個(gè)時(shí)間還收不到某個(gè)DataNode的心跳信息,就認(rèn)為該DataNode死掉了,會(huì)將其從列表中刪除。
(2)存儲(chǔ)數(shù)據(jù):DataNode是按照數(shù)據(jù)塊來分割存儲(chǔ)用戶原數(shù)據(jù)的。Hadoop 1.x 默認(rèn)的數(shù)據(jù)塊大小是64MB,Hadoop 2.x 默認(rèn)的數(shù)據(jù)塊大小是128MB,當(dāng)然也可以由用戶自行指定數(shù)據(jù)塊大小。
(3)自動(dòng)冗余:Hadoop集群默認(rèn)的冗余度為3,即一份用戶數(shù)據(jù),默認(rèn)在HDFS上保存3個(gè)副本,當(dāng)然冗余度可以根據(jù)情況自行設(shè)定。比如Hadoop的本地模式數(shù)據(jù)是存儲(chǔ)在本地文件系統(tǒng)的,沒有HDFS功能,也就沒有DataNode的概念;Hadoop的偽分布模式雖然使用了HDFS功能,但是由于只有一個(gè)節(jié)點(diǎn),所以需要將冗余度設(shè)置為1;Hadoop的全分布模式最少需要兩個(gè)DataNode節(jié)點(diǎn),因此這種情況下需要將冗余度設(shè)置為2;超過3個(gè)DataNode節(jié)點(diǎn)的,保持默認(rèn)的冗余度為3即可。這里的自動(dòng)冗余是指,用戶在上傳數(shù)據(jù)時(shí),只需要上傳至NameNode分配的其中一個(gè)DataName節(jié)點(diǎn)上,然后該DataNode會(huì)根據(jù)機(jī)架感知原理將數(shù)據(jù)水平復(fù)制到NameNode分配的另外兩個(gè)DataNode節(jié)點(diǎn)上,以達(dá)到冗余度為3的目的。另外,NameNode會(huì)定期檢查用戶數(shù)據(jù)是否滿足冗余度要求,當(dāng)有DataNode死掉時(shí),NameNode就會(huì)新分配一個(gè)可用的DataNode,然后從活著的DataNode將數(shù)據(jù)復(fù)制到這個(gè)新的DataNode上以達(dá)到冗余度要求。
2.機(jī)架感知原理介紹

機(jī)架感知是Hadoop存儲(chǔ)冗余數(shù)據(jù)的一種策略。對于大規(guī)模的Hadoop集群來說,DataNode節(jié)點(diǎn)的個(gè)數(shù)往往有很多。這些節(jié)點(diǎn)需要分機(jī)柜(rock)存放,如上圖所示。
第一步:用戶上傳一份數(shù)據(jù)到機(jī)柜rock1上的DataNode11節(jié)點(diǎn)上后就得到了數(shù)據(jù)的第一個(gè)副本;
第二步:會(huì)優(yōu)先在另一個(gè)機(jī)柜rockM上尋找一個(gè)可用的DataNodeM2節(jié)點(diǎn),進(jìn)行水平復(fù)制得到數(shù)據(jù)的第二個(gè)副本;
第三步:再回到機(jī)柜rock1上尋找另一個(gè)DataNode13節(jié)點(diǎn),進(jìn)行水平復(fù)制得到數(shù)據(jù)的第三個(gè)副本。
這樣做的目的是:
(1)如果水平復(fù)制過程中目標(biāo)DataNode掛了,則重新尋找一個(gè)DataNode繼續(xù)執(zhí)行當(dāng)前水平復(fù)制;
(2)如果水平復(fù)制過程中目標(biāo)機(jī)柜掛了(即該機(jī)柜上的所有DataNode節(jié)點(diǎn)均不能訪問了),則以當(dāng)前DataNode作為第一個(gè)副本,重新執(zhí)行第二步和第三步;
(3)將第一步和第三步的兩個(gè)DataNode節(jié)點(diǎn)放到同一個(gè)機(jī)柜上,是為了當(dāng)其中一個(gè)掛了時(shí),能夠快速的從“本地”獲取數(shù)據(jù),因?yàn)榈诙降腄ataNode可能在不同的機(jī)房或者城市。
3.倒排索引
Google的爬蟲每天把全世界的網(wǎng)頁爬回來存儲(chǔ)在GFS上之后,怎樣根據(jù)用戶輸入的檢索關(guān)鍵詞快速找到對應(yīng)的網(wǎng)頁呢?這就要用到一種索引技術(shù)——倒排索引,英文名為Inverted Index。也許叫它“逆向索引”更好理解一些:傳統(tǒng)的檢索方式一般都是根據(jù)文件名查找內(nèi)容,這就是一般的索引;而倒排索引卻反過來,是根據(jù)內(nèi)容查找文件名。下面就來詳細(xì)討論一下這兩種索引的工作原理。
3.1索引
假設(shè)現(xiàn)在有一張員工表tblEMP,我們需要查詢其中的部門號detpno=1的所有員工的信息。如果沒有建立索引,則需要遍歷tblEMP中的每一條記錄,找出其中1號部門的員工,這在數(shù)據(jù)量較小的時(shí)候還是可行的,但是在數(shù)據(jù)量較大時(shí)暴力查找就變得難以忍受了。因此我們可以在deptno列上建一個(gè)索引myindex,由于索引是排好序的,因此可以采用二分查找來加快查找速度。

3.1.1建立索引和刪除索引
在MySQL數(shù)據(jù)庫中建立索引的命令是:create index myindex on tblEMP(deptno);
在MySQL數(shù)據(jù)庫中刪除索引的命令是:drop index myindex on tblEMP;
其他數(shù)據(jù)庫參考相應(yīng)的命令語法。
3.1.2驗(yàn)證建立索引后的性能
通過使用執(zhí)行計(jì)劃可以查看SQL語句的執(zhí)行性能:explain select * from tblEMP where deptno = 1;
以MySQL為例演示建立索引和不建立索引的性能差異:

(*)不建立索引

可以看到,在不建立索引時(shí),查找部門號為1的員工需要遍歷的行數(shù)rows=7;
(*)建立索引

在建立索引之后,查找部門號為1的員工需要遍歷的行數(shù)rows=2;大大加快了查詢效率。
3.2倒排索引
不同于上面的索引,倒排索引是根據(jù)內(nèi)容查找文件。下圖簡要說明了倒排索引的基本原理。

這里假設(shè)有三篇文章(為了方便說明,假設(shè)每篇文章只有一句話)。第一步,先通過分詞得到一張?jiān)急?,index列代表word所在的文章號;第二步,通過去重、合并同一個(gè)詞出現(xiàn)的所有文章號;第三步,將word作按照字典排序,即可得到最終的倒排索引表。
檢索一個(gè)詞時(shí),只需要采用二分法或者其他更高效的算法找到該詞,即可找出該詞出現(xiàn)的文章號;檢索一個(gè)句子時(shí),只需要先將這個(gè)句子分成多個(gè)詞,然后分別找出每個(gè)詞對應(yīng)的文章號,最后進(jìn)行交集運(yùn)算即可找到這個(gè)句子出現(xiàn)的文章號。
注:以上例子只是最簡單的一個(gè)倒排索引的說明,真正的搜索引擎使用的倒排索引要復(fù)雜的多。一個(gè)好的搜索引擎一定要在“分詞”過程中處理的非常完美,如Google的多語言分詞,百度的中文分詞,都是很優(yōu)秀的分詞系統(tǒng)。
至此,Hadoop的分布式文件系統(tǒng)HDFS的工作原理已經(jīng)介紹完畢。祝你玩的愉快!