private static CompletableFuture<Void> scanMeta(AsyncTable<AdvancedScanResultConsumer> metaTable,
    byte[] startRow, byte[] stopRow, QueryType type, int maxRows, final Visitor visitor) {
    int rowUpperLimit = maxRows > 0 ? maxRows : Integer.MAX_VALUE;
    Scan scan = getMetaScan(metaTable, rowUpperLimit);
    for (byte[] family : type.getFamilies()) {
      scan.addFamily(family);
    }
    if (startRow != null) {
      scan.withStartRow(startRow);
    }
    if (stopRow != null) {
      scan.withStopRow(stopRow);
    }

    if (LOG.isDebugEnabled()) {
      LOG.debug("Scanning META" + " starting at row=" + Bytes.toStringBinary(scan.getStartRow())
        + " stopping at row=" + Bytes.toStringBinary(scan.getStopRow()) + " for max="
        + rowUpperLimit + " with caching=" + scan.getCaching());
    }

    CompletableFuture<Void> future = new CompletableFuture<Void>();
    // Get the region locator's meta replica mode.
    CatalogReplicaMode metaReplicaMode = CatalogReplicaMode.fromString(metaTable.getConfiguration()
      .get(LOCATOR_META_REPLICAS_MODE, CatalogReplicaMode.NONE.toString()));

    if (metaReplicaMode == CatalogReplicaMode.LOAD_BALANCE) {
      addListener(metaTable.getDescriptor(), (desc, error) -> {
        if (error != null) {
          LOG.error("Failed to get meta table descriptor, error: ", error);
          future.completeExceptionally(error);
          return;
        }

        int numOfReplicas = desc.getRegionReplication();
        if (numOfReplicas > 1) {
          int replicaId = ThreadLocalRandom.current().nextInt(numOfReplicas);

          // When the replicaId is 0, do not set to Consistency.TIMELINE
          if (replicaId > 0) {
            scan.setReplicaId(replicaId);
            scan.setConsistency(Consistency.TIMELINE);
          }
        }
        metaTable.scan(scan, new MetaTableScanResultConsumer(rowUpperLimit, visitor, future));
      });
    } else {
      if (metaReplicaMode == CatalogReplicaMode.HEDGED_READ) {
        scan.setConsistency(Consistency.TIMELINE);
      }
      metaTable.scan(scan, new MetaTableScanResultConsumer(rowUpperLimit, visitor, future));
    }

    return future;
  }
Performs a scan of META table for given table.
@param metaTable scanner over meta table
@param startRow  Where to start the scan
@param stopRow   Where to stop the scan
@param type      scanned part of meta
@param maxRows   maximum rows to return
@param visitor   Visitor invoked against each row
hbase-client/src/main/java/org/apache/hadoop/hbase/ClientMetaTableAccessor.java