|
40 | 40 | import org.apache.hadoop.hdfs.protocol.BlockListAsLongs; |
41 | 41 | import org.apache.hadoop.hdfs.protocol.BlockType; |
42 | 42 | import org.apache.hadoop.hdfs.protocol.DatanodeInfo; |
| 43 | +import org.apache.hadoop.hdfs.protocol.ErasureCodingPolicy; |
43 | 44 | import org.apache.hadoop.hdfs.protocol.ExtendedBlock; |
44 | 45 | import org.apache.hadoop.hdfs.protocol.LocatedBlock; |
45 | 46 | import org.apache.hadoop.hdfs.protocol.LocatedBlocks; |
|
67 | 68 | import org.apache.hadoop.hdfs.server.protocol.StorageReport; |
68 | 69 | import org.apache.hadoop.io.EnumSetWritable; |
69 | 70 | import org.apache.hadoop.io.IOUtils; |
| 71 | +import org.apache.hadoop.io.erasurecode.ECSchema; |
70 | 72 | import org.apache.hadoop.ipc.RemoteException; |
71 | 73 | import org.apache.hadoop.metrics2.MetricsRecordBuilder; |
72 | 74 | import org.apache.hadoop.net.NetworkTopology; |
@@ -685,6 +687,67 @@ public void testHighestPriReplSrcChosenDespiteMaxReplLimit() throws Exception { |
685 | 687 | LowRedundancyBlocks.QUEUE_HIGHEST_PRIORITY).length); |
686 | 688 | } |
687 | 689 |
|
| 690 | + @Test |
| 691 | + public void testChooseSrcDatanodesWithDupEC() throws Exception { |
| 692 | + bm.maxReplicationStreams = 4; |
| 693 | + |
| 694 | + long blockId = -9223372036854775776L; // real ec block id |
| 695 | + Block aBlock = new Block(blockId, 0, 0); |
| 696 | + // ec policy |
| 697 | + ECSchema rsSchema = new ECSchema("rs", 3, 2); |
| 698 | + String policyName = "RS-3-2-128k"; |
| 699 | + int cellSize = 128 * 1024; |
| 700 | + ErasureCodingPolicy ecPolicy = |
| 701 | + new ErasureCodingPolicy(policyName, rsSchema, cellSize, (byte) -1); |
| 702 | + // striped blockInfo |
| 703 | + BlockInfoStriped aBlockInfoStriped = new BlockInfoStriped(aBlock, ecPolicy); |
| 704 | + // ec storageInfo |
| 705 | + DatanodeStorageInfo ds1 = DFSTestUtil.createDatanodeStorageInfo( |
| 706 | + "storage1", "1.1.1.1", "rack1", "host1"); |
| 707 | + DatanodeStorageInfo ds2 = DFSTestUtil.createDatanodeStorageInfo( |
| 708 | + "storage2", "2.2.2.2", "rack2", "host2"); |
| 709 | + DatanodeStorageInfo ds3 = DFSTestUtil.createDatanodeStorageInfo( |
| 710 | + "storage3", "3.3.3.3", "rack3", "host3"); |
| 711 | + DatanodeStorageInfo ds4 = DFSTestUtil.createDatanodeStorageInfo( |
| 712 | + "storage4", "4.4.4.4", "rack4", "host4"); |
| 713 | + DatanodeStorageInfo ds5 = DFSTestUtil.createDatanodeStorageInfo( |
| 714 | + "storage5", "5.5.5.5", "rack5", "host5"); |
| 715 | + // link block with storage |
| 716 | + aBlockInfoStriped.addStorage(ds1, aBlock); |
| 717 | + aBlockInfoStriped.addStorage(ds2, new Block(blockId + 1, 0, 0)); |
| 718 | + aBlockInfoStriped.addStorage(ds3, new Block(blockId + 2, 0, 0)); |
| 719 | + // dup internal block |
| 720 | + aBlockInfoStriped.addStorage(ds4, new Block(blockId + 3, 0, 0)); |
| 721 | + aBlockInfoStriped.addStorage(ds5, new Block(blockId + 3, 0, 0)); |
| 722 | + // simulate the node 2 arrive maxReplicationStreams |
| 723 | + for(int i = 0; i < 4; i++){ |
| 724 | + ds4.getDatanodeDescriptor().incrementPendingReplicationWithoutTargets(); |
| 725 | + } |
| 726 | + |
| 727 | + addEcBlockToBM(blockId, ecPolicy); |
| 728 | + List<DatanodeDescriptor> cntNodes = new LinkedList<DatanodeDescriptor>(); |
| 729 | + List<DatanodeStorageInfo> liveNodes = new LinkedList<DatanodeStorageInfo>(); |
| 730 | + NumberReplicas numReplicas = new NumberReplicas(); |
| 731 | + List<Byte> liveBlockIndices = new ArrayList<>(); |
| 732 | + |
| 733 | + bm.chooseSourceDatanodes( |
| 734 | + aBlockInfoStriped, |
| 735 | + cntNodes, |
| 736 | + liveNodes, |
| 737 | + numReplicas, liveBlockIndices, |
| 738 | + LowRedundancyBlocks.QUEUE_HIGHEST_PRIORITY); |
| 739 | + |
| 740 | + assertEquals("Choose the source node for reconstruction with one node reach" |
| 741 | + + " the MAX maxReplicationStreams, the numReplicas still return the" |
| 742 | + + " correct live replicas.", 4, |
| 743 | + numReplicas.liveReplicas()); |
| 744 | + |
| 745 | + assertEquals("Choose the source node for reconstruction with one node reach" |
| 746 | + + " the MAX maxReplicationStreams, the numReplicas should return" |
| 747 | + + " the correct redundant Internal Blocks.", 1, |
| 748 | + numReplicas.redundantInternalBlocks()); |
| 749 | + } |
| 750 | + |
688 | 751 | @Test |
689 | 752 | public void testFavorDecomUntilHardLimit() throws Exception { |
690 | 753 | bm.maxReplicationStreams = 0; |
@@ -979,6 +1042,17 @@ public void testUCBlockNotConsideredMissing() throws Exception { |
979 | 1042 | bm.setInitializedReplQueues(false); |
980 | 1043 | } |
981 | 1044 |
|
| 1045 | + private BlockInfo addEcBlockToBM(long blkId, ErasureCodingPolicy ecPolicy) { |
| 1046 | + Block block = new Block(blkId); |
| 1047 | + BlockInfo blockInfo = new BlockInfoStriped(block, ecPolicy); |
| 1048 | + long inodeId = ++mockINodeId; |
| 1049 | + final INodeFile bc = TestINodeFile.createINodeFile(inodeId); |
| 1050 | + bm.blocksMap.addBlockCollection(blockInfo, bc); |
| 1051 | + blockInfo.setBlockCollectionId(inodeId); |
| 1052 | + doReturn(bc).when(fsn).getBlockCollection(inodeId); |
| 1053 | + return blockInfo; |
| 1054 | + } |
| 1055 | + |
982 | 1056 | private BlockInfo addBlockToBM(long blkId) { |
983 | 1057 | Block block = new Block(blkId); |
984 | 1058 | BlockInfo blockInfo = new BlockInfoContiguous(block, (short) 3); |
|
0 commit comments