Example #1
0
 @Before
 public void setup() throws IOException {
   TEST_UTIL = HBaseTestingUtility.createLocalHTU();
   CONF = TEST_UTIL.getConfiguration();
   // Disable block cache.
   CONF.setFloat(HConstants.HFILE_BLOCK_CACHE_SIZE_KEY, 0f);
   dir = TEST_UTIL.getDataTestDir("TestHRegion").toString();
   tableName = TableName.valueOf(name.getMethodName());
 }
  @Before
  public void setUp() throws Exception {

    File tempDir = Files.createTempDir();
    tempDir.deleteOnExit();

    htu = HBaseTestingUtility.createLocalHTU();
    try {
      htu.cleanupTestDir();

      htu.startMiniZKCluster();
      htu.startMiniHBaseCluster(1, 1);

      try {
        htu.deleteTable(Bytes.toBytes(tableName));
      } catch (Exception e) {
        Log.info(" - no table " + tableName + " found");
      }
      htu.createTable(Bytes.toBytes(tableName), colFam);

      dao =
          new Hbase1OffsetStore.Builder()
              .setHbaseConfiguration(htu.getConfiguration())
              .setOffsetTable(tableName)
              .build();

    } catch (Exception e1) {
      throw new RuntimeException(e1);
    }

    KOM =
        new KafkaOffsetManager.Builder()
            .setOffsetManager(dao)
            .setKafkaBrokerList("localhost:" + kafkaRule.kafkaBrokerPort())
            .setGroupID(testGroupID)
            .setTopic(testTopicName)
            .build();
  }
/** Tests encoded seekers by loading and reading values. */
@Category({IOTests.class, MediumTests.class})
@RunWith(Parameterized.class)
public class TestEncodedSeekers {

  private static final String TABLE_NAME = "encodedSeekersTable";
  private static final String CF_NAME = "encodedSeekersCF";
  private static final byte[] CF_BYTES = Bytes.toBytes(CF_NAME);
  private static final int MAX_VERSIONS = 5;

  private static final int BLOCK_SIZE = 64 * 1024;
  private static final int MIN_VALUE_SIZE = 30;
  private static final int MAX_VALUE_SIZE = 60;
  private static final int NUM_ROWS = 1003;
  private static final int NUM_COLS_PER_ROW = 20;
  private static final int NUM_HFILES = 4;
  private static final int NUM_ROWS_PER_FLUSH = NUM_ROWS / NUM_HFILES;

  private final HBaseTestingUtility testUtil = HBaseTestingUtility.createLocalHTU();
  private final DataBlockEncoding encoding;
  private final boolean includeTags;
  private final boolean compressTags;

  /** Enable when debugging */
  private static final boolean VERBOSE = false;

  @Parameters
  public static Collection<Object[]> parameters() {
    List<Object[]> paramList = new ArrayList<Object[]>();
    for (DataBlockEncoding encoding : DataBlockEncoding.values()) {
      for (boolean includeTags : new boolean[] {false, true}) {
        for (boolean compressTags : new boolean[] {false, true}) {
          paramList.add(new Object[] {encoding, includeTags, compressTags});
        }
      }
    }
    return paramList;
  }

  public TestEncodedSeekers(DataBlockEncoding encoding, boolean includeTags, boolean compressTags) {
    this.encoding = encoding;
    this.includeTags = includeTags;
    this.compressTags = compressTags;
  }

  @Test
  public void testEncodedSeeker() throws IOException {
    System.err.println(
        "Testing encoded seekers for encoding : "
            + encoding
            + ", includeTags : "
            + includeTags
            + ", compressTags : "
            + compressTags);
    if (includeTags) {
      testUtil.getConfiguration().setInt(HFile.FORMAT_VERSION_KEY, 3);
    }
    LruBlockCache cache =
        (LruBlockCache) new CacheConfig(testUtil.getConfiguration()).getBlockCache();
    cache.clearCache();
    // Need to disable default row bloom filter for this test to pass.
    HColumnDescriptor hcd =
        (new HColumnDescriptor(CF_NAME))
            .setMaxVersions(MAX_VERSIONS)
            .setDataBlockEncoding(encoding)
            .setBlocksize(BLOCK_SIZE)
            .setBloomFilterType(BloomType.NONE)
            .setCompressTags(compressTags);
    HRegion region = testUtil.createTestRegion(TABLE_NAME, hcd);

    // write the data, but leave some in the memstore
    doPuts(region);

    // verify correctness when memstore contains data
    doGets(region);

    // verify correctness again after compacting
    region.compactStores();
    doGets(region);

    Map<DataBlockEncoding, Integer> encodingCounts = cache.getEncodingCountsForTest();

    // Ensure that compactions don't pollute the cache with unencoded blocks
    // in case of in-cache-only encoding.
    System.err.println("encodingCounts=" + encodingCounts);
    assertEquals(1, encodingCounts.size());
    DataBlockEncoding encodingInCache = encodingCounts.keySet().iterator().next();
    assertEquals(encoding, encodingInCache);
    assertTrue(encodingCounts.get(encodingInCache) > 0);
  }

