-
Notifications
You must be signed in to change notification settings - Fork 9k
HDFS-16757. Add a new method copyBlockCrossNamespace to DataNode #6926
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: HDFS-2139
Are you sure you want to change the base?
Conversation
💔 -1 overall
This message was automatically generated. |
💔 -1 overall
This message was automatically generated. |
Why not merge to trunk? |
At last comment in https://issues.apache.org/jira/browse/HDFS-2139 . I guess this is used for isolate. When all work is done will merge into trunk. Thanks |
💔 -1 overall
This message was automatically generated. |
💔 -1 overall
This message was automatically generated. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @LiuGuH for your works. Leave some comments inline. PFYI. And this is one huge PR, we need involve more folks to revews.
Another one, now we don't consider capacity used between different BlockPool when hardlink at DataNode side, right? Will it resolve at next PR?
LOG.warn("{}:Failed to transfer {} to {} got", | ||
bpReg, b, targets[0], ie); | ||
if (copyBlockCrossNamespace) { | ||
throw new RuntimeException(ie); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Be careful to throw RuntimeException directly here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DataTransfer is implemented Runnable. And only support throw RuntimeException . This RuntimeException will catch by future.get() try catch .
LOG.error("Failed to transfer block {}", b, t); | ||
LOG.error("Failed to transfer block {}", source, t); | ||
if (copyBlockCrossNamespace) { | ||
throw new RuntimeException(t); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As the above comment.
BlockLocalPathInfo blpi = getBlockLocalPathInfo(srcBlock); | ||
FsVolumeImpl v = getVolume(srcBlock); | ||
|
||
try (AutoCloseableLock lock = lockManager.writeLock(LockLevel.VOLUME, dstBlock.getBlockPoolId(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if it is enough to obtain only dest block pool lock here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strictly speaking , here we should use src read lock and dst write lock. And must make sure the order of accquire locks of pools to avoid deadlock.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have the same question. If the src block is not protected here, will the results be inconsistent?
...op-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/DFSOutputStream.java
Show resolved
Hide resolved
hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DFSConfigKeys.java
Show resolved
Hide resolved
...-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataNode.java
Show resolved
Hide resolved
Thanks for reveiw @Hexiaoqiao |
...-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataNode.java
Outdated
Show resolved
Hide resolved
...-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataNode.java
Outdated
Show resolved
Hide resolved
...-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataNode.java
Outdated
Show resolved
Hide resolved
...-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataNode.java
Outdated
Show resolved
Hide resolved
dstBlockFile = dstBPS.addFinalizedBlock(dstBlock.getLocalBlock(), replicaInfo); | ||
replicaInfo = new FinalizedReplica(dstBlock.getLocalBlock(), getVolume(srcBlock), | ||
dstBlockFile.getParentFile()); | ||
volumeMap.add(dstBlock.getBlockPoolId(), replicaInfo); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since volumeMap.add() needs to acquire the block pool's read lock, can we move the line volumeMap.add() outside the try block, and execute volumeMap.add() after releasing the lock? I'm not sure if there will be any concurrency issues with this approach.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dst volume write lock protects hardlink file atomicity and volumeMap.add(). The best case scenario we should use src volume read lock and dst volume write lock to protect src and dst file operation.
And in DataXceiver, writeBlock() readBlock() transferBlock() , is as same as this only require lock with block meta operation.
So, I think this is enough for now. @Hexiaoqiao he @KeeProMise
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dst volume write lock protects hardlink file atomicity and volumeMap.add(). The best case scenario we should use src volume read lock and dst volume write lock to protect src and dst file operation.
And in DataXceiver, writeBlock() readBlock() transferBlock() , is as same as this only require lock with block meta operation.
So, I think this is enough for now. @Hexiaoqiao he @KeeProMise
Based on the offline discussion, I think this change is acceptable for now. However, we need to restrict the scenario, such as the directory being updated cannot use fastcopy.
hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/DFSClient.java
Show resolved
Hide resolved
...-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataNode.java
Outdated
Show resolved
Hide resolved
...hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/BlockPoolSlice.java
Outdated
Show resolved
Hide resolved
💔 -1 overall
This message was automatically generated. |
💔 -1 overall
This message was automatically generated. |
💔 -1 overall
This message was automatically generated. |
💔 -1 overall
This message was automatically generated. |
💔 -1 overall
This message was automatically generated. |
🎊 +1 overall
This message was automatically generated. |
💔 -1 overall
This message was automatically generated. |
🎊 +1 overall
This message was automatically generated. |
@@ -3863,5 +3864,27 @@ public void setLastDirScannerFinishTime(long time) { | |||
public long getPendingAsyncDeletions() { | |||
return asyncDiskService.countPendingDeletions(); | |||
} | |||
|
|||
@Override | |||
public void hardLinkOneBlock(ExtendedBlock srcBlock, ExtendedBlock dstBlock) throws IOException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
public void hardLinkOneBlock(ExtendedBlock srcBlock, ExtendedBlock dstBlock) throws IOException {
ReplicaInfo srcReplicaInfo = getReplicaInfo(srcBlock);
FsVolumeImpl v = getVolume(srcBlock);
try (AutoCloseableLock lock = lockManager.writeLock(LockLevel.VOLUME, dstBlock.getBlockPoolId(),
v.getStorageID())) {
BlockPoolSlice dstBPS = v.getBlockPoolSlice(dstBlock.getBlockPoolId());
LocalReplicaInPipeline replicaInfo = (LocalReplicaInPipeline) v.createTemporary(dstBlock);
hardLinkBlockFiles(srcReplicaInfo, replicaInfo.getMetaFile(), replicaInfo.getBlockFile());
File dstBlockFile = dstBPS.addFinalizedBlock(dstBlock.getLocalBlock(), replicaInfo);
ReplicaInfo finalizedReplica = new FinalizedReplica(dstBlock.getLocalBlock(),
v, dstBlockFile.getParentFile());
volumeMap.add(dstBlock.getBlockPoolId(), finalizedReplica);
}
}
How about using the existing method hardLinkBlockFiles
to perform this logic?
💔 -1 overall
This message was automatically generated. |
🎊 +1 overall
This message was automatically generated. |
Can we continue to push this mission? Thanks @Hexiaoqiao @tomscut @haiyang1987 @ZanderXu |
💔 -1 overall
This message was automatically generated. |
💔 -1 overall
This message was automatically generated. |
💔 -1 overall
This message was automatically generated. |
💔 -1 overall
This message was automatically generated. |
💔 -1 overall
This message was automatically generated. |
💔 -1 overall
This message was automatically generated. |
🎊 +1 overall
This message was automatically generated. |
🎊 +1 overall
This message was automatically generated. |
Description of PR
As described below HDFS-16757
This is the base PR of FastCopy HDFS-2139