我知道dfs.block.replicator.classname属性可用于更改BlockPlacementPolicy。我想知道这个政策到底用于放置数据的时间到底是什么时候?就像在执行-copyFromLocal / -put时一样? 我认为工作的输出也将根据这项政策进行。
其次,在conf文件中指定的属性将影响整个hadoop集群。如果我正在使用共享群集,是否有办法仅针对在我的用户下执行的作业更改BlockPlacement策略,或者是否有办法更改每个作业的策略?
我在4节点集群上使用hadoop流式传输。
答案 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实用程序也使用块放置策略:
BlockPlacementPolicy
可用于将块放置到其他节点,以便重新平衡群集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时执行这些步骤:
在NameNode
启动时初始化NameNode
NameNode::initialize(conf); // Initialize NameNode
NameNode::loadNamesystem(conf); // Load name system
初始化FsNameSystem
。 FsNameSystem
所有预订工作都在NameNode
FSNamesystem.loadFromDisk(conf); // Loads FS Image from disk
实例化BlockManager
。在实例化FsNameSystem
this.blockManager = new BlockManager(this, conf);
实例化BlockPlacementPolicy
。这由BlockManager
调用。
blockplacement = BlockPlacementPolicy.getInstance(
conf, datanodeManager.getFSClusterStats(),
datanodeManager.getNetworkTopology(),
datanodeManager.getHost2DatanodeMap());
由于这是实例化一次,因此您无法为每个作业更改此项。