hadoop hdfs文件系統分析,名字節點,數據節點之間的交互

 

看過的一些文章:php

hadoop頁面訪問 8088端口http://192.168.8.71:8088  html

hdfs頁面java

http://192.168.8.70:50070/dfshealth.html#tab-overviewnode

看過的文章地址:http://dongxicheng.org/mapreduce/how-to-improve-hadoop-stablility-and-performance/linux

http://blog.csdn.net/silentwolfyh/article/details/51570193web

reduce數量怎麼調整http://www.aboutyun.com/forum.php?mod=viewthread&tid=7613&page=2數據庫

http://www.aboutyun.com/thread-9659-1-1.htmlapache

 

http://www.aboutyun.com/thread-8927-1-1.html編程

http://blog.csdn.net/stark_summer/article/details/48494391json

 

 

windows eclipse運行mapreduce遇到權限問題該如何解決

 

http://www.aboutyun.com/thread-7660-1-1.html

 

 

 

 

 

mapreduce是hadoop的核心之一,mapreduce常常讓咱們產生各類困惑,咱們只是知道什麼是map,什麼是renduce,甚至咱們已經熟悉了mapreduce編程,可是內部的原理仍是不明白。
1.Shuffle的定義是什麼?

Shuffle描述着數據從map task輸出到reduce task輸入的這段過程

·  完整地從map task端拉取數據到reduce 端。

·  在跨節點拉取數據時,儘量地減小對帶寬的沒必要要消耗。

·  減小磁盤IO對task執行的影響。

MapReduce提供Partitioner接口,它的做用就是根據key或value及reduce的數量來決定當前的這對輸出數據最終應該交由哪一個reduce task處理。
2.map task與reduce task的執行是否在不一樣的節點上?
3.Shuffle產生的意義是什麼?
4.每一個map task都有一個內存緩衝區,存儲着map的輸出結果,當緩衝區快滿的時候須要將緩衝區的數據該如何處理?
5.在map task執行時,它是如何讀取HDFS的?
6.讀取的Split與block的對應關係多是什麼?
7.MapReduce提供Partitioner接口,它的做用是什麼?
8.溢寫是在什麼狀況下發生?
9.溢寫是爲何不影響往緩衝區寫map結果的線程?
10.當溢寫線程啓動後,須要對這80MB空間內的key作排序(Sort)。排序是MapReduce模型默認的行爲,這裏的排序也是對誰的排序?
11.哪些場景才能使用Combiner呢?

 

 

     若是client設置過Combiner,那麼如今就是使用Combiner的時候了。將有相同key的key/value對的value加起來,減小溢寫到磁盤的數據量。Combiner會優化MapReduce的中間結果,因此它在整個模型中會屢次使用。那哪些場景才能使用Combiner呢?從這裏分析,Combiner的輸出是Reducer的輸入,Combiner毫不能改變最終的計算結果。因此從個人想法來看,Combiner只應該用於那種Reduce的輸入key/value與輸出key/value類型徹底一致,且不影響最終結果的場景。好比累加,最大值等。Combiner的使用必定得慎重,若是用好,它對job執行效率有幫助,反之會影響reduce的最終結果。
12.Merge的做用是什麼?
13.reduce中Copy過程採用是什麼協議?
14.reduce中merge過程有幾種方式,與map有什麼類似之處?
15.溢寫過程當中若是有不少個key/value對須要發送到某個reduce端去,那麼如何處理這些key/value值

問題導讀:
1、什麼是MapReduce
2MapperReducer實現什麼工做內容?
3、如何進行MapReduce性能調優?

 

 

 

 

 

hadoop學習

 

google file ystem Doug cutting等在Nutch項目上應用gfs和mapreduce思想,演化出hadoop項目,

提到了lucene和nutch項目,lucene是引擎開發工具包,nutch還有數據抓取功能,

狹義的hadoop包括hadoop common,hadoop hdfs和hadoop mapreduce三個子項目,可是想相關的還包括Avro,ZooKeeper,Hive,Pig,HBase,還有其餘互補的軟件項目。

zookeeper用來解決分佈式計算中的一致性問題。

 

 

hadoop配置信息處理

配置文件,

在操做系統中,有ini配置文件,裏面有節[],項和值

在java properties文件中沒有分類節 ,繼承自hashtable;

 

Hadoop Configuration 管理配置文件:xml格式;根元素是configuration,通常只包含子元素property,每一個property元素就是一個配置項

 

合併資源是將多個配置文件合併,併產生一個配置;經過Configuration類的addResources()方法,合併成一個配置文件。

hadoop配置系統還有一個屬性擴展${hadoop.tmp.dir}/dfs/name, ${hadoop.tmp.dir}會用Configuration中的相應屬性進行擴展

 

