我眼中的大數據(二)——HDFS

来源:https://www.cnblogs.com/hhhnicvscs/archive/2022/09/22/16719579.html
-Advertisement-
Play Games

Hadoop的第一個產品是HDFS,可以說分散式文件存儲是分散式計算的基礎,也可見分散式文件存儲的重要性。如果我們將大數據計算比作烹飪,那麼數據就是食材,而Hadoop分散式文件系統HDFS就是燒菜的那口大鍋。這些年來,各種計算框架、各種演算法、各種應用場景不斷推陳出新,讓人眼花繚亂,但是大數據存儲的 ...


Hadoop的第一個產品是HDFS,可以說分散式文件存儲是分散式計算的基礎,也可見分散式文件存儲的重要性。如果我們將大數據計算比作烹飪,那麼數據就是食材,而Hadoop分散式文件系統HDFS就是燒菜的那口大鍋。這些年來,各種計算框架、各種演算法、各種應用場景不斷推陳出新,讓人眼花繚亂,但是大數據存儲的王者依然是HDFS。

為什麼HDFS的地位如此穩固呢?在整個大數據體系裡面,最寶貴、最難以代替的資產就是數據,大數據所有的一切都要圍繞數據展開。HDFS作為最早的大數據存儲系統,存儲著寶貴的數據資產,各種新的演算法、框架要想得到人們的廣泛使用,必須支持HDFS才能獲取已經存儲在裡面的數據。所以大數據技術越發展,新技術越多,HDFS得到的支持越多,我們越離不開HDFS。HDFS也許不是最好的大數據存儲技術,但依然最重要的大數據存儲技術

那我們就從HDFS的原理說起,今天我們來聊聊HDFS是如何實現大數據高速、可靠的存儲和訪問的。

Hadoop分散式文件系統HDFS的設計目標是管理數以千計的伺服器、數以萬計的磁碟,將這麼大規模的伺服器計算資源當作一個單一的存儲系統進行管理,對應用程式提供數以PB計的存儲容量,讓應用程式像使用普通文件系統一樣存儲大規模的文件數據。

如何設計這樣一個分散式文件系統?其實思路很簡單。

我們想想RAID磁碟陣列存儲,RAID將數據分片後在多塊磁碟上併發進行讀寫訪問,從而提高了存儲容量、加快了訪問速度,並通過數據的冗餘校驗提高了數據的可靠性,即使某塊磁碟損壞也不會丟失數據。將RAID的設計理念擴大到整個分散式伺服器集群,就產生了分散式文件系統,Hadoop分散式文件系統的核心原理就是如此。

和RAID在多個磁碟上進行文件存儲及並行讀寫的思路一樣,HDFS是在一個大規模分散式伺服器集群上,對數據分片後進行並行讀寫及冗餘存儲。因為HDFS可以部署在一個比較大的伺服器集群上,集群中所有伺服器的磁碟都可供HDFS使用,所以整個HDFS的存儲空間可以達到PB級容量。

上圖是HDFS的架構圖,從圖中你可以看到HDFS的關鍵組件有兩個,一個是DataNode,一個是NameNode。

DataNode負責文件數據的存儲和讀寫操作,HDFS將文件數據分割成若幹數據塊(Block),每個DataNode存儲一部分數據塊,這樣文件就分佈存儲在整個HDFS伺服器集群中。應用程式客戶端(Client)可以並行對這些數據塊進行訪問,從而使得HDFS可以在伺服器集群規模上實現數據並行訪問,極大地提高了訪問速度。

在實踐中,HDFS集群的DataNode伺服器會有很多台,一般在幾百台到幾千台這樣的規模,每台伺服器配有數塊磁碟,整個集群的存儲容量大概在幾PB到數百PB。

NameNode負責整個分散式文件系統的元數據(MetaData)管理,也就是文件路徑名、數據塊的ID以及存儲位置等信息。HDFS為了保證數據的高可用,會將一個數據塊複製為多份(預設情況為3份),並將多份相同的數據塊存儲在不同的伺服器上,甚至不同的機架上。這樣當有磁碟損壞,或者某個DataNode伺服器宕機,甚至某個交換機宕機,導致其存儲的數據塊不能訪問的時候,客戶端會查找其備份的數據塊進行訪問。

