㈠ hdfs詳解之塊、小文件和副本數
1、block:block是物理切塊,在文件上傳到HDFS文件系統後,對大文件將以每128MB的大小切分若干,存放在不同的DataNode上。例如一個文件130M,那麼他會存被切分成2個塊,一個塊128M,另一個塊2M.
1、HDFS 適應場景: 大文件存儲,小文件是致命的
2、如果小文件很多的,則有可能將NN(4G=42億位元組)撐爆。例如:1個小文件(閾值<=30M),那麼NN節點維護的位元組大約250位元組。一億個小文件則是250b * 1億=250億.將會把NN節點撐爆。如果一億個小文件合並成100萬個大文件:250b * 1百萬=2億位元組。
3、在生產上一般會:
1)調整小文件閾值
2)合並小文件:
a.數據未落地到hdfs之前合並
b.數據已經落到hdfs,調用spark service服務 。每天調度去合並 (-15天 業務周期)
3)小文件的危害:
a.撐爆NN。
b.影響hive、spark的計算。佔用集群計算資源
1、如果是偽分布式,那麼副本數只能為一。
2、生成上副本數一般也是官方默認參數: 3份
如果一個文件130M,副本數為3。那麼第一個block128M,有三份。另外一個block2M,也有三份。
題目:
blockSize128M,副本數3份,那麼一個文件260M,請問多少塊,多少實際存儲?
260%128=2....4M 3個塊 3個副本=9塊
260M 3=780M
㈡ HDFS介紹
HDFS是拿清一個文件系統,用於存儲文件,通過目錄樹來定位文件。
它是分布式的,有分多伺服器聯合起來實現其功能。
適合一次寫入,多次讀出的場景,且不支持文件的修改。
是和數據分析,並不適合用來做網盤應用。
NameNode(nn):1.存儲文件的元數據{1.文件信息(文件名,文件目錄結構,文件屬性(生成時間,副本數,文件許可權)),2.每個文件的塊列表和塊所在的DataNode(Block映射信息)},2.處理客戶端讀寫請求。
DataNode(dn):在本地文件系統存儲文件塊數據,以及塊數據的校驗。
Secondary NameNode(2nn):是一個輔助後台的程序,用來監控HDFS狀態,每隔一段時間獲取HDFS元數據的快照。
上面計算的每秒叢敏高傳輸大小為100MB只是一個近似值,實際為128M。
機械硬碟文件順序讀寫的速度為100MB/s
普通固態為500MB/s
pcie固態的速度可以達到2000MB/s
因此塊的大小可以分別設為128MB,512MB,2048MB.
CPU,磁碟,網卡之間的協同效率 即 跨物理機/機架之間文件滲尺傳輸速率
1. 如果塊設置過大,
2. 如果塊設置過小,
文件塊越大,定址時間越短,但磁碟傳輸時間越長;
文件塊越小,定址時間越長,但磁碟傳輸時間越短。
㈢ HDFS(五):NN和2NN
內存一份數據,fsImage存儲數據(合並後的數據,即沒有追加前數據),edits文件只追加,不參與計算
內存數據 == fsImage+edits
伺服器啟動:將(fsImage+edits)數據載入到內存
伺服器關閉:將 fsImage+edits合並
2nn將fsimage和edits文件定期合並
NameNode 被格式化後,將槐碼在/opt/mole/hadoop-3.1.3/data/tmp/dfs/name/current目錄中產生如下文件
2NN 在/opt/mole/hadoop-3.1.3/data/tmp/dfs/namesecondary/current
NameNode相比較2nn多了edits_inprogress
NameNode被格式化之後,將在/opt/mole/hadoop-3.1.3/data/tmp/dfs/name/current目錄產生如下文件
1)fsimage文件:HDFS文件系統元數念納據的一個永久性檢查點,其中包含HDFS文件系統的所有目錄和inode的序列化信息
2)Edits文件:存放HDFS文件系統的所有更新操作的路徑,文件系統客戶端執行的所有寫操作首先會被記錄到edits文件中
3)seen_txid:文件保存的是一個數字,就是最後一個edits_數字
4)VERSION,當前nameNode的命名空鉛高哪間,和集群id
(1)基本語法
hdfs oiv -p 文件類型 -i鏡像文件 -o 轉換後文件輸出路徑
(2)實操
NameNode沒有記錄塊所對應DataNode,DataNode啟動後向NameNode匯報自己有哪些文件塊
(1)基本語法
hdfs oev -p 文件類型 -i 編輯日誌 -o 轉換後文件輸出路徑
(2)實操
只進行追加,不進行合並操作。
在伺服器啟動進入內存,只載入edits後綴大於fsimage後綴。
hdfs-default.xml
1)通常情況下,SecondaryNameNode每隔一個小時執行一次。[hdfs-default.xml]
2)一分鍾檢查一次操作次數,當操作次數達到1百萬次,SecondaryNameNode執行一次。
2nn每隔1分鍾,主動查詢一次。
通過本節可以知道兩個文件fsimage和edits文件作用,通過這兩個文件就是NameNode存儲的元數據。
㈣ hadoop面試題之HDFS
1、簡單介紹下hadoop吧?
廣義上hadoop是指與hadoop相關的大數據生態圈。包含hive、spark、hbase等。
狹義上hadoop指的是手悉apache的開源框架。有三個核心組件:
----hdfs:分布式文件存儲系統
----yarn:分布式資源管理調度平台
----mr:分布式計算引擎
2、介紹下hdfs?
全稱為Hadoop Distributed File System。有三個核心組件:
namenode:有三個作用,第一是負責保存集群的元數據信息,第二是負責維護整個集群節點的正常運行。
第三是負責處理客戶端的請求。
datanode:負責實際保存數據。實際執行數據塊的讀寫操作。
secondarynamenode:輔助namenode進行元數據的管理。不是namenode的備份。
3、namenode的工作機制?
namenode在內存中保存著整個內存系統的名稱空間和文件數據塊的地址映射。整個hdfs可存儲的文件數受限於namenode的內存大小。所以hdfs不適合大量小文件的存儲。
---namenode有三種元數據存儲方式來管理元數據:
》內存元數據:內存中保存了完整的元數據
》保存在磁碟上的元數據鏡像文件(fsimage):該文件時hdfs存在磁碟中梁纖的元數據檢查點,裡面保存的是最後一次檢查點之前的hdfs文件系統中所有目錄和文件的序列化信息。
》數據操作日誌文件(edits):用於銜接內存meta data和持久化元數據鏡像fsimage之間的操作日誌文件。保存了自最後一次檢查點之後所有針對hdfs文件系統的操作。如對文件的增刪改查。
4、如何查看元數據信息?
因為edits和fsimage文件是經過序列化的,所以不能直接查看。hadoop2.0以上提供了查看兩種文件的工具。
----命令:hdfs oiv 可以將fsimage文件轉換成其他格式,如xml和文本文件。-i 表示輸入fsimage文件。-o 輸出文件路徑,-p 指定輸出文件
hdfs oev可以查看edits文件。同理需要指定相關參數。
詳情查看: https://www.imooc.com/article/79705
4、datanode的工作機制?
1)以數據塊的形式存儲hdfs文件
2)datanode響應客戶端的讀寫請求
3)周期性的向namenode匯報心跳信息、數據塊信息、緩存數據塊信息
5、secondary namenode工作機制?
當發生checkpoint機制時會觸發second namenode進行工作。checkpoint:
新的edists文件不會立即和fsimage文件合並,是在edits文件大小超過(默認)64m,或者時間超過(默認)1小時,會觸發checkpoint操作。當checkpoint時,namenode會新建一個edits.new的文件,此時second namenode將文件fsimage文件和edits文件(http get)到本地,然後載入到內存中進行合並,完成的文件名稱為fsimage.ckpt。最後 second namenode將該文件(http post)到namenode,然後edits.new和fsimage.ckpt文件轉換為fsimage和edits。
6、hdfs的文件副本機制?
所有的文件都是以塊的形式保存到hdfs中。塊的大小默認為128m。在hdfs-site文件中進行指定。
動態副本創建策略:默認副本數是3,可以在上傳文件時,顯式設定replication。也可以通過指令修改文件的副本數 hadoop fs -setrep -R 1
7、畢渣乎為實現高可用,hdfs採用了哪些策略?
副本機制、機架感知、心跳機制、安全模式、校驗和、回收站、元數據保護、快照機制(具體介紹導航- https://www.jianshu.com/writer#/notebooks/44567747/notes/66453316 )
8、hdfs的存儲過程?
①client向hdfs發起寫請求,通過RPC與namenode建立通訊。namenode檢查文件是否存在等信息,返回是否可以存儲。
②client將文件切割為一個個block塊,client申請存儲第一塊block。namenode返回可以存儲這個block塊的datanode的地址,假設為ABC。
③A到B到C逐級構建pipeline。client向A上傳第一個packet,默認為64k。A收到一個packet後會將packet傳給B,再傳給C。pipeline反方向返回ack信息。最終由第一個節點A將pipelineack發送給client
④一個block完成之後,再進行下一個block的存儲過程。
9、hdfs的讀過程?
10、hdfs的垃圾桶機制?
hdfs的垃圾桶機制默認是關閉的,需要手動開啟。hdfs刪除的文件不會立刻就刪除,而是在設定的時間後進行刪除。
11、hdfs的擴容和縮容
【
12、
㈤ centos7把文件存放在HDFS下
復制激哪文件。
centos7中支持的磁碟格式有:1.FAT16,使用了16位的空間來表示每個扇區的配置文件;2.FAT32,採用32位二進制數記錄管理的磁碟文件管理方式;3.NTFS,明跡碼為網路州爛和磁碟配額、文件加密等管理安全特性設計的磁碟格式。FAT16是指使用了16位的空間來表示每個扇區的配置文件,是用於記錄文件所在位置的表格,當FAT16容量超出時,所使用的簇就必須擴增,從而適應更大的磁碟空間。
㈥ hdfs適合存儲多大的單個文件
首先hdfs是建立在多個機器文件系統上的一個邏輯上的文件系統。它的底層數據以數據塊方式存儲,塊大小可進行調整。
假如你設置一個數據塊大小為256M,上傳一個1G的文件,它底層會將這個文件分成4塊存儲,每個塊256M。你在hdfs上看到的是一個完整的文件,隨時可對這個文件進行操作,無需關注它的存儲。就像你在操作系統上操作文件一樣,無需關注它存在那個磁碟哪個扇區
㈦ 使用saveastextfile存儲數據到hdfs要求數據類
使用saveastextfile存儲數據到hdfs要求數據類RDD。根據查詢相關公開信息顯示:saveAsTextFile用於將RDD以文本文件的格棚答式存儲到文件困賣系汪和逗統中。
㈧ HDFS能夠存儲哪幾種文件格式
hdfs可以存儲任何形式的文件啊。只要你硬碟能存儲什麼文件,它就能存儲什麼。其實文件就其本質,都是0001101001這種二進制數據。
所以什麼形式都可以的。
但是如果不是這種ascii形式的文件,你讀取他有什麼意思呢
比如一部電影,你放上去能處理嗎對吧
㈨ parquet和orc
Parquet文件是自解析的,文件中包括該文件的數據和元數據。在HDFS文件系統和Parquet文件中存在如下幾個概念:
1)HDFS塊(Block):它是HDFS上的最小的副本單位,HDFS會把一個Block存儲在本地的一個文件並且維護分散在不同的機器上的多個副本,通常情況下一個Block的大小為256M、512M等。
2)HDFS文件(File):一個HDFS的文件,包括數據和元數據,數據分散存儲在多個Block中。
3)行組(Row Group):按照行將數據物理上劃分為多個單元,每一個行組包含一定的行數,在一個HDFS文件中至少存儲一個行組,Parquet讀寫的時候會將整個行組緩存在內存中,所以如果每一個行組的大小是由內存大的小決定的。
4)列塊(Column Chunk):在一個行組中每一列保存在一個列塊中,行組中的所有列連續的存儲在這個行組文件中。不同的列塊可能使用不同的演算法進行壓縮。
5)頁(Page):每一個列塊劃分為多個頁,一個頁是最小的編碼的單位,在同一個列塊的不同頁可能使用不同的編碼方式。
Parquet文件的格式如下圖所示:
可以看出,存儲格式中元數據索引信息是被存儲在最後的,所以當讀取某一行的數據的時候,就需要去定位最後的索引信息,最後才能去讀取對應的行數據。元數據包括 Parquet 原始類型定義、Page類型、編碼類型、壓縮類型等等。
Parquet 支持嵌套結構的數據模型,而非扁平式的數據模型,這是 Parquet 相對其他列存比如 ORC 的一大特點或優勢。支持嵌套式結構,意味著 Parquet 能夠很好的將諸如 Protobuf,thrift,json 等對象模型進行列式存儲。
Parquet 的數據模型也是 schema 表達方式,用關鍵字 message 表示。每個欄位包含三個屬性,repetition屬性(required/repeated/optional)、數據類型(primitive基本類型/group復雜類型)及欄位名。如:
和Parquet類似,ORC文件也是以二進制方式存儲的,所以是不可以直接讀取,ORC文件也是自解析的,它包含許多的元數據,這些元數據都是同構ProtoBuffer進行序列化的。ORC的文件結構如下圖,其中涉及到如下的概念:
ORC文件:保存在文件系統上的普通二進制文件,一個ORC文件中可以包含多個stripe,每一個stripe包含多條記錄,這些記錄按照列進行獨立存儲,對應到Parquet中的row
group的概念。
文件級元數據:包括文件的描述信息PostScript、文件meta信息(包括整個文件的統計信息)、所有stripe的信息和文件schema信息。
stripe:一組行形成一個stripe,每次讀取文件是以行組為單位的,一般為HDFS的塊大小,保存了每一列的索引和數據。
stripe元數據:保存stripe的位置、每一個列的在該stripe的統計信息以及所有的stream類型和位置。
row group:索引的最小單位,一個stripe中包含多個row group,默認為10000個值組成。
stream:一個stream表示文件中一段有效的數據,包括索引和數據兩類。索引stream保存每一個row group的位置和統計信息,數據stream包括多種類型的數據,具體需要哪幾種是由該列類型和編碼方式決定。
在ORC文件中保存了三個層級的統計信息,分別為文件級別、stripe級別和row group級別的,他們都可以用來根據Search ARGuments(謂詞下推條件)判斷是否可以跳過某些數據,在統計信息中都包含成員數和是否有null值,並且對於不同類型的數據設置一些特定的統計信息。
讀取ORC文件是從尾部開始的,第一次讀取16KB的大小,盡可能的將Postscript和Footer數據都讀入內存。文件的最後一個位元組保存著PostScript的長度,它的長度不會超過256位元組,PostScript中保存著整個文件的元數據信息,它包括文件的壓縮格式、文件內部每一個壓縮塊的最大長度(每次分配內存的大小)、Footer長度,以及一些版本信息。在Postscript和Footer之間存儲著整個文件的統計信息(上圖中未畫出),這部分的統計信息包括每一個stripe中每一列的信息,主要統計成員數、最大值、最小值、是否有空值等。
接下來讀取文件的Footer信息,它包含了每一個stripe的長度和偏移量,該文件的schema信息(將schema樹按照schema中的編號保存在數組中)、整個文件的統計信息以及每一個row group的行數。
處理stripe時首先從Footer中獲取每一個stripe的其實位置和長度、每一個stripe的Footer數據(元數據,記錄了index和data的的長度),整個striper被分為index和data兩部分,stripe內部是按照row group進行分塊的(每一個row group中多少條記錄在文件的Footer中存儲),row group內部按列存儲。每一個row group由多個stream保存數據和索引信息。每一個stream的數據會根據該列的類型使用特定的壓縮演算法保存。在ORC中存在如下幾種stream類型:
PRESENT:每一個成員值在這個stream中保持一位(bit)用於標示該值是否為NULL,通過它可以只記錄部位NULL的值
DATA:該列的中屬於當前stripe的成員值。
LENGTH:每一個成員的長度,這個是針對string類型的列才有的。
DICTIONARY_DATA:對string類型數據編碼之後字典的內容。
SECONDARY:存儲Decimal、timestamp類型的小數或者納秒數等。
ROW_INDEX:保存stripe中每一個row group的統計信息和每一個row group起始位置信息。
在初始化階段獲取全部的元數據之後,可以通過includes數組指定需要讀取的列編號,它是一個boolean數組,如果不指定則讀取全部的列,還可以通過傳遞SearchArgument參數指定過濾條件,根據元數據首先讀取每一個stripe中的index信息,然後根據index中統計信息以及SearchArgument參數確定需要讀取的row group編號,再根據includes數據決定需要從這些row group中讀取的列,通過這兩層的過濾需要讀取的數據只是整個stripe多個小段的區間,然後ORC會盡可能合並多個離散的區間盡可能的減少I/O次數。然後再根據index中保存的下一個row group的位置信息調至該stripe中第一個需要讀取的row group中。
ORC文件格式只支持讀取指定欄位,還不支持只讀取特殊欄位類型中的指定部分。
使用ORC文件格式時,用戶可以使用HDFS的每一個block存儲ORC文件的一個stripe。對於一個ORC文件來說,stripe的大小一般需要設置得比HDFS的block小,如果不這樣的話,一個stripe就會分別在HDFS的多個block上,當讀取這種數據時就會發生遠程讀數據的行為。如果設置stripe的只保存在一個block上的話,如果當前block上的剩餘空間不足以存儲下一個strpie,ORC的writer接下來會將數據打散保存在block剩餘的空間上,直到這個block存滿為止。這樣,下一個stripe又會從下一個block開始存儲。
由於ORC中使用了更加精確的索引信息,使得在讀取數據時可以指定從任意一行開始讀取,更細粒度的統計信息使得讀取ORC文件跳過整個row group,ORC默認會對任何一塊數據和索引信息使用ZLIB壓縮,因此ORC文件佔用的存儲空間也更小,這點在後面的測試對比中也有所印證。
㈩ HDFS文件
Hadoop支持的文件系統由很多(見下圖),HDFS只是其中一種實現。java抽象類 org.apache.hadoop.fs.FileSystem 定義了Hadoop中一個文件系統的客戶端介面,並且該抽象類有幾個具體實現。Hadoop一般使用URI(下圖)方案來選取合適的文件系統實例進行交互。
特別的,HDFS文件系統的操作可以使用 FsSystem shell 、客戶端(http rest api、Java api、C api等)。
FsSystem shell 的用法基本同本地shell類似,命令可參考 FsSystem shell
Hadoop是用Java寫的,通過Java Api( FileSystem 類)可以調用大部分Hadoop文件系統的交互操作。更詳細的介紹可參考 hadoop Filesystem 。
非Java開發的應用可以使用由WebHDFS協議提供的HTTP REST API,但是HTTP比原生的Java客戶端要慢,所以不到萬不得已盡量不要使用HTTP傳輸特大數據。通過HTTP來訪問HDFS有兩種方法:
兩種如圖
在第一種情況中,namenode和datanode內嵌的web服務作為WebHDFS的端節點運行(是否啟用WebHDFS可通過dfs.webhdfs.enabled設置,默認為true)。文件元數據在namenode上,文件讀寫操作首先被發往namenode,有namenode發送一個HTTP重定向至某個客戶端,指示以流的方式傳輸文件數據的目的或源datanode。
第二種方法依靠一個或多個獨立代理伺服器通過HTTP訪問HDFS。所有集群的網路通信都需要通過代理,因此客戶端從來不直接訪問namenode或datanode。使用代理後可以使用更嚴格的防火牆策略和帶寬策略。
HttpFs代理提供和WebHDFS相同的HTTP介面,這樣客戶端能夠通過webhdfs URI訪問介面。HttpFS代理啟動獨立於namenode和datanode的守護進程,使用httpfs.sh 腳本,默認在一個不同的埠上監聽(14000)。
下圖描述了
讀文件時客戶端與 HDFS 中的 namenode, datanode 之間的數據流動。
對上圖的解釋如下:
在讀取過程中, 如果 FSDataInputStream 在和一個 datanode 進行交流時出現了一個錯誤,他就去試一試下一個最接近的塊,他當然也會記住剛才發生錯誤的 datanode 以至於之後不會再在這個 datanode 上進行沒必要的嘗試。 DFSInputStream 也會在 datanode 上傳輸出的數據上核查檢查數(checknums).如果損壞的塊被發現了, DFSInputStream 就試圖從另一個擁有備份的 datanode 中去讀取備份塊中的數據。
在這個設計中一個重要的方面就是客戶端直接從 datanode 上檢索數據,並通過 namenode 指導來得到每一個塊的最佳 datanode。這種設計允許 HDFS 擴展大量的並發客戶端,因為數據傳輸只是集群上的所有 datanode 展開的。期間,namenode 僅僅只需要服務於獲取塊位置的請求(塊位置信息是存放在內存中,所以效率很高)。如果不這樣設計,隨著客戶端數據量的增長,數據服務就會很快成為一個瓶頸。
我們知道,相對於客戶端(之後就是 maprece task 了),塊的位置有以下可能性:
我們認為他們對於客戶端的帶寬遞減,距離遞增(括弧中表示距離)。示意圖如下:
如果集群中的機器都在同一個機架上,我們無需其他配置,若集群比較復雜,由於hadoop無法自動發現網路拓撲,所以需要額外配置網路拓撲。
基本讀取程序,將文件內容輸出到console
FileSystemCat
隨機讀取
展開原碼
下圖描述了寫文件時客戶端與 HDFS 中的 namenode, datanode 之間的數據流動。
對上圖的解釋如下:
如果在任何一個 datanode 在寫入數據的時候失敗了,接下來所做的一切對客戶端都是透明的:首先, pipeline 被關閉,在確認隊列中的剩下的包會被添加進數據隊列的起始位置上,以至於在失敗的節點下游的任 何節點都不會丟失任何的包。然後與 namenode 聯系後,當前在一個好的 datanode 會聯系 namenode, 給失敗節點上還未寫完的塊生成一個新的標識ID, 以至於如果這個失敗的 datanode 不久後恢復了,這個不完整的塊將會被刪除。失敗節點會從 pipeline 中移除,然後剩下兩個好的 datanode 會組成一個的新的 pipeline ,剩下的 這些塊的包(也就是剛才放在數據隊列隊首的包)會繼續寫進 pipeline 中好的 datanode 中。最後,namenode 注意到塊備份數小於規定的備份數,他就安排在另一個節點上創建完成備份,直接從已有的塊中復制就可以。然後一直到滿足了備份數( dfs.replication )。如果有多個節點的寫入失敗了,如果滿足了最小備份數的設置( dfs.namenode.repliction.min ),寫入也將會成功,然後剩下的備份會被集群非同步的執行備份,直到滿足了備份數( dfs.replication )。
創建目錄
文件壓縮有兩大好處:
Hadoop 對於壓縮格式的是自動識別。如果我們壓縮的文件有相應壓縮格式的擴展名(比如 lzo,gz,bzip2 等)。Hadoop 會根據壓縮格式的擴展名自動選擇相對應的解碼器來解壓數據,此過程完全是 Hadoop 自動處理,我們只需要確保輸入的壓縮文件有擴展名。
Hadoop中有多種壓縮格式、演算法和工具,下圖列出了常用的壓縮方法。
表中的「是否可切分」表示對應的壓縮演算法是否支持切分,也就是說是否可以搜索數據流的任意位置並進一步往下讀取數據,可切分的壓縮格式尤其適合MapRece。
所有的壓縮演算法都需要權衡空間/時間:壓縮和解壓縮速度更快,其代價通常是只能節省少量的空間。不同的壓縮工具有不同的特性:
更詳細的比較如下
1.壓縮性能比較
2.優缺點
另外使用hadoop原生(native)類庫比其他java實現有更快的壓縮和解壓縮速度。特徵比較如下:
使用容器文件格式結合壓縮演算法也能更好的提高效率。順序文件、Arvo文件、ORCFiles、Parqurt文件同時支持壓縮和切分。
壓縮舉例(Java)
壓縮
解壓縮
六、文件序列化
序列化是指將結構化數據轉換為位元組流以便在網路上傳輸或寫到磁碟進行永久存儲。反序列化獅子將位元組流轉換回結構化對象的逆過程。
序列化用於分布式數據處理的兩大領域:進程間通信和永久存儲。
對序列化的要求時是格式緊湊(高效使用存儲空間)、快速(讀寫效率高)、可擴展(可以透明地讀取老格式數據)且可以互操作(可以使用不同的語言讀寫數據)。
Hadoop使用的是自己的序列化格式 Writable ,它絕對緊湊、速度快,但不太容易用java以外的語言進行擴展或使用。
當然,用戶也可以使用其他序列化框架或者自定義序列化方式,如 Avro 框架。
Hadoop內部還使用了 Apache Thrift 和 Protocal Buffers 來實現RPC和數據交換。