@Override
    public Void call() {
      if (this.sink.isStopped()) {
        return null;
      }
      TableName tableName = null;
      Table table = null;
      Get get = null;
      byte[] startKey = null;
      Scan scan = null;
      StopWatch stopWatch = new StopWatch();
      // monitor one region on every region server
      stopWatch.reset();
      try {
        tableName = region.getTable();
        table = connection.getTable(tableName);
        startKey = region.getStartKey();
        // Can't do a get on empty start row so do a Scan of first element if any instead.
        LOG.debug("Reading from {} {} {} {}", serverName, region.getTable(),
          region.getRegionNameAsString(), Bytes.toStringBinary(startKey));
        if (startKey.length > 0) {
          get = new Get(startKey);
          get.setCacheBlocks(false);
          get.setFilter(new FirstKeyOnlyFilter());
          // Converting get object to scan to enable RAW SCAN.
          // This will work for all the regions of the HBase tables except first region.
          scan = new Scan(get);

        } else {
          scan = new Scan();
          // In case of first region of the HBase Table, we do not have start-key for the region.
          // For Region Canary, we only need scan a single row/cell in the region to make sure that
          // region is accessible.
          //
          // When HBase table has more than 1 empty regions at start of the row-key space, Canary
          // will create multiple scan object to find first available row in the table by scanning
          // all the regions in sequence until it can find first available row.
          //
          // Since First region of the table doesn't have any start key, We should set End Key as
          // stop row and set inclusive=false to limit scan to first region only.
          scan.withStopRow(region.getEndKey(), false);
          scan.setCacheBlocks(false);
          scan.setFilter(new FirstKeyOnlyFilter());
          scan.setCaching(1);
          scan.setMaxResultSize(1L);
          scan.setOneRowLimit();
        }
        scan.setRaw(rawScanEnabled);
        stopWatch.start();
        ResultScanner s = table.getScanner(scan);
        s.next();
        s.close();
        stopWatch.stop();
        successes.incrementAndGet();
        sink.publishReadTiming(tableName.getNameAsString(), serverName, stopWatch.getTime());
      } catch (TableNotFoundException tnfe) {
        LOG.error("Table may be deleted", tnfe);
        // This is ignored because it doesn't imply that the regionserver is dead
      } catch (TableNotEnabledException tnee) {
        // This is considered a success since we got a response.
        successes.incrementAndGet();
        LOG.debug("The targeted table was disabled.  Assuming success.");
      } catch (DoNotRetryIOException dnrioe) {
        sink.publishReadFailure(tableName.getNameAsString(), serverName);
        LOG.error(dnrioe.toString(), dnrioe);
      } catch (IOException e) {
        sink.publishReadFailure(tableName.getNameAsString(), serverName);
        LOG.error(e.toString(), e);
      } finally {
        if (table != null) {
          try {
            table.close();
          } catch (IOException e) {/* DO NOTHING */
            LOG.error("Close table failed", e);
          }
        }
        scan = null;
        get = null;
        startKey = null;
      }
      return null;
    }
Run a single RegionServer Task and then exit. Get one row from a region on the regionserver and
output latency or the failure.
hbase-server/src/main/java/org/apache/hadoop/hbase/tool/CanaryTool.java