下麵這張圖是數據塊多份複製存儲的示意,圖中對於文件/users/sameerp/data/part-0,其複製備份數設置為2,存儲的BlockID分別為1、3。Block1的兩個備份存儲在DataNode0和DataNode2兩個伺服器上,Block3的兩個備份存儲DataNode4和DataNode6兩個伺服器上,上述任何一臺伺服器宕機後,每個數據塊都至少還有一個備份存在,不會影響對文件/users/sameerp/data/part-0的訪問。

和RAID一樣,數據分成若幹數據塊後存儲到不同伺服器上,可以實現數據大容量存儲,並且不同分片的數據可以並行進行讀/寫操作,進而實現數據的高速訪問。你可以看到,HDFS的大容量存儲和高速訪問相對比較容易實現,但是HDFS是如何保證存儲的高可用性呢?

我們嘗試從不同層面來討論一下HDFS的高可用設計。

1.數據存儲故障容錯

磁碟介質在存儲過程中受環境或者老化影響,其存儲的數據可能會出現錯亂。HDFS的應對措施是,對於存儲在DataNode上的數據塊,計算並存儲校驗和(CheckSum)。在讀取數據的時候,重新計算讀取出來的數據的校驗和,如果校驗不正確就拋出異常,應用程式捕獲異常後就到其他DataNode上讀取備份數據。

2.磁碟故障容錯

如果DataNode監測到本機的某塊磁碟損壞,就將該塊磁碟上存儲的所有BlockID報告給NameNode,NameNode檢查這些數據塊還在哪些DataNode上有備份,通知相應的DataNode伺服器將對應的數據塊複製到其他伺服器上,以保證數據塊的備份數滿足要求。

3.DataNode故障容錯

DataNode會通過心跳和NameNode保持通信,如果DataNode超時未發送心跳,NameNode就會認為這個DataNode已經宕機失效,立即查找這個DataNode上存儲的數據塊有哪些,以及這些數據塊還存儲在哪些伺服器上,隨後通知這些伺服器再複製一份數據塊到其他伺服器上,保證HDFS存儲的數據塊備份數符合用戶設置的數目,即使再出現伺服器宕機,也不會丟失數據。

4.NameNode故障容錯

NameNode是整個HDFS的核心,記錄著HDFS文件分配表信息,所有的文件路徑和數據塊存儲信息都保存在NameNode,如果NameNode故障,整個HDFS系統集群都無法使用;如果NameNode上記錄的數據丟失,整個集群所有DataNode存儲的數據也就沒用了。

所以,NameNode高可用容錯能力非常重要。NameNode採用主從熱備的方式提供高可用服務,請看下圖。

集群部署兩台NameNode伺服器,一臺作為主伺服器提供服務,一臺作為從伺服器進行熱備,兩台伺服器通過ZooKeeper選舉,主要是通過爭奪znode鎖資源,決定誰是主伺服器。而DataNode則會向兩個NameNode同時發送心跳數據,但是只有主NameNode才能向DataNode返回控制信息。

正常運行期間,主從NameNode之間通過一個共用存儲系統shared edits來同步文件系統的元數據信息。當主NameNode伺服器宕機,從NameNode會通過ZooKeeper升級成為主伺服器,並保證HDFS集群的元數據信息,也就是文件分配表信息完整一致。

對於一個軟體系統而言,性能差一點,用戶也許可以接受;使用體驗差,也許也能忍受。但是如果可用性差,經常出故障導致不可用,那就比較麻煩了;如果出現重要數據丟失,那開發工程師絕對是攤上大事了。

而分散式系統可能出故障地方又非常多,記憶體、CPU、主板、磁碟會損壞,伺服器會宕機,網路會中斷,機房會停電,所有這些都可能會引起軟體系統的不可用,甚至數據永久丟失。

所以在設計分散式系統的時候,軟體工程師一定要繃緊可用性這根弦,思考在各種可能的故障情況下,如何保證整個軟體系統依然是可用的。

根據我的經驗,一般說來,常用的保證系統可用性的策略有冗餘備份、失效轉移和降級限流。雖然這3種策略你可能早已耳熟能詳,但還是有一些容易被忽略的地方。

