|  | 
| 45 | 45 | import java.io.IOException; | 
| 46 | 46 | import java.io.InterruptedIOException; | 
| 47 | 47 | import java.nio.ByteBuffer; | 
|  | 48 | +import java.util.ArrayList; | 
| 48 | 49 | import java.util.Arrays; | 
|  | 50 | +import java.util.Collections; | 
| 49 | 51 | import java.util.EnumSet; | 
|  | 52 | +import java.util.List; | 
| 50 | 53 | import java.util.Set; | 
| 51 | 54 | import java.util.Collection; | 
| 52 | 55 | import java.util.Map; | 
| @@ -154,6 +157,17 @@ void skip() { | 
| 154 | 157 |   private StripeRange curStripeRange; | 
| 155 | 158 |   private final CompletionService<Void> readingService; | 
| 156 | 159 | 
 | 
|  | 160 | +  /** | 
|  | 161 | +   * When warning the user of a lost block in striping mode, we remember the | 
|  | 162 | +   * dead nodes we've logged. All other striping blocks on these nodes can be | 
|  | 163 | +   * considered lost too, and we don't want to log a warning for each of them. | 
|  | 164 | +   * This is to prevent the log from being too verbose. Refer to HDFS-8920. | 
|  | 165 | +   * | 
|  | 166 | +   * To minimize the overhead, we only store the datanodeUuid in this set | 
|  | 167 | +   */ | 
|  | 168 | +  private final Set<String> warnedNodes = Collections.newSetFromMap( | 
|  | 169 | +      new ConcurrentHashMap<String, Boolean>()); | 
|  | 170 | + | 
| 157 | 171 |   DFSStripedInputStream(DFSClient dfsClient, String src, | 
| 158 | 172 |       boolean verifyChecksum, ErasureCodingPolicy ecPolicy, | 
| 159 | 173 |       LocatedBlocks locatedBlocks) throws IOException { | 
| @@ -527,6 +541,26 @@ protected void fetchBlockByteRange(LocatedBlock block, long start, | 
| 527 | 541 |     } | 
| 528 | 542 |   } | 
| 529 | 543 | 
 | 
|  | 544 | +  @Override | 
|  | 545 | +  protected void reportLostBlock(LocatedBlock lostBlock, | 
|  | 546 | +      Collection<DatanodeInfo> ignoredNodes) { | 
|  | 547 | +    DatanodeInfo[] nodes = lostBlock.getLocations(); | 
|  | 548 | +    if (nodes != null && nodes.length > 0) { | 
|  | 549 | +      List<String> dnUUIDs = new ArrayList<>(); | 
|  | 550 | +      for (DatanodeInfo node : nodes) { | 
|  | 551 | +        dnUUIDs.add(node.getDatanodeUuid()); | 
|  | 552 | +      } | 
|  | 553 | +      if (!warnedNodes.containsAll(dnUUIDs)) { | 
|  | 554 | +        DFSClient.LOG.warn(Arrays.toString(nodes) + " are unavailable and " + | 
|  | 555 | +            "all striping blocks on them are lost. " + | 
|  | 556 | +            "IgnoredNodes = " + ignoredNodes); | 
|  | 557 | +        warnedNodes.addAll(dnUUIDs); | 
|  | 558 | +      } | 
|  | 559 | +    } else { | 
|  | 560 | +      super.reportLostBlock(lostBlock, ignoredNodes); | 
|  | 561 | +    } | 
|  | 562 | +  } | 
|  | 563 | + | 
| 530 | 564 |   /** | 
| 531 | 565 |    * The reader for reading a complete {@link AlignedStripe}. Note that an | 
| 532 | 566 |    * {@link AlignedStripe} may cross multiple stripes with cellSize width. | 
|  | 
0 commit comments