使用configuaration的通常過程是:用addResource()方法添加須要加載的資源,而後經過get,set….對資源進行操做。

 

getProps方法中,採用了延遲加載的設計模式,當真正須要配置數據的時候,纔開始分析配置文件

 

 

配置文件有windows的ini配置文件,有java的properties文件,properties文件也能夠用方法保存爲xml,也能夠從xml中讀成properties,j2se1.5版本之後,Properties中的數據也能夠用xml格式保存,對應的加載和寫入方法分別是loadFomXML和storeToXML(),

 

hadoop使用dom處理xml文件,由於文件小。能夠所有加載到內存後,再進行解析。

Configurable接口位於org.apache.hadoop.conf包中

 

 

序列化與壓縮

對象的序列化(Serialization)是用於將對象編碼成一個字節流,以及從字節流中從新構建對象。「將一個對象編碼成一個字節流」稱爲序列化該對象;相反的過程稱爲反序列化。

文本->對象 序列化

對象->文本 反序列化

 

序列化主要有三種用途:

做爲一種持久化的格式

做爲一種通訊數據格式,序列化結果能夠從一個正在運行的虛擬機,經過網絡被傳輸到另外一個虛擬機上。

做爲拷貝和克隆的機制,到內存緩存區,獲得新拷貝的對象

 

Serializable接口是一個標誌,不具備任何成員函數

public interface Serializable{}

 

ObjectOutputStream對象,對java自定義類,和基本類型的序列化

ObjectInputStream對象

 

 

java序列化機制

hadoop序列化機制

hadoop writable機制

 

RawCompatator和WritableComparable接口

 

 

 

 

hadoop序列化框架

Avro

Thrift

Google Protocol Buffer

Hadoop提供了一個簡單的序列化框架API,集成各類序列化的實現,該框架由 Serialization實現(org.apache.hadoop.io.serializer包中)

 

 

數據壓縮每每是計算密集型的操做,考慮到性能,建議使用本地庫,Java本地方法就是一個不錯的選擇,java提供了一些鉤子程序,使得調用本地方法成爲了可能,本地方法是類的成員方法。

 

org.apace.hadoop.io序列化和壓縮

 

 

 

 

 

Hadoop遠程過程調用

遠程調用如何隱藏底層通訊的細節

 

xml-rpc json-rpc

 

hadoop-ipc

 

常規的過程調用,歸納了進程的控制流同步模型

RPC跨越了不一樣的進程

theClinet and theServer

 

 

 

 

請求參數保存在棧中,調用方法,從棧中取得參數,肯定調用過程當中的名字並調用相應的過程,調用結束後,返回值經過主程序打包併發送給客戶端,通知客戶端調用結束

 

 

實現RPC須要關心下面三個問題

RPC的語法應該與高級程序設計語言中的本地過程調用語法有相同的外觀;

RPC和本地調用的語義儘量相似,如參數傳遞中包含的語義

Rpc接收者應該如同一個傳統的調用。

 

RPC引入了客戶存根和服務器骨架。

服務器骨架和客戶端存根是等價物,用來將經過網絡的輸入請求轉爲本地調用。調用結束後,由骨架打包成消息發送到客戶端存根,存根經過return將結果返回到主程序中,

RPC經過接口定義語言IDL描述調用接口的相關信息,定義信息包含類型定義,常量聲明,參數傳遞信息和註釋。

 

 

 

java遠程方法調用是一個Java的一個核心API和類庫。容許一個java虛擬機上運行的java程序調用不一樣虛擬機上運行的對象中的方法,RMI能夠當作是RPC的java升級版。包含RMI的java程序包含服務程序和客戶端程序,服務器應用程序將建立多個遠程對象,使這些對象可以被客戶端引用。標準的Stub/Skeleton機制

Stub表明被客戶端引用的遠程對象,並保存着遠程對象的接口和方法列表,位於客戶端;服務端的Skeleton對象處理有關調用「遠方」對象中的全部細節。

 

 

public class RMIQueryStatusImpl extends UnicastRemoteObject implements RMIQueryStatus

 

客戶端要訪問遠程對象必須得到一個本地的存根對象。

如何得到存根對象呢?java中用RMI遠程對象註冊點(Registry)解決了這個問題

 

一個Rmi典型的存根包含哪些成員。

 

Java動態代理

java.lang.reflect包下,主要包含java.lang.relflect.Proxy和java.lang.reflect.InvocationHandler

 

反射,代理

反射,便於編寫可以動態操做java代碼的程序

 

 

 

 

 

 

 

函數seek()來自org.apache.hadoop.fs.Seekable接口,提供在輸入流中進行定位的能力。

「cre/0」是校驗文件的魔數(Magic NUmber)

Arrays.equals(a,b)

 

ChecksumException

 

