什麼是HDFS?算了,告訴你也不懂。

前言

只有光頭才能變強。

文本已收錄至個人GitHub精選文章,歡迎Starhttps://github.com/ZhongFuCheng3y/3ygit

上一篇已經講解了「大數據入門」的相關基礎概念和知識了,這篇咱們來學學HDFS。若是文章有錯誤的地方,不妨在評論區友善指出~github

1、HDFS介紹

上篇文章已經講到了,隨着數據量愈來愈大,在一臺機器上已經沒法存儲全部的數據了,那咱們會將這些數據分配到不一樣的機器來進行存儲,可是這就帶來一個問題:不方便管理和維護服務器

因此,咱們就但願有一個系統能夠將這些分佈在不一樣操做服務器上的數據進行統一管理,這就有了分佈式文件系統架構

  • HDFS是分佈式文件系統的其中一種(目前用得最普遍的一種)

在使用HDFS的時候是很是簡單的:雖然HDFS是將文件存儲到不一樣的機器上,可是我去使用的時候是把這些文件當作是存儲在一臺機器的方式去使用(背後倒是多臺機器在執行):app

  • 比如:我調用了一個RPC接口,我給他參數,他返回一個response給我。RPC接口作了什麼事其實我都不知道的(可能這個RPC接口又調了其餘的RPC接口)-----屏蔽掉實現細節,對用戶友好

HDFS使用

明確一下:HDFS就是一個分佈式文件系統,一個文件系統,咱們用它來作什麼?存數據呀框架

下面,咱們來了解一下HDFS的一些知識,可以幫咱們更好地去「使用」HDFS分佈式

2、HDFS學習

從上面咱們已經提到了,HDFS做爲一個分佈式文件系統,那麼它的數據是保存在多個系統上的。例如,下面的圖:一個1GB的文件,會被切分成幾個小的文件,每一個服務器都會存放一部分。工具

那確定會有人會問:那會切分多少個小文件呢?默認以128MB的大小來切分,每一個128MB的文件,在HDFS叫作(block)學習

顯然,這個128MB大小是可配的。若是設置爲過小或者太大都很差。若是切分的文件過小,那一份數據可能分佈到多臺的機器上(尋址時間就很慢)。若是切分的文件太大,那數據傳輸時間的時間就很慢。

PS:老版本默認是64MB大數據

一個用戶發出了一個1GB的文件請求給HDFS客戶端,HDFS客戶端會根據配置(如今默認是128MB),對這個文件進行切分,因此HDFS客戶端會切分爲8個文件(也叫作block),而後每一個服務器都會存儲這些切分後的文件(block)。如今咱們假設每一個服務器都存儲兩份

這些存放真實數據的服務器,在HDFS領域叫作DataNode

如今問題來了,HDFS客戶端按照配置切分完之後,怎麼知道往哪一個服務器(DataNode)放數據呢?這個時候,就須要另外一個角色了,管理者(NameNode)。

NameNode實際上就是管理文件的各類信息(這種信息專業點咱們叫作MetaData「元數據」),其中包括:文文件路徑名,每一個Block的ID和存放的位置等等。

因此,不管是讀仍是寫,HDFS客戶端都會先去找NameNode,經過NameNode得知相應的信息,再去找DataNode

  • 若是是寫操做,HDFS切分完文件之後,會詢問NameNode應該將這些切分好的block往哪幾臺DataNode上寫。
  • 若是是讀操做,HDFS拿到文件名,也會去詢問NameNode應該往哪幾臺DataNode上讀數據。

2.1 HDFS備份

做爲一個分佈式系統(把大文件切分爲多個小文件,存儲到不一樣的機器上),若是沒有備份的話,只要有其中的一臺機器掛了,那就會致使「數據」是不可用狀態的。

寫到這裏,若是看過個人 KafkaElasticSearch的文章可能就懂了。其實思想都是同樣的。

Kafka對partition備份,ElasticSearch對分片進行備份,而到HDFS就是對Block進行備份。

儘量將數據備份到不一樣的機器上,即使某臺機器掛了,那就能夠將備份數據拉出來用。

對Kafka和ElasticSearch不瞭解的同窗,能夠關注個人GitHub,搜索關鍵字便可查詢(我以爲還算寫得比較通俗易懂的)

注:這裏的備份並不須要HDFS客戶端去寫,只要DataNode之間互相傳遞數據就行了。

2.2 NameNode的一些事

從上面咱們能夠看到,NameNode是須要處理hdfs客戶端請求的。(由於它是存儲元數據的地方,不管讀寫都須要通過它)。

如今問題就來了,NameNode是怎麼存放元數據的呢?

  • 若是NameNode只是把元數據放到內存中,那若是NameNode這臺機器重啓了,那元數據就沒了。
  • 若是NameNode將每次寫入的數據都存儲到硬盤中,那若是只針對磁盤查找和修改又會很慢(由於這個是純IO的操做)

說到這裏,又想起了Kafka。Kafka也是將partition寫到磁盤裏邊的,但人家是怎麼寫的?順序IO

NameNode一樣也是作了這個事:修改內存中的元數據,而後把修改的信息append(追加)到一個名爲editlog的文件上。

因爲append是順序IO,因此效率也不會低。如今咱們增刪改查都是走內存,只不過增刪改的時候往磁盤文件editlog裏邊追加一條。這樣咱們即使重啓了NameNode,仍是能夠經過editlog文件將元數據恢復。