  private void doPuts(HRegion region) throws IOException {
    LoadTestKVGenerator dataGenerator = new LoadTestKVGenerator(MIN_VALUE_SIZE, MAX_VALUE_SIZE);
    for (int i = 0; i < NUM_ROWS; ++i) {
      byte[] key = LoadTestKVGenerator.md5PrefixedKey(i).getBytes();
      for (int j = 0; j < NUM_COLS_PER_ROW; ++j) {
        Put put = new Put(key);
        byte[] col = Bytes.toBytes(String.valueOf(j));
        byte[] value = dataGenerator.generateRandomSizeValue(key, col);
        if (includeTags) {
          Tag[] tag = new Tag[1];
          tag[0] = new Tag((byte) 1, "Visibility");
          KeyValue kv = new KeyValue(key, CF_BYTES, col, HConstants.LATEST_TIMESTAMP, value, tag);
          put.add(kv);
        } else {
          put.add(CF_BYTES, col, value);
        }
        if (VERBOSE) {
          KeyValue kvPut = new KeyValue(key, CF_BYTES, col, value);
          System.err.println(Strings.padFront(i + "", ' ', 4) + " " + kvPut);
        }
        region.put(put);
      }
      if (i % NUM_ROWS_PER_FLUSH == 0) {
        region.flushcache();
      }
    }
  }

  private void doGets(HRegion region) throws IOException {
    for (int i = 0; i < NUM_ROWS; ++i) {
      final byte[] rowKey = LoadTestKVGenerator.md5PrefixedKey(i).getBytes();
      for (int j = 0; j < NUM_COLS_PER_ROW; ++j) {
        final String qualStr = String.valueOf(j);
        if (VERBOSE) {
          System.err.println(
              "Reading row " + i + ", column " + j + " " + Bytes.toString(rowKey) + "/" + qualStr);
        }
        final byte[] qualBytes = Bytes.toBytes(qualStr);
        Get get = new Get(rowKey);
        get.addColumn(CF_BYTES, qualBytes);
        Result result = region.get(get);
        assertEquals(1, result.size());
        byte[] value = result.getValue(CF_BYTES, qualBytes);
        assertTrue(LoadTestKVGenerator.verify(value, rowKey, qualBytes));
      }
    }
  }
}
/** Test of the {@link CloseRegionHandler}. */
@Category(MediumTests.class)
public class TestCloseRegionHandler {
  static final Log LOG = LogFactory.getLog(TestCloseRegionHandler.class);
  private static final HBaseTestingUtility HTU = HBaseTestingUtility.createLocalHTU();
  private static final HTableDescriptor TEST_HTD =
      new HTableDescriptor(TableName.valueOf("TestCloseRegionHandler"));
  private HRegionInfo TEST_HRI;
  private int testIndex = 0;

  @BeforeClass
  public static void before() throws Exception {
    HTU.startMiniZKCluster();
  }

  @AfterClass
  public static void after() throws IOException {
    HTU.shutdownMiniZKCluster();
  }

  /**
   * Before each test, use a different HRI, so the different tests don't interfere with each other.
   * This allows us to use just a single ZK cluster for the whole suite.
   */
  @Before
  public void setupHRI() {
    TEST_HRI =
        new HRegionInfo(
            TEST_HTD.getTableName(), Bytes.toBytes(testIndex), Bytes.toBytes(testIndex + 1));
    testIndex++;
  }

  /**
   * Test that if we fail a flush, abort gets set on close.
   *
   * @see <a href="https://issues.apache.org/jira/browse/HBASE-4270">HBASE-4270</a>
   * @throws IOException
   * @throws NodeExistsException
   * @throws KeeperException
   */
  @Test
  public void testFailedFlushAborts() throws IOException, NodeExistsException, KeeperException {
    final Server server = new MockServer(HTU, false);
    final RegionServerServices rss = HTU.createMockRegionServerService();
    HTableDescriptor htd = TEST_HTD;
    final HRegionInfo hri =
        new HRegionInfo(htd.getTableName(), HConstants.EMPTY_END_ROW, HConstants.EMPTY_END_ROW);
    HRegion region = HTU.createLocalHRegion(hri, htd);
    try {
      assertNotNull(region);
      // Spy on the region so can throw exception when close is called.
      HRegion spy = Mockito.spy(region);
      final boolean abort = false;
      Mockito.when(spy.close(abort)).thenThrow(new RuntimeException("Mocked failed close!"));
      // The CloseRegionHandler will try to get an HRegion that corresponds
      // to the passed hri -- so insert the region into the online region Set.
      rss.addToOnlineRegions(spy);
      // Assert the Server is NOT stopped before we call close region.
      assertFalse(server.isStopped());
      CloseRegionHandler handler = new CloseRegionHandler(server, rss, hri, false, false, -1);
      boolean throwable = false;
      try {
        handler.process();
      } catch (Throwable t) {
        throwable = true;
      } finally {
        assertTrue(throwable);
        // Abort calls stop so stopped flag should be set.
        assertTrue(server.isStopped());
      }
    } finally {
      HRegion.closeHRegion(region);
    }
  }

