Hadoop2.8.5 数据节点 DataNode

数据节点 DataNode 在 HDFS 文件系统中处于从属的地位, 但是其结构却比处于主导地位的查名节点 NameNode 更复杂。这是因为:虽然 NameNode 起着目录的作用,但是文件的内容却是存储在 DataNode 上的,读写文件时一旦知道了哪一个块在什么节点上,或者指定存放在什么节点上,下面就不需要 NameNode 的介入了。而块的存取,却是颇为复杂的操作。再说 NameNode 是靠“听汇报”来掌握什么 DataNode 上存储着哪一些块的,这一来倒好像DataNode 才是主动的, NameNode 反倒是被动的了。而且,新版 Hadoop 的设计还允许集群中有多个 NameNode ,形成“联邦( Federal )”,一个 DataNode 可以为多个 NameNode 存储数据块。

1. DataNode

数据节点 DataNode 在 HDFS 文件系统中处于从属的地位,但是其结构却比处于主导地位的查名节点 NameNode 更复杂。

public class DataNode extends ReconfigurableBase implements InterDatanodeProtocol, ClientDatanodeProtocol,
        TraceAdminProtocol, DataNodeMXBean {
   
   
   
  private BlockPoolManager blockPoolManager; // 同一文件卷的块属于相同 BlockPool
  volatile FsDatasetSpi<? extends FsVolumeSpi> data = null;//数据块的集合,实际上是个 FsVolumeImpl
  private DataStorage storage = null; //代表着数据块的存储空间
  private DatanodeHttpServer httpServer = null;
  DataXceiverServer xserver = null;
  private  BlockScanner blockScanner;//数据块扫描线程
  private DirectoryScanner directoryScanner = null;//目录扫描线程
  Daemon dataXceiverServer = null; //数据收发线程,通过局域网收发数据
  Daemon localDataXceiverServer; //通过 Unix 域 socket 在本节点上收发数据的线程
  ThreadGroup threadGroup = null;//一组 dataXceiverServer 线程
  public RPC.Server ipcServer; //提供 RPC 服务
  List<StorageLocation> dataDirs;//本地宿主文件系统中用于 HDFS 块存储的目录
  
}

BlockPoolManager中有两个映射表( Map )和一个 BPOfferService 的列表。一个 BPOfferService 相当于面向一个
具体 FSNamesystem 的联络站, BP 就是 BlockPool 的缩写,所以这是“由 BlockPool 提供的服务”的意思。两个映射表的存在是为迅速找到具体的 BPOfferService ,一个是按 NameserviceId 映射查找,另一个是按 BlockPoolId 映射查找。然后,进一步在每个 BPOfferService 内部又有一个 BPServiceActor 的列表,每个 BPServiceActor 相当于专责与某个 NameNode 联系的联络员。

class BlockPoolManager {
   
   
  //按 NameserviceId 查找
  private final Map<String, BPOfferService> bpByNameserviceId = Maps.newHashMap();
  //按 BlockPoolId 查找
  private final Map<String, BPOfferService> bpByBlockPoolId = Maps.newHashMap();
  //对于每个 Nameservice 都有个联络组
  private final List<BPOfferService> offerServices =new CopyOnWriteArrayList<>();
  private final DataNode dn;
  
}

核心的部件当然是这里的 FsDataset,代表着数据块的集合,实现了对数据块集合的管理。

class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
   
   
	final DataStorage dataStorage; //代表着实际的存储
	private final FsVolumeList volumes; //数据块可能属于不同的文件卷
	final Map<String, DatanodeStorage> storageMap; //按 storageUuid 查找
	final FsDatasetAsyncDiskService asyncDiskService; /实现对磁盘的异步读写
	Daemon lazyWriter //一个 LazyWriter 线程,仅在真有必要时才写磁盘
	final FsDatasetCache cacheManager; //对于缓冲块的管理
	final ReplicaMap volumeMap; //可以根据 BlockPoolId 和块号找到其复份的 ReplicaInfo
}

数据块最终总是存储在某种存储介质上, DataStorage 就代表着这样的存储介质、存储空间。不过 HDFS 所看到的存储介质并非物理的、实体的存储介质,例如磁盘,而是宿主机的文件系统,是宿主机文件系统中的若干目录。这些目录可以在磁盘上,也可以在 RAMDisk 上,还可以在别的介质上。 DataStorage 类是对 Storage 类的扩充,我们在 NameNode 那一边看到的 NNStorage 也是对 Storage 类的扩充。所以, DataStorage 和 NNStorage 分别是 DateNode和 NameNode 上的 Storage ,二者都由宿主文件系统提供,只是使用方式不同。

一个 DataNode 上存储着一些什么块,并不是由 NameNode 告诉它的,而是反过来由DataNode 自己扫描,得知本节点上有些什么以后向 NameNode 报告的。而且这样的扫描和报告要周期地反复进行。 DataNode 上有两个线程,即 BlockScanner 和 DirectoryScanner ,就是专门从事这个工作的。

DataNode 上 的 节 点 间 通 信 也 比 NameNode 上 复 杂,因 为 DataNode 不 仅 要 面 对NameNode ,还有DataNode 互相之间的通信,特别是数据块的收发。 DataNode 之间的通信是对等通信,没 有 固 定 的 Client 和 Server ,每 个 DataNode 都 既 是 Client 又 是 Server ,所 以DataNode 上专门有一组 dataXceiverServer 线程。当然, DataNode 上也要有 RPC 服务端,即RPC. Server 。

DataNode(final Configuration conf, final List<StorageLocation> dataDirs, final SecureResources resources) {
   
   
	 try {
   
   
      hostName = getHostName(conf);
      LOG.info("Configured hostname is " + hostName);
      startDataNode(conf, dataDirs, resources);
    } catch (IOException ie) {
   
   
      shutdown();
      throw ie;
    }
}
void startDataNode(Configuration
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值