如今也有個問題:若是NameNode一直長期運行的話,那editlog文件應該會愈來愈大(由於全部的修改元數據信息都須要在這追加一條)。重啓的時候須要依賴editlog文件來恢復數據,若是文件特別大,那啓動的時候不就特別慢了嗎?

的確是如此的,那HDFS是怎麼作的呢?爲了防止editlog過大,致使在重啓的時候須要較長的時間恢復數據,因此NameNode會有一個內存快照,叫作fsimage

說到快照,有沒有想起Redis的RDB!!

這樣一來,重啓的時候只須要加載內存快照fsimage+部分的editlog就能夠了。

想法很美好,現實還須要解決一些事:我何時生成一個內存快照fsimage?我怎麼知道加載哪一部分的editlog

問題看起來好像複雜,其實咱們就只須要一個定時任務

若是讓我本身作的話,我可能會想:咱們加一份配置,設置個時間就OK了

  • 若是editlog大到什麼程度或者隔了多長時間,咱們就把editlog文件的數據跟內存快照fsiamge給合併起來。而後生成一個新的fsimage,把editlog給清空,覆蓋舊的fsimage內存快照
  • 這樣一來,NameNode每次重啓的時候,拿到的都是最新的fsimage文件,editlog裏邊的都是沒合併到fsimage的。根據這兩個文件就能夠恢復最新的元數據信息了。

HDFS也是相似上面這樣乾的,只不過它不是在NameNode起個定時的任務跑,而是用了一個新的角色:SecondNameNode。至於爲何?可能HDFS以爲合併所耗費的資源太大了,不一樣的工做交由不一樣的服務器來完成,也符合分佈式的理念。

如今問題仍是來了,此時的架構NameNode是單機的。SecondNameNode的做用只是給NameNode合併editlogfsimage文件,若是NameNode掛了,那client就請求不到了,而全部的請求都須要走NameNode,這致使整個HDFS集羣都不可用了。

因而咱們須要保證NameNode是高可用的。通常如今咱們會經過Zookeeper來實現。架構圖以下:

主NameNode和從NameNode須要保持元數據的信息一致(由於若是主NameNode掛了,那從NameNode須要頂上,這時從NameNode須要有主NameNode的信息)。

因此,引入了Shared Edits來實現主從NameNode之間的同步,Shared Edits也叫作JournalNode。實際上就是主NameNode若是有更新元數據的信息,它的editlog會寫到JournalNode,而後從NameNode會在JournalNode讀取到變化信息,而後同步。從NameNode也實現了上面所說的SecondNameNode功能(合併editlog和fsimage)

稍微總結一下:

  • NameNode須要處理client請求,它是存儲元數據的地方
  • NameNode的元數據操做都在內存中,會把增刪改以editlog持續化到硬盤中(由於是順序io,因此不會太慢)
  • 因爲editlog可能存在過大的問題,致使從新啓動NameNode過慢(由於要依賴editlog來恢復數據),引出了fsimage內存快照。須要跑一個定時任務來合併fsimageeditlog,引出了SecondNameNode
  • 又由於NameNode是單機的,可能存在單機故障的問題。因此咱們能夠經過Zookeeper來維護主從NameNode,經過JournalNode(Share Edits)來實現主從NameNode元數據的一致性。最終實現NameNode的高可用。

2.3 學點DataNode

從上面咱們就知道,咱們的數據是存放在DataNode上的(還會備份)。

若是某個DataNode掉線了,那HDFS是怎麼知道的呢?

DataNode啓動的時候會去NameNode上註冊,他倆會維持心跳,若是超過期間閾值沒有收到DataNode的心跳,那HDFS就認爲這個DataNode掛了。

還有一個問題就是:咱們將Block存到DataNode上,那仍是有可能這個DataNode的磁盤損壞了部分,而咱們DataNode沒有下線,但咱們也不知道損壞了。

一個Block除了存放數據的自己,還會存放一份元數據(包括數據塊的長度,塊數據的校驗和,以及時間戳)。DataNode仍是會按期向NameNode上報全部當前全部Block的信息,經過元數據就可校驗當前的Block是否是正常狀態

最後

其實在學習HDFS的時候,你會發現不少的思想跟以前學過的都相似。就好比提到的Kafka、Elasticsearch這些經常使用的分佈式組件。

若是對Kafka、Elasticsearch、Zookeeper、Redis等不瞭解的同窗,能夠在個人GitHub或公衆號裏邊找對應的文章哦~我以爲還算寫得通俗易懂的。

改天整合一下這些框架的持久化特色,再寫一篇(由於能夠發現,他們的持久化機制都十分相似)

下一篇無心外的話,會寫寫MapReduce,感謝你看到這裏

參考資料:

  • HDFS漫畫
  • 《從零開始學大數據 -李智慧》

若是你們想要實時關注我更新的文章以及分享的乾貨的話,能夠關注個人公衆號「Java3y」。

  • 🔥Java精美腦圖
  • 🔥Java學習路線
  • 🔥開發經常使用工具

在公衆號下回復「888」便可獲取!!

本已收錄至個人GitHub精選文章,歡迎Starhttps://github.com/ZhongFuCheng3y/3y

求點贊 求關注️ 求分享👥 求留言💬 對我來講真的 很是有用!!!

相關文章
相關標籤/搜索