  /**
   * Test if close region can handle ZK closing node version mismatch
   *
   * @throws IOException
   * @throws NodeExistsException
   * @throws KeeperException
   * @throws DeserializationException
   */
  @Test
  public void testZKClosingNodeVersionMismatch()
      throws IOException, NodeExistsException, KeeperException, DeserializationException {
    final Server server = new MockServer(HTU);
    final RegionServerServices rss = HTU.createMockRegionServerService();

    HTableDescriptor htd = TEST_HTD;
    final HRegionInfo hri = TEST_HRI;

    // open a region first so that it can be closed later
    OpenRegion(server, rss, htd, hri);

    // close the region
    // Create it CLOSING, which is what Master set before sending CLOSE RPC
    int versionOfClosingNode =
        ZKAssign.createNodeClosing(server.getZooKeeper(), hri, server.getServerName());

    // The CloseRegionHandler will validate the expected version
    // Given it is set to invalid versionOfClosingNode+1,
    // CloseRegionHandler should be M_ZK_REGION_CLOSING
    CloseRegionHandler handler =
        new CloseRegionHandler(server, rss, hri, false, true, versionOfClosingNode + 1);
    handler.process();

    // Handler should remain in M_ZK_REGION_CLOSING
    RegionTransition rt =
        RegionTransition.parseFrom(ZKAssign.getData(server.getZooKeeper(), hri.getEncodedName()));
    assertTrue(rt.getEventType().equals(EventType.M_ZK_REGION_CLOSING));
  }

  /**
   * Test if the region can be closed properly
   *
   * @throws IOException
   * @throws NodeExistsException
   * @throws KeeperException
   * @throws org.apache.hadoop.hbase.exceptions.DeserializationException
   */
  @Test
  public void testCloseRegion()
      throws IOException, NodeExistsException, KeeperException, DeserializationException {
    final Server server = new MockServer(HTU);
    final RegionServerServices rss = HTU.createMockRegionServerService();

    HTableDescriptor htd = TEST_HTD;
    HRegionInfo hri = TEST_HRI;

    // open a region first so that it can be closed later
    OpenRegion(server, rss, htd, hri);

    // close the region
    // Create it CLOSING, which is what Master set before sending CLOSE RPC
    int versionOfClosingNode =
        ZKAssign.createNodeClosing(server.getZooKeeper(), hri, server.getServerName());

    // The CloseRegionHandler will validate the expected version
    // Given it is set to correct versionOfClosingNode,
    // CloseRegionHandlerit should be RS_ZK_REGION_CLOSED
    CloseRegionHandler handler =
        new CloseRegionHandler(server, rss, hri, false, true, versionOfClosingNode);
    handler.process();
    // Handler should have transitioned it to RS_ZK_REGION_CLOSED
    RegionTransition rt =
        RegionTransition.parseFrom(ZKAssign.getData(server.getZooKeeper(), hri.getEncodedName()));
    assertTrue(rt.getEventType().equals(EventType.RS_ZK_REGION_CLOSED));
  }

  private void OpenRegion(
      Server server, RegionServerServices rss, HTableDescriptor htd, HRegionInfo hri)
      throws IOException, NodeExistsException, KeeperException, DeserializationException {
    // Create it OFFLINE node, which is what Master set before sending OPEN RPC
    ZKAssign.createNodeOffline(server.getZooKeeper(), hri, server.getServerName());
    OpenRegionHandler openHandler = new OpenRegionHandler(server, rss, hri, htd);
    rss.getRegionsInTransitionInRS().put(hri.getEncodedNameAsBytes(), Boolean.TRUE);
    openHandler.process();
    // This parse is not used?
    RegionTransition.parseFrom(ZKAssign.getData(server.getZooKeeper(), hri.getEncodedName()));
    // delete the node, which is what Master do after the region is opened
    ZKAssign.deleteNode(
        server.getZooKeeper(),
        hri.getEncodedName(),
        EventType.RS_ZK_REGION_OPENED,
        server.getServerName());
  }
}