1从srcnamenode获取到block的信息,2去dest addblock信息,3判断block进行拷贝,拷贝判断是不是同一个datanode,如果是进行硬链接拷贝。否进行复制数据
LocatedBlock存放文件的block信息,
通过DatanodeInfo[] getLocations()
获取包含了文件所在的DatanodeInfo
DatanodeInfo中包含节点信息favoredNodes[i] = srcLocatedBlock.getLocations()[i].getHostName()
+ ":" + srcLocatedBlock.getLocations()[i].getXferPort()
ClientDatanodeProtocolTranslatorPB实现ClientDatanodeProtocol接口,是Client跟DataNode的RPC通信类
ClientNamenodeProtocolTranslatorPB实现ClientProtocol接口,是Client跟NameNode的RPC通信类
+ @Override
+ public void copyBlock(ExtendedBlock src, ExtendedBlock dst, DatanodeInfo dstDn)
+ throws IOException {
+ if (!data.isValidBlock(src)) {
+ // block does not exist or is under-construction
+ String errStr = "copyBlock:(" + this.getInfoPort() + ") Can't send invalid block " + src
+ + " " + data.getReplicaString(src.getBlockPoolId(), src.getBlockId());
+ LOG.info(errStr);
+ throw new IOException(errStr);
+ }
+ long onDiskLength = data.getLength(src);
+ if (src.getNumBytes() > onDiskLength) {
+ // Shorter on-disk len indicates corruption so report NN the corrupt block
+ String msg = "copyBlock: Can't replicate block " + src
+ + " because on-disk length " + onDiskLength
+ + " is shorter than provided length " + src.getNumBytes();
+ LOG.info(msg);
+ throw new IOException(msg);
+ }
+ LOG.info(getDatanodeInfo() + " copyBlock: Starting thread to transfer: " +
+ "block:" + src + " from " + this.getDatanodeUuid() + " to " + dstDn.getDatanodeUuid() +
+ "(" +dstDn + ")");
+ Future<?> result;
+ if (this.getDatanodeUuid().equals(dstDn.getDatanodeUuid())) {//如果是同一个节点,则用hardLink硬拷贝
+ result = blockCopyExecutor.submit(new LocalBlockCopy(src, dst));
+ } else {
+ result = blockCopyExecutor.submit(new DataCopy(dstDn, src, dst));
+ }
+ try {
+ // Wait for 5 minutes.
+ result.get(5 * 60, TimeUnit.SECONDS);
+ } catch (Exception e) {
+ LOG.error(e);
+ throw new IOException(e);
+ }
+ }