@Override
  public boolean next(List<? super ExtendedCell> outResult, ScannerContext ctx) throws IOException {
    boolean result = super.next(outResult, ctx);
    if (!rawMobScan) {
      // retrieve the mob data
      if (outResult.isEmpty()) {
        return result;
      }
      long mobKVCount = 0;
      long mobKVSize = 0;
      for (int i = 0; i < outResult.size(); i++) {
        ExtendedCell cell = (ExtendedCell) outResult.get(i);
        if (MobUtils.isMobReferenceCell(cell)) {
          MobCell mobCell =
            mobStore.resolve(cell, cacheMobBlocks, readPt, readEmptyValueOnMobCellMiss);
          mobKVCount++;
          mobKVSize += mobCell.getCell().getValueLength();
          outResult.set(i, mobCell.getCell());
          // Keep the MobCell here unless we shipped the RPC or close the scanner.
          referencedMobCells.add(mobCell);
        }
      }
      mobStore.updateMobScanCellsCount(mobKVCount);
      mobStore.updateMobScanCellsSize(mobKVSize);
    }
    return result;
  }
Firstly reads the cells from the HBase. If the cell is a reference cell (which has the
reference tag), the scanner need seek this cell from the mob file, and use the cell found from
the mob file as the result.
hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ReversedMobStoreScanner.java