免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
HBase 數據文件在HDFS上的存儲

HBase 數據文件在HDFS上的存儲

517人閱讀評論(0)收藏舉報

 

英文原文:http://www.larsgeorge.com/2010/05/hbase-file-locality-in-hdfs.html

 

HDFS上面最不明確的事情之一就是數據的冗余。它完全是自動進行的,因為無法得知其中詳細的信息,我們需要做的就是相信它。HBase完全相信HDFS存儲數據的安全性和完整性,并將數據文件交給HDFS存儲。正是因為HDFS的數據冗余方式對于HBase來說是完全透明的,產生了一個問題:HBase的效率會受到多大的影響?說的簡單一點,當HBase需要存取數據時,如何保證有一份冗余的數據塊離自己最近?當我們對HBase做一次MapReduce的掃描操作時,這個問題尤其顯現出來。所有的RegionServer都在從HDFS上面讀取數據,理想的狀況當然是每個RegionServer要讀取的數據都離自己很近。這個問題就牽扯到HBase的數據文件是如何在HDFS上面存儲的。

讓我們首先拋開HBase,假設要處理的數據就是HDFS上面的數據塊,看看Hadoop是如何工作的。MapReduce總是有一個建議,那就是在每個TaskTracker上面Map/Reduce程序要處理的數據在本地就有一份冗余。這樣程序只需要與本地數據交互,減少了網絡流量并提高了效率。為了做到這一點,HDFS會把大文件分割成很多小文件來存儲,我們稱之為數據塊(Block)。每個數據塊的大小比操作系統(tǒng)數據塊的大小要大得多,默認是64M,但通常我們選擇128M,或者某個更大的值(這取決與你的文件大小,最好你的單個文件大小總是大于一個數據塊)。在MapReduce中,每個數據塊會被分配給一個Task,這個Task就負責處理這個數據塊中的數據。所以數據塊越大,產生的Task就越少,需要mapper的數量就越少。Hadoop自己知道每個數據塊存儲的位置,這樣在任務分配的時候就可以直接在存儲數據塊的機器上啟動Task,或者選擇一個最近機器啟動Task。真是因為每個數據塊有多份冗余,使得Hadoop有更大的選擇空間。只要找到一份冗余符合條件就行了,不是嗎?這樣Hadoop就可以保證在MapReduce期間Task總是操作本地數據。

讓我們回到HBase,現在你已經理解了Hadoop是如何保證在MapReduce的過程中每個Task都盡量處理本地數據。如果你看過HBase的存儲架構你就會知道HBase只是簡單的將HFileWAL log存儲在HDFS上面。通過簡單的調用HDFSAPI來創(chuàng)建文件:FileSystem.create(Path path)。接下來你會關心兩件事情的效率:1)隨機的訪問 2)通過MapReduce掃描全表。我們當然希望當每個RegionServer讀取數據時存儲數據的數據塊就在本地。它能做到嗎?

第一種情況,你有兩個集群,一個集群裝Hadoop,另一個集群裝HBase,兩個集群是分隔開的,只有網線來傳輸數據。好了,討論到此為止,神也幫不了你。

第二種情況,你有一個大的集群,每臺機器都混裝了HadoopHBase,每個RegionServer上面都有一個DataNode(這是我們最希望看到的)。好,這樣的話RegionServer就具備了從本地讀取數據的前提。我們還剩下一個問題,如何保證每個RegionServer管理的Region所對應的HFileWAL log就存在本地的DataNode上面?設想一種情況,你對HBase創(chuàng)建了大量的數據,每個RegionServer都管理了各自的Region,這時你重啟了HBase,重啟了所有的RegionServer,所有的Region都會被隨機的分配給各個RegionServer,這種情況下你顯然無法保證我們希望的本地數據存儲。

在討論如何解決這個問題之前我們先強調一點:HBase不應該頻繁的被重啟,并且部署的架構不應該被頻繁的改變,這是能解決這個問題的一個基礎。寫入HDFS的文件都有一個特點,一旦寫入一個文件就無法更改(由于種種原因)。因此HBase會定期的將數據寫入HDFS中并生成一個新文件。這里有一個讓人驚奇的地方:HDFS足夠聰明,它知道如何將文件寫到最合適的地方。換句話說,它知道把文件放到什么地方使得RegionServer用起來最方便。如果想知道HDFS如何做到這一點,我們需要深入學習Hadoop的源代碼,看看前面提到的FileSystem.create(Path path) 具體是怎么工作的。

HDFS中實際調用的函數是:DistributedFileSystem.create(Path path), 他看起來是這個樣子的:

public FSDataOutputStream create(Path f) throwsIOException {

return create(f, true);

}

public FSDataOutputStream create(Path f,FsPermission permission, boolean overwrite, int bufferSize, short replication,long blockSize, Progressable progress) throws IOException {

  return newFSDataOutputStream(dfs.create(getPathName(f),permission, overwrite, replication, blockSize, progress, bufferSize),statistics);

}