數據完整性是海量數據處理中的一個重要問題。不但hadoop Common中的文件系統提供了ChecksumFileSystem,在hadoop分佈式文件系統中也實現了相似的機制。

 

 

RawLocalFileSystem和ChecksumFileSystem並無實現一個真正的文件系統,必須依賴一個已有的文件系統。

 

RawInMemoryFileSystem不依賴任何文件系統,十分簡單,內存文件系統RawInMemeryFileSystem

內存文件系統它部分實現了抽象類org.apache.hadoop.fs.FileSystem中 要求的API及簡單的輸入/輸出流。

InMemoryFileSystem內部類RawInMemoryFileSystem,內存文件系統沒有目錄,全部文件都以映射表的形式保存在系統中,映射表的鍵是文件名,映射表對應的值是FileAttribues對象,它包含預留空間和該空間大小的信息;這樣的映射表有兩個,一個保存正在產生的文件tempFileAttribs中,經過映射表這樣的文件結構將數據保存在了內存中。

 

public class FileAttributes {

  private byte[] data;// 保存數據

  private int size; // 保存大小

 

  public FileAttributes(int size) {

     this.size = size;

     this.data = new byte[size];

  }

}

 

 

 

HDFS

   超大文件,硬件故障,流式數據訪問,簡化一致性,一次寫入,屢次讀取,簡化可一致性模型,提升了吞吐量;大量的小文件會影響名字節點的性能。

 

HDFS體系結構

主從:名字節點,數據節點,客戶端Client

數據塊:塊的大小表明系統讀寫操做的最小單位,LinuxExt3文件系統中,塊大小默認爲4096字節

默認HDFS數據塊的大小是64mb,減小須要管理數據塊須要的開銷,減小創建網絡鏈接須要的成本。

名字節點維護着整個文件系統的文件目錄樹,文件/目錄的元信息和文件的數據塊索引,即每一個文件對應的數據塊列表;

這些信息以兩種形式存儲在本地文件系統中:一種是命名空間鏡像FSImage,另外一種是命名空間鏡像的編輯日誌(EditLog).

空間鏡像保存着某一特定時刻HDFS的目錄樹,元信息和數據塊索引等信息,對這些信息的改動,則保存在編輯日誌中;

 

第二名字節點用於按期合併命名空間鏡像和鏡像編輯日誌的輔助守護進程,它不接收或者記錄HDFS的任何實時變化,而是間隔不停的得到HDFS某一時間點的命名空間鏡像和鏡像的編輯日誌,合併獲得一個新的命名空間鏡像,該鏡像會上傳到名字節點,替換原有的命名空間鏡像,並清除上述日誌。應該說,第二名字節點配合名字節點,爲名字節點上的名字節點第一關係提供一個檢查點機制Checkpoint,避免編輯日誌過大,致使名字節點啓動時間過長的問題。

 

第二名字節點能夠減小停機的時間並減低名字節點元數據丟失的風險,名字節點失效不行。

 

 

 

 

數據節點上都會有一個守護進程,將HDFS數據塊寫到linux本地文件系統的實際文件中,或者從實際文件中讀取數據庫。

數據節點會和其餘數據節點通訊,複製數據塊,保證數據的冗餘性。

客戶端是HDFS和用戶交互的手段,JAVAAPI,命令行,其餘類庫等等。。

 

                               hdfs.web

hdfs.server.namenode.web.resources hdfs.server.datanode.web.resources

       hdfs.web.resources

hdfs.tools  hdfs.server.balancer

                      

 

 

hdfs       hdfs.server.namenode     hdfs.server.datanode

hdfs.protocal    hdfs.server.common

hdfs.server.namenode.metrics  hdfs.server.datanode.metrics

 

 

 

 

 

hdfs.util    hdfs.security.token.bloacl   hdfs.security.token.do….

     

 

 

 

 

hadoop遠程調用接口

基於tcp和http的流式接口

 

 

版本號用來維護具備相同數據塊標識的數據的一致性

數據塊的id號<id>, name爲blk_<id>

 

LocatedBlock已經確認存儲位置的數據塊

 

數據節點標識datanodeID用於在HDFS中肯定一個數據節點,

 

 

經過create()建立文件時,ClientProtocal的成員函數addBlock()用於爲當前客戶端打開的文件添加一個數據塊。當用戶建立一個新文件,或者寫滿一個數據塊後,客戶端就會調用這個方法,向名字節點申請一個新的數據塊。

 

在linux中,大多數磁盤IO操做都會經過內核緩存區,若是緩存區還沒有寫滿,則不會發生實際的io操做,這種機制叫作延遲寫,它的優勢是減小了磁盤io操做的次數,但缺點是一旦系統出故障,可能會丟失那些在緩存區但未被寫進磁盤的文件數據。

 

