精华内容
下载资源
问答
  • hdfs副本存放策略
    千次阅读
    2017-02-19 20:28:50

    第一个block副本放在和client所在的node里(如果是集群外提交,则随机挑选一台磁盘不太慢、CPU不太忙的节点上)。
    第二个副本放置在与第一个节点不同的机架中的node中(随机选择)。
    第三个副本和第二个在同一个机架,随机放在不同的node中。
    如果还有更多的副本就随机放在集群的node里。

    这里写图片描述
    流水线复制
    当客户端向 HDFS 文件写入数据的时候,一开始是写到本地临时文件中。
    假设该文件的副本系数设置为 3 ,当本地临时文件累积到一个数据块的大小时,客户端会从 Namenode 获取一个 Datanode 列表用于存放副本。然后客户端开始向第一个Datanode传输数据,第一个 Datanode 一小部分一小部分 (4 KB) 地接收数据,将每一部分写入本地仓库,并同时传输该部分到列表中第二个 Datanode 节点。第二个 Datanode 也是这样,一小部分一小部分地接收数据,写入本地仓库,并同时传给第三个 Datanode 。最后,第三个 Datanode 接收数据并存储在本地。因此,Datanode 能流水线式地从前一个节点接收数据,并同时转发给下一个节点,数据以流水线的方式从前一个Datanode复制到下一个Datanode。

    注: 修改副本数 修改hdfs-site.xml中dfs.replication配置项

    更多相关内容
  • HDFS副本存放策略(官方文档)

    千次阅读 2020-06-02 12:39:39
    HDFS副本存放策略(权威官方文档) 关于HDFS的副本位置默认存放策略(以3个副本为例),网络上一直流传着两种说法; 第一种说法: 副本1:在client端所处的节点(就近),若客户端在集群外则随机选一个; 副本2:和...

    HDFS副本存放策略(官方文档)

    关于HDFS的副本位置默认存放策略(以3个副本为例),网络上一直流传着两种说法;

    第一种说法:

    副本1:在client端所处的节点(就近),若客户端在集群外则随机选一个;
    副本2:和第一个副本位于相同机架的不同节点上;
    副本3:跨机架随机挑选一个节点,增加副本的可靠性;

    第二种说法:

    副本1:在client端所处的节点(就近),若客户端在集群外则随机选一个DataNode;
    副本2:和第一个副本位于不同机架的一个节点上;
    副本3:和第二个副本相同机架的不同节点上;

    看起来这两种说法好像都有道理(都保证了数据的可靠性和带宽的利用率),不知道应该以哪个为准,为了得到更加准确的答案,我查阅了一下Hadoop领域比较经典的书籍《Hadooop权威指南第4版》,原文如下:
    在这里插入图片描述
    在这里插入图片描述
    但是书中的内容可能并不是最新的内容,很有可能Hadoop官方更新了一部分内容,但是书籍还没来得及更新,所以我又在Hadoop的官网上找了一下,以下是官网原文(https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HdfsDesign.html):

    For the common case, when the replication factor is three, HDFS’s placement policy is to put one replica on the local machine if the writer is on a datanode, otherwise on a random datanode in the same rack as that of the writer, another replica on a node in a different (remote) rack, and the last on a different node in the same remote rack. This policy cuts the inter-rack write traffic which generally improves write performance. The chance of rack failure is far less than that of node failure; this policy does not impact data reliability and availability guarantees. However, it does reduce the aggregate network bandwidth used when reading data since a block is placed in only two unique racks rather than three. With this policy, the replicas of a file do not evenly distribute across the racks. One third of replicas are on one node, two thirds of replicas are on one rack, and the other third are evenly distributed across the remaining racks. This policy improves write performance without compromising data reliability or read performance.

    《Hadooop权威指南第4版》和官网原文相互印证,至此,我们基本可以得出结论,关于副本存放策略的说法,第一种是错误的,第二种是正确的。

    (至于为什么会有第一种说法的存在,一些网友给出的理由是版本问题,不同的Hadoop版本的副本分配策略也不同,但是我在官网上没有找到之前版本的分配策略,如果有哪位朋友知道为什么会有第一种说法的存在,欢迎留言讨论。)

    展开全文
  • HDFS副本存放策略

    2021-05-16 14:51:49
    HDFS作为Hadoop中的一个分布式文件...首先,HDFS将每一个文件的数据进行分块存储,同时每一个数据块又保存有多个副本,这些数据块副本分布在不同的机器节点上,这种数据分块存储+副本策略HDFS保证可靠性和性能的...

    HDFS作为Hadoop中的一个分布式文件系统,而且是专门为它的MapReduce设计,所以HDFS除了必须满足自己作为分布式文件系统的高可靠性外,还必须为MapReduce提供高效的读写性能,那么HDFS是如何做到这些的呢?首先,HDFS将每一个文件的数据进行分块存储,同时每一个数据块又保存有多个副本,这些数据块副本分布在不同的机器节点上,这种数据分块存储+副本的策略是HDFS保证可靠性和性能的关键,这是因为:一.文件分块存储之后按照数据块来读,提高了文件随机读的效率和并发读的效率;二.保存数据块若干副本到不同的机器节点实现可靠性的同时也提高了同一数据块的并发读效率;三.数据分块是非常切合MapReduce中任务切分的思想。在这里,副本的存放策略又是HDFS实现高可靠性和搞性能的关键。

    HDFS采用一种称为机架感知的策略来改进数据的可靠性、可用性和网络带宽的利用率。通过一个机架感知的过程,NameNode可以确定每一个DataNode所属的机架id(这也是NameNode采用NetworkTopology数据结构来存储数据节点的原因,也是我在前面详细介绍NetworkTopology类的原因)。一个简单但没有优化的策略就是将副本存放在不同的机架上,这样可以防止当整个机架失效时数据的丢失,并且允许读数据的时候充分利用多个机架的带宽。这种策略设置可以将副本均匀分布在集群中,有利于当组件失效的情况下的均匀负载,但是,因为这种策略的一个写操作需要传输到多个机架,这增加了写的代价。

    在大多数情况下,副本系数是3,HDFS的存放策略是将一个副本存放在本地机架节点上,一个副本存放在同一个机架的另一个节点上,最后一个副本放在不同机架的节点上。这种策略减少了机架间的数据传输,提高了写操作的效率。机架的错误远远比节点的错误少,所以这种策略不会影响到数据的可靠性和可用性。与此同时,因为数据块只存放在两个不同的机架上,所以此策略减少了读取数据时需要的网络传输总带宽。在这种策略下,副本并不是均匀的分布在不同的机架上:三分之一的副本在一个节点上,三分之二的副本在一个机架上,其它副本均匀分布在剩下的机架中,这种策略在不损害数据可靠性和读取性能的情况下改进了写的性能。下面就来看看HDFS是如何来具体实现这一策略的。

    NameNode是通过类来为每一分数据块选择副本的存放位置的,这个ReplicationTargetChooser的一般处理过程如下:

    047979f74084ae51b3d79d6a6f6cdbad.gif

    上面的流程图详细的描述了Hadoop-0.2.0版本中副本的存放位置的选择策略,当然,这当中还有一些细节问题,如:如何选择一个本地数据节点,如何选择一个本地机架数据节点等,所以下面我还将继续展开讨论。

    1.选择一个本地节点

    这里所说的本地节点是相对于客户端来说的,也就是说某一个用户正在用一个客户端来向HDFS中写数据,如果该客户端上有数据节点,那么就应该最优先考虑把正在写入的数据的一个副本保存在这个客户端的数据节点上,它即被看做是本地节点,但是如果这个客户端上的数据节点空间不足或者是当前负载过重,则应该从该数据节点所在的机架中选择一个合适的数据节点作为此时这个数据块的本地节点。另外,如果客户端上没有一个数据节点的话,则从整个集群中随机选择一个合适的数据节点作为此时这个数据块的本地节点。那么,如何判定一个数据节点合不合适呢,它是通过isGoodTarget方法来确定的:

    privatebooleanisGoodTarget(DatanodeDescriptor node,longblockSize,intmaxTargetPerLoc,booleanconsiderLoad, List results) {

    Log logr = FSNamesystem.LOG;

    // 节点不可用了

    if(node.isDecommissionInProgress() || node.isDecommissioned()) {

    logr.debug("Node "+NodeBase.getPath(node)+" is not chosen because the node is (being) decommissioned");

    returnfalse;

    }

    longremaining = node.getRemaining() - (node.getBlocksScheduled() * blockSize);

    // 节点剩余的容量够不够

    if(blockSize* FSConstants.MIN_BLOCKS_FOR_WRITE>remaining) {

    logr.debug("Node "+NodeBase.getPath(node)+" is not chosen because the node does not have enough space");

    returnfalse;

    }

    // 节点当前的负载情况

    if(considerLoad) {

    doubleavgLoad =0;

    intsize = clusterMap.getNumOfLeaves();

    if(size !=0) {

    avgLoad = (double)fs.getTotalLoad()/size;

    }

    if(node.getXceiverCount() > (2.0* avgLoad)) {

    logr.debug("Node "+NodeBase.getPath(node)+" is not chosen because the node is too busy");

    returnfalse;

    }

    }

    // 该节点坐在的机架被选择存放当前数据块副本的数据节点过多

    String rackname = node.getNetworkLocation();

    intcounter=1;

    for(Iterator iter = results.iterator(); iter.hasNext();) {

    Node result = iter.next();

    if(rackname.equals(result.getNetworkLocation())) {

    counter++;

    }

    }

    if(counter>maxTargetPerLoc) {

    logr.debug("Node "+NodeBase.getPath(node)+" is not chosen because the rack has too many chosen nodes");

    returnfalse;

    }

    returntrue;

    }2.选择一个本地机架节点

    实际上,选择本地节假节点和远程机架节点都需要以一个节点为参考,这样才是有意义,所以在上面的流程图中,我用红色字体标出了参考点。那么,ReplicationTargetChooser是如何根据一个节点选择它的一个本地机架节点呢?

    这个过程很简单,如果参考点为空,则从整个集群中随机选择一个合适的数据节点作为此时的本地机架节点;否则就从参考节点所在的机架中随机选择一个合适的数据节点作为此时的本地机架节点,若这个集群中没有合适的数据节点的话,则从已选择的数据节点中找出一个作为新的参考点,如果找到了一个新的参考点,则从这个新的参考点在的机架中随机选择一个合适的数据节点作为此时的本地机架节点;否则从整个集群中随机选择一个合适的数据节点作为此时的本地机架节点。如果新的参考点所在的机架中仍然没有合适的数据节点,则只能从整个集群中随机选择一个合适的数据节点作为此时的本地机架节点了。

    privateDatanodeDescriptor chooseLocalRack(DatanodeDescriptor localMachine, List excludedNodes,longblocksize,intmaxNodesPerRack, List results)throwsNotEnoughReplicasException {

    // 如果参考点为空,则从整个集群中随机选择一个合适的数据节点作为此时的本地机架节点

    if(localMachine ==null) {

    returnchooseRandom(NodeBase.ROOT, excludedNodes, blocksize, maxNodesPerRack, results);

    }

    //从参考节点所在的机架中随机选择一个合适的数据节点作为此时的本地机架节点

    try{

    returnchooseRandom(localMachine.getNetworkLocation(), excludedNodes, blocksize, maxNodesPerRack, results);

    }catch(NotEnoughReplicasException e1) {

    //若这个集群中没有合适的数据节点的话,则从已选择的数据节点中找出一个作为新的参考点

    DatanodeDescriptor newLocal=null;

    for(Iterator iter=results.iterator(); iter.hasNext();) {

    DatanodeDescriptor nextNode = iter.next();

    if(nextNode != localMachine) {

    newLocal = nextNode;

    break;

    }

    }

    if(newLocal !=null) {//找到了一个新的参考点

    try{

    //从这个新的参考点在的机架中随机选择一个合适的数据节点作为此时的本地机架节点

    returnchooseRandom(newLocal.getNetworkLocation(), excludedNodes, blocksize, maxNodesPerRack, results);

    }catch(NotEnoughReplicasException e2) {

    //新的参考点所在的机架中仍然没有合适的数据节点,从整个集群中随机选择一个合适的数据节点作为此时的本地机架节点

    returnchooseRandom(NodeBase.ROOT, excludedNodes, blocksize, maxNodesPerRack, results);

    }

    }else{

    //从整个集群中随机选择一个合适的数据节点作为此时的本地机架节点

    returnchooseRandom(NodeBase.ROOT, excludedNodes, blocksize, maxNodesPerRack, results);

    }

    }

    }3.选择一个远程机架节点

    选择一个远程机架节点就是随机的选择一个合适的不在参考点坐在的机架中的数据节点,如果没有找到这个合适的数据节点的话,就只能从参考点所在的机架中选择一个合适的数据节点作为此时的远程机架节点了。

    4.随机选择若干数据节点

    这里的随机随机选择若干个数据节点实际上指的是从某一个范围内随机的选择若干个节点,它的实现需要利用前面提到过的NetworkTopology数据结构。随机选择所使用的范围本质上指的是一个路径,这个路径表示的是NetworkTopology所表示的树状网络拓扑图中的一个非叶子节点,随机选择针对的就是这个节点的所有叶子子节点,因为所有的数据节点都被表示成了这个树状网络拓扑图中的叶子节点。

    5.优化数据传输的路径   以前说过,HDFS对于Block的副本copy采用的是流水线作业的方式:client把数据Block只传给一个DataNode,这个DataNode收到Block之后,传给下一个DataNode,依次类推,...,最后一个DataNode就不需要下传数据Block了。所以,在为一个数据块确定了所有的副本存放的位置之后,就需要确定这种数据节点之间流水复制的顺序,这种顺序应该使得数据传输时花费的网络延时最小。ReplicationTargetChooser用了非常简单的方法来考量的,大家一看便知:

    privateDatanodeDescriptor[] getPipeline( DatanodeDescriptor writer, DatanodeDescriptor[] nodes) {

    if(nodes.length==0)returnnodes;

    synchronized(clusterMap) {

    intindex=0;

    if(writer ==null|| !clusterMap.contains(writer)) {

    writer = nodes[0];

    }

    for(;index

    DatanodeDescriptor shortestNode = nodes[index];

    intshortestDistance = clusterMap.getDistance(writer, shortestNode);

    intshortestIndex = index;

    for(inti=index+1; i

    DatanodeDescriptor currentNode = nodes[i];

    intcurrentDistance = clusterMap.getDistance(writer, currentNode);

    if(shortestDistance>currentDistance) {

    shortestDistance = currentDistance;

    shortestNode = currentNode;

    shortestIndex = i;

    }

    }

    //switch position index & shortestIndex

    if(index != shortestIndex) {

    nodes[shortestIndex] = nodes[index];

    nodes[index] = shortestNode;

    }

    writer = shortestNode;

    }

    }

    returnnodes;

    }     可惜的是,HDFS目前并没有把副本存放策略的实现开放给用户,也就是用户无法根据自己的实际需求来指定文件的数据块存放的具体位置。例如:我们可以将有关系的两个文件放到相同的数据节点上,这样在进行map-reduce的时候,其工作效率会大大的提高。但是,又考虑到副本存放策略是与集群负载均衡休戚相关的,所以要是真的把负载存放策略交给用户来实现的话,对用户来说是相当负载的,所以我只能说Hadoop目前还不算成熟,尚需大踏步发展。0b1331709591d260c1c78e86d0c51c18.png

    展开全文
  • 首先,HDFS将每一个文件的数据进行分块存储,同时每一个数据块又保存有多个副本,这些数据块副本分布在不同的机器节点上,这种数据分块存储+副本策略HDFS保证可靠性和性能的关键,这是因为:一.文件分块存储之后...

    HDFS作为Hadoop中的一个分布式文件系统,而且是专门为它的MapReduce设计,所以HDFS除了必须满足自己作为分布式文件系统的高可靠性外,还必须为MapReduce提供高效的读写性能,那么HDFS是如何做到这些的呢?首先,HDFS将每一个文件的数据进行分块存储,同时每一个数据块又保存有多个副本,这些数据块副本分布在不同的机器节点上,这种数据分块存储+副本的策略是HDFS保证可靠性和性能的关键,这是因为:一.文件分块存储之后按照数据块来读,提高了文件随机读的效率和并发读的效率;二.保存数据块若干副本到不同的机器节点实现可靠性的同时也提高了同一数据块的并发读效率;三.数据分块是非常切合MapReduce中任务切分的思想。在这里,副本的存放策略又是HDFS实现高可靠性和搞性能的关键。

    ​ HDFS采用一种称为机架感知的策略来改进数据的可靠性、可用性和网络带宽的利用率。通过一个机架感知的过程,NameNode可以确定每一个DataNode所属的机架id(这也是NameNode采用NetworkTopology数据结构来存储数据节点的原因,也是我在前面详细介绍NetworkTopology类的原因)。一个简单但没有优化的策略就是将副本存放在不同的机架上,这样可以防止当整个机架失效时数据的丢失,并且允许读数据的时候充分利用多个机架的带宽。这种策略设置可以将副本均匀分布在集群中,有利于当组件失效的情况下的均匀负载,但是,因为这种策略的一个写操作需要传输到多个机架,这增加了写的代价。

    在大多数情况下,副本系数是3,HDFS的存放策略是将一个副本存放在本地机架节点上,一个副本存放在同一个机架的另一个节点上,最后一个副本放在不同机架的节点上。这种策略减少了机架间的数据传输,提高了写操作的效率。机架的错误远远比节点的错误少,所以这种策略不会影响到数据的可靠性和可用性。与此同时,因为数据块只存放在两个不同的机架上,所以此策略减少了读取数据时需要的网络传输总带宽。在这种策略下,副本并不是均匀的分布在不同的机架上:三分之一的副本在一个节点上,三分之二的副本在一个机架上,其它副本均匀分布在剩下的机架中,这种策略在不损害数据可靠性和读取性能的情况下改进了写的性能。下面就来看看HDFS是如何来具体实现这一策略的。

    ​ NameNode是通过类来为每一分数据块选择副本的存放位置的,这个ReplicationTargetChooser的一般处理过程如下:

    在这里插入图片描述

    上面的流程图详细的描述了Hadoop-0.2.0版本中副本的存放位置的选择策略,当然,这当中还有一些细节问题,如:如何选择一个本地数据节点,如何选择一个本地机架数据节点等,所以下面我还将继续展开讨论。

    1.选择一个本地节点
    这里所说的本地节点是相对于客户端来说的,也就是说某一个用户正在用一个客户端来向HDFS中写数据,如果该客户端上有数据节点,那么就应该最优先考虑把正在写入的数据的一个副本保存在这个客户端的数据节点上,它即被看做是本地节点,但是如果这个客户端上的数据节点空间不足或者是当前负载过重,则应该从该数据节点所在的机架中选择一个合适的数据节点作为此时这个数据块的本地节点。另外,如果客户端上没有一个数据节点的话,则从整个集群中随机选择一个合适的数据节点作为此时这个数据块的本地节点。那么,如何判定一个数据节点合不合适呢,它是通过isGoodTarget方法来确定的:

     1. **private \**boolean isGoodTarget(DatanodeDescriptor node, \*\*long blockSize, \*\*int maxTargetPerLoc, \*\*boolean considerLoad, List<DatanodeDescriptor> results) {\*\*\*\*\*\**\*** 
     2. ​    
     3. Log logr = FSNamesystem.LOG; 
     4. // 节点不可用了  
     5. **if (node.isDecommissionInProgress() || node.isDecommissioned()) {** 
     6. logr.debug("Node "+NodeBase.getPath(node)+ " is not chosen because the node is (being) decommissioned"); 
     7. **return \**false;\**** 
     8. } 
     9. 
     10. **long remaining = node.getRemaining() - (node.getBlocksScheduled() \* blockSize);** 
     11. // 节点剩余的容量够不够  
     12. **if (blockSize\* FSConstants.MIN_BLOCKS_FOR_WRITE>remaining) {** 
     13. logr.debug("Node "+NodeBase.getPath(node)+ " is not chosen because the node does not have enough space"); 
     14. **return \**false;\**** 
     15. } 
     16. ​    
     17. // 节点当前的负载情况  
     18. **if (considerLoad) {** 
     19. **double avgLoad = 0;** 
     20. **int size = clusterMap.getNumOfLeaves();** 
     21. **if (size != 0) {** 
     22. ​    avgLoad = (**double)fs.getTotalLoad()/size;** 
     23. } 
     24. **if (node.getXceiverCount() > (2.0 \* avgLoad)) {** 
     25. ​    logr.debug("Node "+NodeBase.getPath(node)+ " is not chosen because the node is too busy"); 
     26. ​    **return \**false;\**** 
     27. } 
     28. } 
     29. ​    
     30. // 该节点坐在的机架被选择存放当前数据块副本的数据节点过多  
     31. String rackname = node.getNetworkLocation(); 
     32. **int counter=1;** 
     33. **for(Iterator<DatanodeDescriptor> iter = results.iterator(); iter.hasNext();) {** 
     34. Node result = iter.next(); 
     35. **if (rackname.equals(result.getNetworkLocation())) {** 
     36. ​    counter++; 
     37. } 
     38. } 
     39. **if (counter>maxTargetPerLoc) {** 
     40. logr.debug("Node "+NodeBase.getPath(node)+ " is not chosen because the rack has too many chosen nodes"); 
     41. **return \**false;\**** 
     42. } 
     43. 
     44. **return \**true;\**** 
     45. } 
    

    2.选择一个本地机架节点
    实际上,选择本地节假节点和远程机架节点都需要以一个节点为参考,这样才是有意义,所以在上面的流程图中,我用红色字体标出了参考点。那么,ReplicationTargetChooser是如何根据一个节点选择它的一个本地机架节点呢?
    这个过程很简单,如果参考点为空,则从整个集群中随机选择一个合适的数据节点作为此时的本地机架节点;否则就从参考节点所在的机架中随机选择一个合适的数据节点作为此时的本地机架节点,若这个集群中没有合适的数据节点的话,则从已选择的数据节点中找出一个作为新的参考点,如果找到了一个新的参考点,则从这个新的参考点在的机架中随机选择一个合适的数据节点作为此时的本地机架节点;否则从整个集群中随机选择一个合适的数据节点作为此时的本地机架节点。如果新的参考点所在的机架中仍然没有合适的数据节点,则只能从整个集群中随机选择一个合适的数据节点作为此时的本地机架节点了。

       1.   // 如果参考点为空,则从整个集群中随机选择一个合适的数据节点作为此时的本地机架节点  
       2.   **if (localMachine == \**null) {\**** 
       3.    **return chooseRandom(NodeBase.ROOT, excludedNodes, blocksize, maxNodesPerRack, results);** 
       4.   } 
       5. ​    
       6.   //从参考节点所在的机架中随机选择一个合适的数据节点作为此时的本地机架节点  
       7.   **try {** 
       8.    **return chooseRandom(localMachine.getNetworkLocation(), excludedNodes, blocksize, maxNodesPerRack, results);** 
       9.   } **catch (NotEnoughReplicasException e1) {** 
       10.    //若这个集群中没有合适的数据节点的话,则从已选择的数据节点中找出一个作为新的参考点  
       11.    DatanodeDescriptor newLocal=**null;** 
       12.    **for(Iterator<DatanodeDescriptor> iter=results.iterator(); iter.hasNext();) {** 
       13. ​    DatanodeDescriptor nextNode = iter.next(); 
       14. ​    **if (nextNode != localMachine) {** 
       15. ​     newLocal = nextNode; 
       16. ​     **break;** 
       17. ​    } 
       18.    } 
       19. ​    
       20.    **if (newLocal != \**null) {//找到了一个新的参考点\****  
       21. ​    **try {** 
       22. ​     //从这个新的参考点在的机架中随机选择一个合适的数据节点作为此时的本地机架节点  
       23. ​     **return chooseRandom(newLocal.getNetworkLocation(), excludedNodes, blocksize, maxNodesPerRack, results);** 
       24. ​    } **catch(NotEnoughReplicasException e2) {** 
       25. ​     //新的参考点所在的机架中仍然没有合适的数据节点,从整个集群中随机选择一个合适的数据节点作为此时的本地机架节点  
       26. ​     **return chooseRandom(NodeBase.ROOT, excludedNodes, blocksize, maxNodesPerRack, results);** 
       27. ​    } 
       28.    } **else {** 
       29. ​    //从整个集群中随机选择一个合适的数据节点作为此时的本地机架节点  
       30. ​    **return chooseRandom(NodeBase.ROOT, excludedNodes, blocksize, maxNodesPerRack, results);** 
       31.    } 
       32.   } 
       33.  }
    

    3.选择一个远程机架节点
    选择一个远程机架节点就是随机的选择一个合适的不在参考点坐在的机架中的数据节点,如果没有找到这个合适的数据节点的话,就只能从参考点所在的机架中选择一个合适的数据节点作为此时的远程机架节点了。

    4.随机选择若干数据节点
    这里的随机随机选择若干个数据节点实际上指的是从某一个范围内随机的选择若干个节点,它的实现需要利用前面提到过的NetworkTopology数据结构。随机选择所使用的范围本质上指的是一个路径,这个路径表示的是NetworkTopology所表示的树状网络拓扑图中的一个非叶子节点,随机选择针对的就是这个节点的所有叶子子节点,因为所有的数据节点都被表示成了这个树状网络拓扑图中的叶子节点。

    5.优化数据传输的路径
    以前说过,HDFS对于Block的副本copy采用的是流水线作业的方式:client把数据Block只传给一个DataNode,这个DataNode收到Block之后,传给下一个DataNode,依次类推,…,最后一个DataNode就不需要下传数据Block了。所以,在为一个数据块确定了所有的副本存放的位置之后,就需要确定这种数据节点之间流水复制的顺序,这种顺序应该使得数据传输时花费的网络延时最小。ReplicationTargetChooser用了非常简单的方法来考量的,大家一看便知:

       1. **private DatanodeDescriptor[] getPipeline( DatanodeDescriptor writer, DatanodeDescriptor[] nodes) {** 
       2. **if (nodes.length==0) \**return nodes;\**** 
       3. ​    
       4. **synchronized(clusterMap) {** 
       5. **int index=0;** 
       6. **if (writer == \**null || !clusterMap.contains(writer)) {\**** 
       7. ​    writer = nodes[0]; 
       8. } 
       9. ​    
       10. **for(;index<nodes.length; index++) {** 
       11. ​    DatanodeDescriptor shortestNode = nodes[index]; 
       12. ​    **int shortestDistance = clusterMap.getDistance(writer, shortestNode);** 
       13. ​    **int shortestIndex = index;** 
       14. ​    **for(\**int i=index+1; i<nodes.length; i++) {\**** 
       15. ​     DatanodeDescriptor currentNode = nodes[i]; 
       16. ​     **int currentDistance = clusterMap.getDistance(writer, currentNode);** 
       17. ​     **if (shortestDistance>currentDistance) {** 
       18. ​      shortestDistance = currentDistance; 
       19. ​      shortestNode = currentNode; 
       20. ​      shortestIndex = i; 
       21. ​     } 
       22. ​    } 
       23. ​    //switch position index & shortestIndex  
       24. ​    **if (index != shortestIndex) {** 
       25. ​     nodes[shortestIndex] = nodes[index]; 
       26. ​     nodes[index] = shortestNode; 
       27. ​    } 
       28. ​    writer = shortestNode; 
       29. } 
       30. } 
       31. **return nodes;** 
       32. } 
    

    可惜的是,HDFS目前并没有把副本存放策略的实现开放给用户,也就是用户无法根据自己的实际需求来指定文件的数据块存放的具体位置。例如:我们可以将有关系的两个文件放到相同的数据节点上,这样在进行map-reduce的时候,其工作效率会大大的提高。但是,又考虑到副本存放策略是与集群负载均衡休戚相关的,所以要是真的把负载存放策略交给用户来实现的话,对用户来说是相当负载的,所以我只能说Hadoop目前还不算成熟,尚需大踏步发展。

    展开全文
  • 今天的大数据入门分享,我们就来讲讲HDFS数据副本存放策略HDFS 是 Hadoop 分布式文件系统,基于廉价的PC集群,就能支持大规模数据集的存储,并且可以通过增加机器来提升存储容量,对于企业而言,提供了低成本的...
  • 4.2 HDFS 副本存放策略

    2020-08-05 01:03:09
    了解 HDFS 副本存放策略的作用 理解 DataNode 网络拓扑图 知晓查看集群机架及其节点情况的命令 熟记 HDFS 副本存放策略 任务清单 任务1:副本存放策略的作用 任务2:机架感知 任务3:HDFS 副本存放策略基本...
  • 第一个block副本放在和client所在的node里(如果是集群外提交,则随机挑选一台磁盘不太慢、CPU不太忙的节点上)。...当客户端向 HDFS 文件写入数据的时候,一开始是写到本地临时文件中。 假设该文件...
  • 数据分块存储和副本存放,是保证可靠性和高性能的关键 将每个文件的数据进行分块存储,每一个数据块又保存有多个副本。这些数据块副本分布在不同的机器节点上   设置备份数   方法一:配置文件hdfs-site....
  • 副本存放策略 将每个文件的数据进行分块存储,每一个数据块又保存有多个副本,这些数据块副本分布在不同的机器节点上。 在多数情况下,HDFS 默认的副本系数是 3 第一个block副本放在和client所在的node里(如果...
  • HDFS- 副本存放策略

    2020-08-06 14:06:52
    这切实关系到 HDFS 的可依赖性与表现,并且经过优化的副本放置策略也使得 HDFS 相比其他分布式文件系统具有优势。 先来看下这个策略类的功能说明: This interface is used for choosing the desired number of ...
  • Block的副本放置策略 第一个副本:放置在上传文件的DN;如果是集群外提交,则随机挑选一台磁盘不太满,CPU不太忙的节点。 第二个副本:放置在于第一个副本不同的 机架的节点上。 第三个副本:与第二个副本相同机架的...
  • HDFS-- 副本放置策略

    2021-08-05 09:00:04
    一、概述 ...HDFS副本放置策略主要做的事情在于副本的最终存放,位置放得好了,能提高读写性能,否则反而会起到负面的效果 之前文章提到的三副本备份策略就是其中一个副本放置 策略 二、副本放...
  • HDFS副本放置策略

    2020-12-09 14:23:26
    第一个副本:放置在上传的DN节点上,就近原则节省网络IO。 假如是在非DN节点上,就挑选一个磁盘不太快,CPU不太忙的节点。 第二个副本:放置在第一个副本的不同机架的某个节点 第三个副本:与第二个副本放置在同一个...
  • HDFS副本放置策略

    万次阅读 多人点赞 2016-04-19 19:36:37
    前一篇文章中刚刚分析完HDFS的异构存储以及相关的存储类型选择策略,浏览量还是不少的,说明大家对于HDFS的异构存储方面的功能还是很感兴趣的.但是其实一个文件Block块从最初的产生到最后的落盘,存储类型选择策略只是...
  • [hadoop] HDFS默认的副本存放策略

    千次阅读 2019-09-25 16:59:40
    第二份:存放到第一份副本所在的机架上的另外一个不同的节点上 第三份:存放到第一份所在的机架外的另外一个不同的节点上 更多的副本:随机选择与第一份副本所在节点同一数据中心上的任一节点进行存储 原文 For the...
  • HDFS作为Hadoop中的一个分布式文件...首先,HDFS将每一个文件的数据进行分块存储,同时每一个数据块又保存有多个副本,这些数据块副本分布在不同的机器节点上,这种数据分块存储+副本策略HDFS保证可靠性和性能的...
  • 副本放置策略副本放置策略的基本思想是:第一个block副本放在和client所在的node里(如果client不在集群范围内,则这第一个node是随机选取的,当然系统会尝试不选择哪些太满或者太忙的node)。第二个副本放置在与第一...
  • HDFS副本放置策略 第一个副本: 假如上传节点为DN节点,优先放置本节点; 否则就随机挑选一台磁盘不太慢 CPU不太繁忙的节点; 第二个副本: 放置在于第一个副本的不同的机架的节点上 第三个副本: 放置于第二个副本...
  • HDFS新版本的副本存放策略

    千次阅读 2019-10-17 16:10:53
    关于HDFS副本存放策略,一直以来总是会听到和看到两种不同的观点。 今天看了Hadoop官网上关于Hadoop2.7.6与Hadoop2.8.4的技术文档,HDFS副本存放策略其实可以分为新旧两种策略。 Hadoop2.7.6及以下版本是按照旧的...
  • 浅析HDFS副本存放策略

    千次阅读 2019-10-21 19:29:43
    在大多数情况下,副本系数是3,HDFS存放策略是: 将一个副本存放在本地机架节点上, 一个副本存放在同一个机架的另一个节点上, 最后一个副本放在不同机架的节点上。 简单说:在我们的笔记本中,搭建hadoop...
  • 数据块副本放置策略直接决定了每个数据块多个副本存放节点的选择,一个良好的副本放置策略能权衡写性能和可靠性两个因素,在保证写性能较优的情况下,尽可能提高数据的可靠性。 副本放置策略与集群物理拓扑结构是...
  • hadoop读写副本放置策略

    千次阅读 2018-08-29 10:27:42
    根据Maneesh Varshney的漫画改编,以简洁易懂的漫画形式讲解HDFS存储机制与运行原理,非常适合Hadoop/HDFS初学者理解。 一、角色出演 如上图所示,HDFS存储相关角色与功能如下: Client:客户端,系统使用者,调用...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,767
精华内容 3,106
关键字:

hdfs副本存放策略

友情链接: BERSER.rar