比如冗餘備份,任何程式、任何數據,都至少要有一個備份,也就是說程式至少要部署到兩台伺服器,數據至少要備份到另一臺伺服器上。此外,稍有規模的互聯網企業都會建設多個數據中心,數據中心之間互相進行備份,用戶請求可能會被分發到任何一個數據中心,即所謂的異地多活,在遭遇地域性的重大故障和自然災害的時候,依然保證應用的高可用。

當要訪問的程式或者數據無法訪問時,需要將訪問請求轉移到備份的程式或者數據所在的伺服器上,這也就是失效轉移。失效轉移你應該註意的是失效的鑒定,像NameNode這樣主從伺服器管理同一份數據的場景,如果從伺服器錯誤地以為主伺服器宕機而接管集群管理,會出現主從伺服器一起對DataNode發送指令,進而導致集群混亂,也就是所謂的“腦裂”。這也是這類場景選舉主伺服器時,引入ZooKeeper的原因。ZooKeeper的工作原理,我將會在後面專門分析。

當大量的用戶請求或者數據處理請求到達的時候,由於計算資源有限,可能無法處理如此大量的請求,進而導致資源耗盡,系統崩潰。這種情況下,可以拒絕部分請求,即進行限流;也可以關閉部分功能,降低資源消耗,即進行降級。限流是互聯網應用的常備功能,因為超出負載能力的訪問流量在何時會突然到來,你根本無法預料,所以必須提前做好準備,當遇到突發高峰流量時,就可以立即啟動限流。而降級通常是為可預知的場景準備的,比如電商的“雙十一”促銷,為了保障促銷活動期間應用的核心功能能夠正常運行,比如下單功能,可以對系統進行降級處理,關閉部分非重要功能,比如商品評價功能。

我們小結一下,看看HDFS是如何通過大規模分散式伺服器集群實現數據的大容量、高速、可靠存儲、訪問的。

1.文件數據以數據塊的方式進行切分,數據塊可以存儲在集群任意DataNode伺服器上,所以HDFS存儲的文件可以非常大,一個文件理論上可以占據整個HDFS伺服器集群上的所有磁碟,實現了大容量存儲。

2.HDFS一般的訪問模式是通過MapReduce程式在計算時讀取,MapReduce對輸入數據進行分片讀取,通常一個分片就是一個數據塊,每個數據塊分配一個計算進程,這樣就可以同時啟動很多進程對一個HDFS文件的多個數據塊進行併發訪問,從而實現數據的高速訪問。關於MapReduce的具體處理過程,我們會在專欄後面詳細討論。

