何时使用了块放置策略?

时间:2015-11-29 02:40:12

标签: hadoop hdfs yarn hadoop-streaming

我知道dfs.block.replicator.classname属性可用于更改BlockPlacementPolicy。我想知道这个政策到底用于放置数据的时间到底是什么时候?就像在执行-copyFromLocal / -put时一样? 我认为工作的输出也将根据这项政策进行。

其次,在conf文件中指定的属性将影响整个hadoop集群。如果我正在使用共享群集,是否有办法仅针对在我的用户下执行的作业更改BlockPlacement策略,或者是否有办法更改每个作业的策略?

我在4节点集群上使用hadoop流式传输。

1 个答案:

答案 0 :(得分:2)

只要将新数据块写入HDFS,就会使用块放置策略。可能是数据被摄入HDFS或作业将数据写入HDFS等时。它用于块的最佳放置,因此HDFS集群中有统一的分布块。

例如默认块放置策略类(BlockPlacementPolicyDefault)使用的算法是:

The replica placement strategy is that if the writer is on a datanode,
the 1st replica is placed on the local machine, otherwise a random datanode. 
The 2nd replica is placed on a datanode that is on a different rack. The 3rd 
replica is placed on a datanode which is on a different node of the rack as 
the second replica.

以下HDFS实用程序也使用块放置策略:

  • Balancer:平衡HDFS上的磁盘空间使用情况。在这种情况下,BlockPlacementPolicy可用于将块放置到其他节点,以便重新平衡群集
  • NamenodeFsck: - 检查HDFS是否存在不一致的实用程序。在这种情况下,BlockPlacementPolicy用于检查错误复制块的数量。

您可以拥有自己的自定义块放置级别。为此,您需要扩展BlockPlacementPolicy类并将配置参数dfs.block.replicator.classname设置为hdfs-site.xml中的自定义类名。

默认情况下,BlockPlacementPolicyDefault类用于块放置:

final Class<? extends BlockPlacementPolicy> replicatorClass = conf.getClass(
    DFSConfigKeys.DFS_BLOCK_REPLICATOR_CLASSNAME_KEY,
    DFSConfigKeys.DFS_BLOCK_REPLICATOR_CLASSNAME_DEFAULT,
    BlockPlacementPolicy.class);

您无法更改每个作业的块放置策略。原因是,当NameNode出现时,块放置策略被实例化一次。

以下是调用序列,以初始化BlockPlacementPolicy。启动NameNode时执行这些步骤:

  1. NameNode启动时初始化NameNode

    NameNode::initialize(conf);  // Initialize NameNode
    NameNode::loadNamesystem(conf); // Load name system
    
  2. 初始化FsNameSystemFsNameSystem所有预订工作都在NameNode

    上完成
    FSNamesystem.loadFromDisk(conf); // Loads FS Image from disk
    
  3. 实例化BlockManager。在实例化FsNameSystem

    时调用此方法
    this.blockManager = new BlockManager(this, conf);
    
  4. 实例化BlockPlacementPolicy。这由BlockManager调用。

    blockplacement = BlockPlacementPolicy.getInstance(
                     conf, datanodeManager.getFSClusterStats(),
                     datanodeManager.getNetworkTopology(),
                     datanodeManager.getHost2DatanodeMap());
    
  5. 由于这是实例化一次,因此您无法为每个作业更改此项。