日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

hdfs读写流程_深度探索Hadoop分布式文件系统(HDFS)数据读取流程

發布時間:2023/12/2 windows 57 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hdfs读写流程_深度探索Hadoop分布式文件系统(HDFS)数据读取流程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、開篇

Hadoop分布式文件系統(HDFS)是Hadoop大數據生態最底層的數據存儲設施。因其具備了海量數據分布式存儲能力,針對不同批處理業務的大吞吐數據計算承載力,使其綜合復雜度要遠遠高于其他數據存儲系統。

因此對Hadoop分布式文件系統(HDFS)的深入研究,了解其架構特征、讀寫流程、分區模式、高可用思想、數據存儲規劃等知識,對學習大數據技術大有裨益,尤其是面臨開發生產環境時,能做到胸中有數。

本文重點從客戶端讀取HDFS數據的角度切入,通過Hadoop源代碼跟蹤手段,層層撥開,漸漸深入Hadoop機制內部,使其讀取流程逐漸明朗化。

二、HDFS數據讀取整體架構流程

如上圖所示:描繪了客戶端訪問HDFS數據的簡化后整體架構流程。
  • 客戶端向hdfs namenode節點發送Path文件路徑的數據訪問的請求

  • Namenode會根據文件路徑收集所有數據塊(block)的位置信息,并根據數據塊在文件中的先后順序,按次序組成數據塊定位集合(located blocks),回應給客戶端

  • 客戶端拿到數據塊定位集合后,創建HDFS輸入流,定位第一個數據塊所在的位置,并讀取datanode的數據流。之后根據讀取偏移量定位下一個datanode并創建新的數據塊讀取數據流,以此類推,完成對HDFS文件的整個讀取。

三、Hadoop源代碼分析經過上述簡單描述,我們對客戶端讀取HDFS文件數據有了一個整體上概念,那么這一節,我們開始從源代碼跟蹤的方向,深度去分析一下HDFS的數據訪問內部機制。(一) ?namenode代理類生成的源代碼探索為什么我們要先從namenode代理生成說起呢?原因就是先了解清楚客戶端與namenode之間的來龍去脈,再看之后的數據獲取過程就有頭緒了。

1. 首先我們先從一個hdfs-site.xml配置看起

????dfs.client.failover.proxy.provider.fszx

????org.apache.hadoop.hdfs.server.namenode.ha.

????ConfiguredFailoverProxyProvider

配置中定義了namenode代理的提供者為ConfiguredFailoverProxyProvider。什么叫namenode代理?其實本質上就是連接namenode服務的客戶端網絡通訊對象,用于客戶端和namenode服務端的交流。

2. 分析ConfiguredFailoverProxyProvider

上圖是ConfiguredFailoverProxyProvider的繼承關系,頂端接口是FailoverProxyProvider,它包含了一段代碼:

??/**

???*?Get?the?proxy?object?which?should?be?used?until?the?next?failover?event

???*?occurs.

???*?@return?the?proxy?object?to?invoke?methods?upon

???*/

??public?ProxyInfo?getProxy();

這個方法返回的ProxyInfo就是namenode代理對象,當然客戶端獲取的ProxyInfo整個過程非常復雜,甚至還用到了動態代理,但本質上就是通過此接口拿到了namenode代理。

3. 此時類關系演化成如下圖所示:

上圖ProxyInfo就是namenode的代理類,繼承的子類NNProxyInfo就是具體指定是高可用代理類。

4. 那么費了這么大勁搞清楚的namenode代理,它的作用在哪里呢?

這就需要關注一個極為重要的對象DFSClient了,它是所有客戶端向HDFS發起輸入輸出流的起點,如下圖所示:上圖實線代表了真實的調用過程,虛線代表了對象之間的間接關系。我們可以看到DFSClient是一個關鍵角色,它由分布式文件系統對象(DistributeFileSystem)初始化,并在初始化中調用NameNodeProxiesClient等一系列操作,實現了高可用NNproxyInfo對象創建,也就是namenode代理,并最終作為DFSClient對象的一個成員,在創建數據流等過程中使用。(二) ?讀取文件流的深入源代碼探索

1. 首先方法一樣,先找一個切入口。建立從HDFS下載文件到本地的一個簡單場景,以下是代碼片段

……

//打開HDFS文件輸入流