其中dfs是一個連接到HDFS NameNodeDFSClient。當你向HDFS寫入數據的時候,數據都流過DFSClient.DFSOutputStream,DFSClient將這些數據收集,積攢到一定程度后,作為一個Block寫入到DataNode里面。

將一個Block寫到DataNode的過程都發(fā)生在DFSClient.DFSOutputStream.DataStreamer里面,它是一個運行在后臺的守護線程。注意,從現在開始我們將逐漸揭開解決問題的秘密方法。

在接收到一個Block以后,DataStreamer需要知道這個Block應該被寫到哪些DataNode上面,同時它也應該讓NameNode知道這個Block寫到了哪些DataNode上面。它的做法是聯絡NameNodeHi,我這里有一個文件的一個Block,請告訴我應該寫在哪些DataNode上面?

nodes =nextBlockOutputStream(src);

->

long startTime =System.currentTimeMillis();

lb =locateFollowingBlock(startTime);

block = lb.getBlock();

nodes = lb.getLocations();

->

return namenode.addBlock(src,clientName);

這時NameNode收到了一個添加Block的請求,它包含兩個參數:srcclientName

其中src標明了這個Block屬于哪個文件,clientName則是client端的名稱。

我們跳過一些簡單的步驟來看最重要的一步:

public LocatedBlockgetAdditionalBlock(String src, String clientName) throws IOException {

  ...

  INodeFileUnderConstruction pendingFile  = checkLease(src, clientName);

  ...

  fileLength =pendingFile.computeContentSummary().getLength();

  blockSize =pendingFile.getPreferredBlockSize();

  clientNode = pendingFile.getClientNode();

  replication =(int)pendingFile.getReplication();

 

  // choose targets for the new block tobeallocated.

  DatanodeDescriptor targets[] =replicator.chooseTarget(replication, clientNode, null, blockSize);

  ...

}

最重要的一步就是replicator.chooseTarget(),它的具體實現如下:

private DatanodeDescriptor chooseTarget(int numOfReplicas,DatanodeDescriptor writer, List<Node> excludedNodes, long blocksize, intmaxNodesPerRack, List<DatanodeDescriptor> results) {

 

  if (numOfReplicas == 0 || clusterMap.getNumOfLeaves()==0){

    return writer;

  }

 

  int numOfResults = results.size();

  boolean newBlock = (numOfResults==0);

  if (writer == null && !newBlock) {

    writer =(DatanodeDescriptor)results.get(0);

  }

 

  try {

    switch(numOfResults) {

    case 0:

      writer = chooseLocalNode(writer,excludedNodes, blocksize, maxNodesPerRack, results);

      if (--numOfReplicas == 0) {

        break;

      }

    case 1:

      chooseRemoteRack(1, results.get(0),excludedNodes, blocksize, maxNodesPerRack, results);

      if (--numOfReplicas == 0) {

        break;

      }

    case 2:

      if(clusterMap.isOnSameRack(results.get(0), results.get(1))) {

        chooseRemoteRack(1, results.get(0),excludedNodes, blocksize, maxNodesPerRack, results);

      } else if (newBlock) {

        chooseLocalRack(results.get(1),excludedNodes, blocksize, maxNodesPerRack, results);

      } else {

        chooseLocalRack(writer, excludedNodes,blocksize, maxNodesPerRack, results);

      }

      if (--numOfReplicas == 0) {

        break;

      }

    default:

      chooseRandom(numOfReplicas,NodeBase.ROOT, excludedNodes, blocksize, maxNodesPerRack, results);

    }

  } catch (NotEnoughReplicasException e) {

    FSNamesystem.LOG.warn("Not able toplace enough replicas, still in need of " + numOfReplicas);

  }

  return writer;

}

這段代碼很清楚的說明了整個的選擇過程,NameNode總是為第一份冗余優(yōu)先選擇本地節(jié)點作為存儲空間,對于第二份冗余,則是優(yōu)先選擇另一個機架的節(jié)點。如果前兩份冗余位于不同機架,第三份冗余偏向于選擇與第一份冗余相同的機架,否則選擇不同的機架。大于三份的冗余就聽天由命,隨機挑選節(jié)點了。

總結一下,基于當前的情況,每個Region Server運行的時間越長,那么數據的存儲地點就越穩(wěn)定,每個Region Server就能保證它要管理的數據在本地就有一份拷貝。這樣無論是Scan還是MapReduce都能達到效率的最優(yōu)化。

最后要說的是HBase Team正在致力于重新設計MasterServer分配Region的機制。新的設計能夠盡量保證每個Region被分配給擁有最多Region BlockRegion Server。這將能夠部分解決重啟RegionServer所帶來的問題。

本站僅提供存儲服務,所有內容均由用戶發(fā)布,如發(fā)現有害或侵權內容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
HBase學習之路 (二)HBase集群安裝
Hbase/Hdfs刪除節(jié)點
01-Hbase環(huán)境搭建、shell和API訪問實現
HBase工程師線上工作經驗總結
通過BulkLoad快速將海量數據導入到Hbase[Hadoop篇] – 過往記憶
HBase簡介
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯系客服!

聯系客服