3.DataNode存儲的數據塊會進行複製,使每個數據塊在集群里有多個備份,保證了數據的可靠性,並通過一系列的故障容錯手段實現HDFS系統中主要組件的高可用,進而保證數據和整個系統的高可用。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一:背景 1. 講故事 其實這個問題是前段時間有位朋友咨詢我的,由於問題說的比較泛,不便作答,但想想梳理一下還是能回答一些的,這篇就來聊一聊下麵這幾個鎖。 Interlocked AutoResetEvent / ManualResetEvent Semaphore 用戶態層面我就不想說了,網上一搜 ...
  • .NET運行時之書(Book of the Runtime,簡稱BotR)是一系列描述.NET運行時的文檔,2007年左右在微軟內部創建,最初的目的為了幫助其新員工快速上手.NET運行時;隨著.NET開源,BotR也被公開了出來,如果你想深入理解CLR,這系列文章你不可錯過。 BotR系列目錄: [ ...
  • 從頭一二去閱讀語法和命令說明,對於腳本小白來說比較枯燥,難以堅持,所以這裡選擇對一份完整的shell腳本代碼來逐行逐段解讀,希望可以一渡小白,幫助我們快速進入腳本的大門^_^ ...
  • 版本控制gitlab 什麼是版本控制gitlab GitLab 是一個用於倉庫管理系統的開源項目,使用Git作為代碼管理工具,併在此基礎上搭建起來的Web服務。安裝方法是參考GitLab在GitHub上的Wiki頁面。Gitlab是目前被廣泛使用的基於git的開源代碼管理平臺, 基於Ruby on ...
  • 提到直流無刷電機,那不得不提的就是有刷電機了。有刷電機有一個比較令人討厭的缺點:那就是“吵”。 因為電刷和換向環需要時刻不停地摩擦,才能給電樞供電。 所以,如果你想要一個“靜音風扇”的話,肯定不能選使用了有刷電機的產品。 並且電刷使用時間久了,比較容易損壞。電流較大的時候,你甚至可以看到電刷在換向的 ...
  • 腳本安裝lamp [root@localhost ~]# mkdir lamp [root@localhost ~]# cd lamp/ [root@localhost lamp]# mkdir files [root@localhost lamp]# ls files [root@localhos ...
  • 2022-09-18-21:28:59 老師作業說明: TOP500中國超算占比,LINUX系統占比 說明:當時使用的是bing搜索,中國超算占比其實澎湃新聞什麼的都有介紹,但是我對它的數據來源持懷疑態度,索性自己去官網上看資料,後面解決Linux系統占比問題時,也是直接想著在官網解決,其實後面和同 ...
  • 近日, 在一個小型項目中, 遇到了一個觸及我知識盲區的bug. 項目用的是MySQL 5.7.25, 其中有一張表 config_data, 包含四個欄位, id, name, value, expireAt. 其中id為主鍵, name建有唯一索引, 表的用途大概就是存放一些有時效性的配置. 以上 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 在我們開發過程中基本上不可或缺的用到一些敏感機密數據,比如SQL伺服器的連接串或者是OAuth2的Secret等,這些敏感數據在代碼中是不太安全的,我們不應該在源代碼中存儲密碼和其他的敏感數據,一種推薦的方式是通過Asp.Net Core的機密管理器。 機密管理器 在 ASP.NET Core ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 順序棧的介面程式 目錄順序棧的介面程式頭文件創建順序棧入棧出棧利用棧將10進位轉16進位數驗證 頭文件 #include <stdio.h> #include <stdbool.h> #include <stdlib.h> 創建順序棧 // 指的是順序棧中的元素的數據類型,用戶可以根據需要進行修改 ...
  • 前言 整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本為 v11 最新的版本。 開源項目 從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。 系列文章 web server apache tomcat11-01-官方文檔入門介紹 web serv ...
  • C總結與剖析:關鍵字篇 -- <<C語言深度解剖>> 目錄C總結與剖析:關鍵字篇 -- <<C語言深度解剖>>程式的本質:二進位文件變數1.變數:記憶體上的某個位置開闢的空間2.變數的初始化3.為什麼要有變數4.局部變數與全局變數5.變數的大小由類型決定6.任何一個變數,記憶體賦值都是從低地址開始往高地 ...
  • 如果讓你來做一個有狀態流式應用的故障恢復,你會如何來做呢? 單機和多機會遇到什麼不同的問題? Flink Checkpoint 是做什麼用的?原理是什麼? ...
  • C++ 多級繼承 多級繼承是一種面向對象編程(OOP)特性,允許一個類從多個基類繼承屬性和方法。它使代碼更易於組織和維護,並促進代碼重用。 多級繼承的語法 在 C++ 中,使用 : 符號來指定繼承關係。多級繼承的語法如下: class DerivedClass : public BaseClass1 ...
  • 前言 什麼是SpringCloud? Spring Cloud 是一系列框架的有序集合,它利用 Spring Boot 的開發便利性簡化了分散式系統的開發,比如服務註冊、服務發現、網關、路由、鏈路追蹤等。Spring Cloud 並不是重覆造輪子,而是將市面上開發得比較好的模塊集成進去,進行封裝,從 ...
  • class_template 類模板和函數模板的定義和使用類似,我們已經進行了介紹。有時,有兩個或多個類,其功能是相同的,僅僅是數據類型不同。類模板用於實現類所需數據的類型參數化 template<class NameType, class AgeType> class Person { publi ...
  • 目錄system v IPC簡介共用記憶體需要用到的函數介面shmget函數--獲取對象IDshmat函數--獲得映射空間shmctl函數--釋放資源共用記憶體實現思路註意 system v IPC簡介 消息隊列、共用記憶體和信號量統稱為system v IPC(進程間通信機制),V是羅馬數字5,是UNI ...