|
@@ -49,6 +49,7 @@ import org.apache.hadoop.hdfs.server.protocol.DisallowedDatanodeException;
|
|
import org.apache.hadoop.hdfs.server.protocol.FinalizeCommand;
|
|
import org.apache.hadoop.hdfs.server.protocol.FinalizeCommand;
|
|
import org.apache.hadoop.hdfs.server.protocol.KeyUpdateCommand;
|
|
import org.apache.hadoop.hdfs.server.protocol.KeyUpdateCommand;
|
|
import org.apache.hadoop.hdfs.server.protocol.NamespaceInfo;
|
|
import org.apache.hadoop.hdfs.server.protocol.NamespaceInfo;
|
|
|
|
+import org.apache.hadoop.hdfs.server.protocol.ReceivedDeletedBlockInfo;
|
|
import org.apache.hadoop.hdfs.server.protocol.UpgradeCommand;
|
|
import org.apache.hadoop.hdfs.server.protocol.UpgradeCommand;
|
|
import org.apache.hadoop.ipc.RPC;
|
|
import org.apache.hadoop.ipc.RPC;
|
|
import org.apache.hadoop.ipc.RemoteException;
|
|
import org.apache.hadoop.ipc.RemoteException;
|
|
@@ -87,6 +88,7 @@ class BPOfferService implements Runnable {
|
|
DatanodeRegistration bpRegistration;
|
|
DatanodeRegistration bpRegistration;
|
|
|
|
|
|
long lastBlockReport = 0;
|
|
long lastBlockReport = 0;
|
|
|
|
+ long lastDeletedReport = 0;
|
|
|
|
|
|
boolean resetBlockReportTime = true;
|
|
boolean resetBlockReportTime = true;
|
|
|
|
|
|
@@ -94,8 +96,9 @@ class BPOfferService implements Runnable {
|
|
DatanodeProtocol bpNamenode;
|
|
DatanodeProtocol bpNamenode;
|
|
private long lastHeartbeat = 0;
|
|
private long lastHeartbeat = 0;
|
|
private volatile boolean initialized = false;
|
|
private volatile boolean initialized = false;
|
|
- private final LinkedList<Block> receivedBlockList = new LinkedList<Block>();
|
|
|
|
- private final LinkedList<String> delHints = new LinkedList<String>();
|
|
|
|
|
|
+ private final LinkedList<ReceivedDeletedBlockInfo> receivedAndDeletedBlockList
|
|
|
|
+ = new LinkedList<ReceivedDeletedBlockInfo>();
|
|
|
|
+ private volatile int pendingReceivedRequests = 0;
|
|
private volatile boolean shouldServiceRun = true;
|
|
private volatile boolean shouldServiceRun = true;
|
|
UpgradeManagerDatanode upgradeManager = null;
|
|
UpgradeManagerDatanode upgradeManager = null;
|
|
private final DataNode dn;
|
|
private final DataNode dn;
|
|
@@ -271,39 +274,30 @@ class BPOfferService implements Runnable {
|
|
* Report received blocks and delete hints to the Namenode
|
|
* Report received blocks and delete hints to the Namenode
|
|
* @throws IOException
|
|
* @throws IOException
|
|
*/
|
|
*/
|
|
- private void reportReceivedBlocks() throws IOException {
|
|
|
|
- //check if there are newly received blocks
|
|
|
|
- Block [] blockArray=null;
|
|
|
|
- String [] delHintArray=null;
|
|
|
|
- synchronized(receivedBlockList) {
|
|
|
|
- synchronized(delHints){
|
|
|
|
- int numBlocks = receivedBlockList.size();
|
|
|
|
- if (numBlocks > 0) {
|
|
|
|
- if(numBlocks!=delHints.size()) {
|
|
|
|
- LOG.warn("Panic: receiveBlockList and delHints are not of " +
|
|
|
|
- "the same length" );
|
|
|
|
- }
|
|
|
|
- //
|
|
|
|
- // Send newly-received blockids to namenode
|
|
|
|
- //
|
|
|
|
- blockArray = receivedBlockList.toArray(new Block[numBlocks]);
|
|
|
|
- delHintArray = delHints.toArray(new String[numBlocks]);
|
|
|
|
- }
|
|
|
|
|
|
+ private void reportReceivedDeletedBlocks() throws IOException {
|
|
|
|
+
|
|
|
|
+ // check if there are newly received blocks
|
|
|
|
+ ReceivedDeletedBlockInfo[] receivedAndDeletedBlockArray = null;
|
|
|
|
+ int currentReceivedRequestsCounter;
|
|
|
|
+ synchronized (receivedAndDeletedBlockList) {
|
|
|
|
+ currentReceivedRequestsCounter = pendingReceivedRequests;
|
|
|
|
+ int numBlocks = receivedAndDeletedBlockList.size();
|
|
|
|
+ if (numBlocks > 0) {
|
|
|
|
+ //
|
|
|
|
+ // Send newly-received and deleted blockids to namenode
|
|
|
|
+ //
|
|
|
|
+ receivedAndDeletedBlockArray = receivedAndDeletedBlockList
|
|
|
|
+ .toArray(new ReceivedDeletedBlockInfo[numBlocks]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- if (blockArray != null) {
|
|
|
|
- if(delHintArray == null || delHintArray.length != blockArray.length ) {
|
|
|
|
- LOG.warn("Panic: block array & delHintArray are not the same" );
|
|
|
|
- }
|
|
|
|
- bpNamenode.blockReceived(bpRegistration, getBlockPoolId(), blockArray,
|
|
|
|
- delHintArray);
|
|
|
|
- synchronized(receivedBlockList) {
|
|
|
|
- synchronized(delHints){
|
|
|
|
- for(int i=0; i<blockArray.length; i++) {
|
|
|
|
- receivedBlockList.remove(blockArray[i]);
|
|
|
|
- delHints.remove(delHintArray[i]);
|
|
|
|
- }
|
|
|
|
|
|
+ if (receivedAndDeletedBlockArray != null) {
|
|
|
|
+ bpNamenode.blockReceivedAndDeleted(bpRegistration, getBlockPoolId(),
|
|
|
|
+ receivedAndDeletedBlockArray);
|
|
|
|
+ synchronized (receivedAndDeletedBlockList) {
|
|
|
|
+ for (int i = 0; i < receivedAndDeletedBlockArray.length; i++) {
|
|
|
|
+ receivedAndDeletedBlockList.remove(receivedAndDeletedBlockArray[i]);
|
|
}
|
|
}
|
|
|
|
+ pendingReceivedRequests -= currentReceivedRequestsCounter;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -314,26 +308,42 @@ class BPOfferService implements Runnable {
|
|
* client? For now we don't.
|
|
* client? For now we don't.
|
|
*/
|
|
*/
|
|
void notifyNamenodeReceivedBlock(ExtendedBlock block, String delHint) {
|
|
void notifyNamenodeReceivedBlock(ExtendedBlock block, String delHint) {
|
|
- if(block==null || delHint==null) {
|
|
|
|
- throw new IllegalArgumentException(
|
|
|
|
- block==null?"Block is null":"delHint is null");
|
|
|
|
|
|
+ if (block == null || delHint == null) {
|
|
|
|
+ throw new IllegalArgumentException(block == null ? "Block is null"
|
|
|
|
+ : "delHint is null");
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
if (!block.getBlockPoolId().equals(getBlockPoolId())) {
|
|
if (!block.getBlockPoolId().equals(getBlockPoolId())) {
|
|
LOG.warn("BlockPool mismatch " + block.getBlockPoolId() + " vs. "
|
|
LOG.warn("BlockPool mismatch " + block.getBlockPoolId() + " vs. "
|
|
+ getBlockPoolId());
|
|
+ getBlockPoolId());
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
-
|
|
|
|
- synchronized (receivedBlockList) {
|
|
|
|
- synchronized (delHints) {
|
|
|
|
- receivedBlockList.add(block.getLocalBlock());
|
|
|
|
- delHints.add(delHint);
|
|
|
|
- receivedBlockList.notifyAll();
|
|
|
|
- }
|
|
|
|
|
|
+
|
|
|
|
+ synchronized (receivedAndDeletedBlockList) {
|
|
|
|
+ receivedAndDeletedBlockList.add(new ReceivedDeletedBlockInfo(block
|
|
|
|
+ .getLocalBlock(), delHint));
|
|
|
|
+ pendingReceivedRequests++;
|
|
|
|
+ receivedAndDeletedBlockList.notifyAll();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ void notifyNamenodeDeletedBlock(ExtendedBlock block) {
|
|
|
|
+ if (block == null) {
|
|
|
|
+ throw new IllegalArgumentException("Block is null");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!block.getBlockPoolId().equals(getBlockPoolId())) {
|
|
|
|
+ LOG.warn("BlockPool mismatch " + block.getBlockPoolId() + " vs. "
|
|
|
|
+ + getBlockPoolId());
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ synchronized (receivedAndDeletedBlockList) {
|
|
|
|
+ receivedAndDeletedBlockList.add(new ReceivedDeletedBlockInfo(block
|
|
|
|
+ .getLocalBlock(), ReceivedDeletedBlockInfo.TODELETE_HINT));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
|
|
/**
|
|
/**
|
|
* Report the list blocks to the Namenode
|
|
* Report the list blocks to the Namenode
|
|
@@ -443,7 +453,8 @@ class BPOfferService implements Runnable {
|
|
* forever calling remote NameNode functions.
|
|
* forever calling remote NameNode functions.
|
|
*/
|
|
*/
|
|
private void offerService() throws Exception {
|
|
private void offerService() throws Exception {
|
|
- LOG.info("For namenode " + nnAddr + " using BLOCKREPORT_INTERVAL of "
|
|
|
|
|
|
+ LOG.info("For namenode " + nnAddr + " using DELETEREPORT_INTERVAL of "
|
|
|
|
+ + dnConf.deleteReportInterval + " msec " + " BLOCKREPORT_INTERVAL of "
|
|
+ dnConf.blockReportInterval + "msec" + " Initial delay: "
|
|
+ dnConf.blockReportInterval + "msec" + " Initial delay: "
|
|
+ dnConf.initialBlockReportDelay + "msec" + "; heartBeatInterval="
|
|
+ dnConf.initialBlockReportDelay + "msec" + "; heartBeatInterval="
|
|
+ dnConf.heartBeatInterval);
|
|
+ dnConf.heartBeatInterval);
|
|
@@ -481,8 +492,11 @@ class BPOfferService implements Runnable {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
- reportReceivedBlocks();
|
|
|
|
|
|
+ if (pendingReceivedRequests > 0
|
|
|
|
+ || (startTime - lastDeletedReport > dnConf.deleteReportInterval)) {
|
|
|
|
+ reportReceivedDeletedBlocks();
|
|
|
|
+ lastDeletedReport = startTime;
|
|
|
|
+ }
|
|
|
|
|
|
DatanodeCommand cmd = blockReport();
|
|
DatanodeCommand cmd = blockReport();
|
|
processCommand(cmd);
|
|
processCommand(cmd);
|
|
@@ -498,10 +512,10 @@ class BPOfferService implements Runnable {
|
|
//
|
|
//
|
|
long waitTime = dnConf.heartBeatInterval -
|
|
long waitTime = dnConf.heartBeatInterval -
|
|
(System.currentTimeMillis() - lastHeartbeat);
|
|
(System.currentTimeMillis() - lastHeartbeat);
|
|
- synchronized(receivedBlockList) {
|
|
|
|
- if (waitTime > 0 && receivedBlockList.size() == 0) {
|
|
|
|
|
|
+ synchronized(receivedAndDeletedBlockList) {
|
|
|
|
+ if (waitTime > 0 && pendingReceivedRequests == 0) {
|
|
try {
|
|
try {
|
|
- receivedBlockList.wait(waitTime);
|
|
|
|
|
|
+ receivedAndDeletedBlockList.wait(waitTime);
|
|
} catch (InterruptedException ie) {
|
|
} catch (InterruptedException ie) {
|
|
LOG.warn("BPOfferService for " + this + " interrupted");
|
|
LOG.warn("BPOfferService for " + this + " interrupted");
|
|
}
|
|
}
|