public class BlockCommand extends DatanodeCommand{

        

         Block blocks[]; //包含了blockCommand命令具體涉及的數據塊

         DatanodeInfo targets[][];//是一個類型爲DatanodeInfo的二維數組,用於數據塊複製和數據塊恢復

}

 

 

 

namenodeProtocal

調用者有兩個,一個是第二名字節點,另外一個是hdfs工具:均衡器balancer

 

 

balancer能夠把數據塊從改數據節點移動到其餘數據節點,達到平衡各個數據節點數據塊數量的目的;

第二名字節點的功能:獲取hdfs命名空間鏡像和鏡像編輯日誌,合併到一個新的鏡像,上傳新命名空間鏡像到名字節點,替換原有鏡像並清空鏡像編輯日誌。

 

hdfs寫數據的數據流管道:

GFS寫一份數據的多個副本時,能夠充分利用集羣中每一臺機器的寬帶。

首先推送到一個節點,而後再向下一個節點推送。

流式接口:

 

fsimage,edits文件

 

hadoop的各個節點都嵌入了Jetty,是一個web容器,實現了java的http servlet規範,

用http協議來交換數據,

${dfs.data.dir}

 

 

數據節點的實現

 

一個目錄下最多隻有64個數據塊(128個文件)和64個目錄。

數據存儲DataStorage和文件系統數據集FSDataset.

StorageDirectory

Storage

DataStorage

數據節點第一次啓動的時候,會調用DataStorage.format()建立存儲目錄結果。

 

Storage和DataStorage一塊兒提供了一個完美的HDFS數據節點升級機制,簡化了大型分佈式系統的運維,它們不但解決了系統升級過程當中數據格式的轉化,升級回滾等常見的問題,並保證了這個過程不會丟失數據;同時,特別是Storage狀態機,以及配合狀態機工做的臨時文件,提供了完整的升級方案。在升級過程或者回滾的過程當中任何一個步驟出現錯誤,均可以經過狀態機,恢復到正常狀態。

 

 

文件系統數據集的工做機制

FSVolume是數據目錄配置項${dfs.data.dir}中的一項。

ongoingCreates是文件塊Block對象到ActiveFile對象的映射,ActiveFile是活躍文件,它保存着處於寫狀態的數據塊的一些附加信息。

 

 

 

數據節點和名字節點的交互

數據節點到名字節點的握手,註冊,數據庫上報和心跳;

 

名字節點保存並持久化了整個文件系統的文件目錄樹以及文件的數據塊索引,但名字節點不持久化數據庫的保存位置。HDFS啓動時,數據節點會按期上報它上面保存的數據塊信息。心跳上報過程當中,數據節點會發送可以描述當前節點負載的一些信息,如數據節點儲存的容量,目前已使用的容量等,名字節點會根據這些信息估計數據節點的工做狀態。

DataBlockScanner對數據塊進行校驗,

數據節點的啓停

DataNode.main()是數據節點的入口方法,但只作一件事 sercureMain()方法,它經過createDataNode()建立並啓動數據節點,而後經過dataNode對象的join()方法等待數據節點中止運行。

       public static void main(String args[]) {

              secureMain(args, null);

       }

 

       public static void secureMain(String[] args, SecureResources resources) {

              try {

                     // ...todo something

                     DataNode datanode = createDataNode(args, null, resources);

                     if (datanode != null) {

                            datanode.join();

                     }

                     // do something....

              } finally {

              }

       }

 

       public static DataNode createDataNode(String args[], Configuration conf, SecureResources resources)

                     throws Exception {

              DataNode dn = instanntiateDataNode(args, conf, resources);

              runDatanodeDaemon(dn);

              return dn;

 

       }

 

 

名字節點的實現

hdfs的文件目錄樹,以及文件的數據塊索引,即每一個文件對應的數據塊列表

數據塊和數據節點的對應關係。某個數據塊保存在哪些數據節點的信息

文件系統

主要考慮文件和目錄如何存儲

linux中的i-node,索引節點,INode,INodeFile,INodeDirectory

命名空間鏡像和編輯日誌

文件目錄由INode和其子類保存,若是節點掉電,數據將再也不存在,所以必須將信息保存到磁盤,鏡像將保存某一時刻目錄樹的信息,它在HDFS中實現爲FSImage,名字節點把命名空間鏡像和編輯日誌保存在current目錄下,

 

 

遠程調用過程

 

 

 

 

 
 

while(1){

msg=receive(anyClient)

unpack(msg,t1)

unoack(msg,t2)

unpack(msg,t3)

unpack(msg,tn)

func(t1,t2,…,tn)

pack(retMsg,a1)

pack(retMsg,an)

pack(retMsg,an)

send(theClient,retMsg)

 

}

相關文章
相關標籤/搜索