input?=?fileSystem.open(new?Path(hdfs_file_path));

//創建本地文件輸出流

output?=?new?FileOutputStream(local_file_path);

//通過IOUtils工具實現數據流字節循環復制

IOUtils.copyBytes(input,?output,?4096,?true);

……

咱們再看看IOUtils的一段文件流讀寫的方法代碼。

/**

???*?Copies?from?one?stream?to?another.

???*?

???*?@param?in?InputStrem?to?read?from

???*?@param?out?OutputStream?to?write?to

???*?@param?buffSize?the?size?of?the?buffer?

???*/

??public?static?void?copyBytes(InputStream?in,?OutputStream?out,?int?buffSize)?

????throws?IOException?{

??????PrintStream?ps?=?out?instanceof?PrintStream??

???????(PrintStream)out?:?null;

??????byte?buf[]?=?new?byte[buffSize];

??????int?bytesRead?=?in.read(buf);

??????while?(bytesRead?>=?0)?{

??????out.write(buf,?0,?bytesRead);

??????if?((ps?!=?null)?&&?ps.checkError())?{

??????????throw?new?IOException("

??????????Unable?to?write?to?output?stream.");

??????}

??????bytesRead?=?in.read(buf);

????}

??}

這段代碼是個標準的循環讀取HDFS InputStream數據流,然后向本地文件OutputStream輸出流寫數據的過程。我們的目標是深入到HDFS InputStream數據流的創建和使用過程。

2. 接下來我們開始分析InputStream的產生過程,如下圖所示:

上圖實線代表了真實的調用過程,虛線代表了對象之間的間接關系。其代碼內部結構極為復雜,我用此圖用最簡化的方式讓我們能快速的理解清楚他的原理。我來簡單講解一下這個過程:
  • 第一步?

是DistributeFileSystem通過調用DFSClient對象的open方法,實現對DFSInputStream對象的創建,DFSInputStream對象是真正讀取數據塊(LocationBlock)以及與datanode交互的實現邏輯,是真正的核心類。
  • 第二步?

DFSClient在創建DFSInputStream的過程中,需要為其傳入調用namenode代理而返回的數據塊集合(LocationBlocks)。
  • 第三步

DFSClient創建一個裝飾器類HDFSDataInputStream,封裝了DFSInputStream,由裝飾器的父類FSDataInputStream最終返回給DistributeFileSystem,由客戶端開發者使用。

3. 最后我們再深入到數據塊讀取機制的源代碼上看看,如下圖所示:

上圖實線代表了真實的調用過程,虛線代表了對象之間的間接關系。實際的代碼邏輯比較復雜,此圖也是盡量簡化展現,方便我們理解。一樣的,我來簡單講解一下這個過程:
  • 第一步?

FSDataInputStream裝飾器接受客戶端的讀取調用對DFSInputStream對象進行read(...)方法調用。
  • 第二步?

DFSInputStream會調用自身的blockSeekTo(long offset)方法,一方面根據offset數據偏移量,定位當前是否要讀取新的數據塊(LocationBlock),另一方面新的數據塊從數據塊集合(LocationBlocks)中找到后,尋找最佳的數據節點,也就是Hadoop所謂的就近原則,先看看本機數據節點有沒有副本,再次根據網絡距離著就近獲取副本。
  • 第三步?

通過FSDataInputStream副本上數據塊(LocationBlock)構建BlockReader對象,它就是真正讀取數據塊的對象。BlockReader對象它有不同的實現,由BlockReaderFactory.build根據條件最優選擇具體實現,BlockReaderLocal和BlockReaderLocalLegacy(based on HDFS-2246)是優選方案,也是short-circuit block readers方案,相當于直接從本地文件系統讀數據了,若short-circuit因為安全等因素不可用,就會嘗試UNIX domain sockets的優化方案,再不行才考慮BlockReaderRemote建立TCP sockets的連接方案了。BlockReader的細節原理也非常值得深入一探究竟,下次我專門寫一篇針對BlockReader原理機制文章。四、結束非常感覺您能看完。下一篇我會對“Hadoop分布式文件系統(HDFS)數據寫入流程”做一篇深度探索分析。期盼您的關注。

總結

以上是生活随笔為你收集整理的hdfs读写流程_深度探索Hadoop分布式文件系统(HDFS)数据读取流程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。