Skip to content

Commit 74b8867

Browse files
committed
HBASE-30204 Split TestClearRegionBlockCache by cache type to avoid pe… (#8310)
Signed-off-by: Duo Zhang <zhangduo@apache.org>
1 parent df9843f commit 74b8867

3 files changed

Lines changed: 232 additions & 157 deletions

File tree

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
package org.apache.hadoop.hbase.regionserver;
19+
20+
import static org.junit.jupiter.api.Assertions.assertEquals;
21+
22+
import java.io.IOException;
23+
import java.util.ArrayList;
24+
import java.util.List;
25+
import org.apache.hadoop.hbase.CacheEvictionStats;
26+
import org.apache.hadoop.hbase.Cell;
27+
import org.apache.hadoop.hbase.HBaseTestingUtil;
28+
import org.apache.hadoop.hbase.HConstants;
29+
import org.apache.hadoop.hbase.TableName;
30+
import org.apache.hadoop.hbase.client.Admin;
31+
import org.apache.hadoop.hbase.client.AsyncAdmin;
32+
import org.apache.hadoop.hbase.client.AsyncConnection;
33+
import org.apache.hadoop.hbase.client.ConnectionFactory;
34+
import org.apache.hadoop.hbase.client.Scan;
35+
import org.apache.hadoop.hbase.client.Table;
36+
import org.apache.hadoop.hbase.io.hfile.BlockCache;
37+
import org.apache.hadoop.hbase.util.Bytes;
38+
import org.junit.jupiter.api.BeforeEach;
39+
import org.junit.jupiter.api.Test;
40+
41+
public abstract class ClearRegionBlockCacheTestBase {
42+
43+
private static final byte[] FAMILY = Bytes.toBytes("family");
44+
private static final byte[][] SPLIT_KEY = new byte[][] { Bytes.toBytes("5") };
45+
private static final int NUM_RS = 2;
46+
47+
private static TableName tableName;
48+
private static HBaseTestingUtil htu;
49+
private static HRegionServer rs1;
50+
private static HRegionServer rs2;
51+
52+
protected static void setUpCluster(TableName testTableName) throws Exception {
53+
setUpCluster(testTableName, false);
54+
}
55+
56+
protected static void setUpBucketCacheCluster(TableName testTableName) throws Exception {
57+
setUpCluster(testTableName, true);
58+
}
59+
60+
private static void setUpCluster(TableName testTableName, boolean bucketCache) throws Exception {
61+
tableName = testTableName;
62+
htu = new HBaseTestingUtil();
63+
if (bucketCache) {
64+
htu.getConfiguration().set(HConstants.BUCKET_CACHE_IOENGINE_KEY, "offheap");
65+
htu.getConfiguration().setInt(HConstants.BUCKET_CACHE_SIZE_KEY, 30);
66+
}
67+
htu.startMiniCluster(NUM_RS);
68+
rs1 = htu.getMiniHBaseCluster().getRegionServer(0);
69+
rs2 = htu.getMiniHBaseCluster().getRegionServer(1);
70+
71+
try (Table table = htu.createTable(testTableName, FAMILY, SPLIT_KEY)) {
72+
htu.loadNumericRows(table, FAMILY, 1, 10);
73+
htu.flush(testTableName);
74+
}
75+
}
76+
77+
protected static void tearDownCluster() throws Exception {
78+
if (htu != null) {
79+
htu.shutdownMiniCluster();
80+
}
81+
}
82+
83+
@BeforeEach
84+
void clearBlockCacheBeforeTest() {
85+
clearRegionBlockCache(rs1);
86+
clearRegionBlockCache(rs2);
87+
}
88+
89+
@Test
90+
void testClearBlockCache() throws Exception {
91+
BlockCache blockCache1 = rs1.getBlockCache().get();
92+
BlockCache blockCache2 = rs2.getBlockCache().get();
93+
94+
long initialBlockCount1 = blockCache1.getBlockCount();
95+
long initialBlockCount2 = blockCache2.getBlockCount();
96+
97+
// scan will cause blocks to be added in BlockCache
98+
scanAllRegionsForRS(rs1);
99+
assertEquals(blockCache1.getBlockCount() - initialBlockCount1,
100+
htu.getNumHFilesForRS(rs1, tableName, FAMILY));
101+
clearRegionBlockCache(rs1);
102+
103+
scanAllRegionsForRS(rs2);
104+
assertEquals(blockCache2.getBlockCount() - initialBlockCount2,
105+
htu.getNumHFilesForRS(rs2, tableName, FAMILY));
106+
clearRegionBlockCache(rs2);
107+
108+
assertEquals(initialBlockCount1, blockCache1.getBlockCount(), "" + blockCache1.getBlockCount());
109+
assertEquals(initialBlockCount2, blockCache2.getBlockCount(), "" + blockCache2.getBlockCount());
110+
}
111+
112+
@Test
113+
void testClearBlockCacheFromAdmin() throws Exception {
114+
Admin admin = htu.getAdmin();
115+
116+
BlockCache blockCache1 = rs1.getBlockCache().get();
117+
BlockCache blockCache2 = rs2.getBlockCache().get();
118+
long initialBlockCount1 = blockCache1.getBlockCount();
119+
long initialBlockCount2 = blockCache2.getBlockCount();
120+
121+
// scan will cause blocks to be added in BlockCache
122+
scanAllRegionsForRS(rs1);
123+
assertEquals(blockCache1.getBlockCount() - initialBlockCount1,
124+
htu.getNumHFilesForRS(rs1, tableName, FAMILY));
125+
scanAllRegionsForRS(rs2);
126+
assertEquals(blockCache2.getBlockCount() - initialBlockCount2,
127+
htu.getNumHFilesForRS(rs2, tableName, FAMILY));
128+
129+
CacheEvictionStats stats = admin.clearBlockCache(tableName);
130+
assertEquals(
131+
htu.getNumHFilesForRS(rs1, tableName, FAMILY) + htu.getNumHFilesForRS(rs2, tableName, FAMILY),
132+
stats.getEvictedBlocks());
133+
assertEquals(initialBlockCount1, blockCache1.getBlockCount());
134+
assertEquals(initialBlockCount2, blockCache2.getBlockCount());
135+
}
136+
137+
@Test
138+
void testClearBlockCacheFromAsyncAdmin() throws Exception {
139+
try (AsyncConnection conn =
140+
ConnectionFactory.createAsyncConnection(htu.getConfiguration()).get()) {
141+
AsyncAdmin admin = conn.getAdmin();
142+
143+
BlockCache blockCache1 = rs1.getBlockCache().get();
144+
BlockCache blockCache2 = rs2.getBlockCache().get();
145+
long initialBlockCount1 = blockCache1.getBlockCount();
146+
long initialBlockCount2 = blockCache2.getBlockCount();
147+
148+
// scan will cause blocks to be added in BlockCache
149+
scanAllRegionsForRS(rs1);
150+
assertEquals(blockCache1.getBlockCount() - initialBlockCount1,
151+
htu.getNumHFilesForRS(rs1, tableName, FAMILY));
152+
scanAllRegionsForRS(rs2);
153+
assertEquals(blockCache2.getBlockCount() - initialBlockCount2,
154+
htu.getNumHFilesForRS(rs2, tableName, FAMILY));
155+
156+
CacheEvictionStats stats = admin.clearBlockCache(tableName).get();
157+
assertEquals(htu.getNumHFilesForRS(rs1, tableName, FAMILY)
158+
+ htu.getNumHFilesForRS(rs2, tableName, FAMILY), stats.getEvictedBlocks());
159+
assertEquals(initialBlockCount1, blockCache1.getBlockCount());
160+
assertEquals(initialBlockCount2, blockCache2.getBlockCount());
161+
}
162+
}
163+
164+
private void scanAllRegionsForRS(HRegionServer rs) throws IOException {
165+
for (Region region : rs.getRegions(tableName)) {
166+
try (RegionScanner scanner = region.getScanner(new Scan())) {
167+
List<Cell> cells = new ArrayList<>();
168+
while (scanner.next(cells)) {
169+
cells.clear();
170+
}
171+
}
172+
}
173+
}
174+
175+
private void clearRegionBlockCache(HRegionServer rs) {
176+
for (Region region : rs.getRegions(tableName)) {
177+
rs.clearRegionBlockCache(region);
178+
}
179+
}
180+
}

hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestClearRegionBlockCache.java

Lines changed: 11 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -17,171 +17,25 @@
1717
*/
1818
package org.apache.hadoop.hbase.regionserver;
1919

20-
import static org.junit.jupiter.api.Assertions.assertEquals;
21-
22-
import java.io.IOException;
23-
import java.util.ArrayList;
24-
import java.util.stream.Stream;
25-
import org.apache.hadoop.conf.Configuration;
26-
import org.apache.hadoop.hbase.CacheEvictionStats;
27-
import org.apache.hadoop.hbase.Cell;
28-
import org.apache.hadoop.hbase.HBaseParameterizedTestTemplate;
29-
import org.apache.hadoop.hbase.HBaseTestingUtil;
30-
import org.apache.hadoop.hbase.HConstants;
31-
import org.apache.hadoop.hbase.SingleProcessHBaseCluster;
3220
import org.apache.hadoop.hbase.TableName;
33-
import org.apache.hadoop.hbase.client.Admin;
34-
import org.apache.hadoop.hbase.client.AsyncAdmin;
35-
import org.apache.hadoop.hbase.client.AsyncConnection;
36-
import org.apache.hadoop.hbase.client.ConnectionFactory;
37-
import org.apache.hadoop.hbase.client.Scan;
38-
import org.apache.hadoop.hbase.client.Table;
39-
import org.apache.hadoop.hbase.io.hfile.BlockCache;
4021
import org.apache.hadoop.hbase.testclassification.LargeTests;
41-
import org.apache.hadoop.hbase.util.Bytes;
42-
import org.junit.jupiter.api.AfterEach;
43-
import org.junit.jupiter.api.BeforeEach;
22+
import org.junit.jupiter.api.AfterAll;
23+
import org.junit.jupiter.api.BeforeAll;
4424
import org.junit.jupiter.api.Tag;
45-
import org.junit.jupiter.api.TestTemplate;
46-
import org.junit.jupiter.params.provider.Arguments;
47-
import org.slf4j.Logger;
48-
import org.slf4j.LoggerFactory;
4925

5026
@Tag(LargeTests.TAG)
51-
@HBaseParameterizedTestTemplate(name = "{index}: {0}")
52-
public class TestClearRegionBlockCache {
53-
54-
private static final Logger LOG = LoggerFactory.getLogger(TestClearRegionBlockCache.class);
55-
private static final TableName TABLE_NAME = TableName.valueOf("testClearRegionBlockCache");
56-
private static final byte[] FAMILY = Bytes.toBytes("family");
57-
private static final byte[][] SPLIT_KEY = new byte[][] { Bytes.toBytes("5") };
58-
private static final int NUM_RS = 2;
59-
60-
private final HBaseTestingUtil HTU = new HBaseTestingUtil();
61-
62-
private Configuration CONF = HTU.getConfiguration();
63-
private Table table;
64-
private HRegionServer rs1, rs2;
65-
private SingleProcessHBaseCluster cluster;
66-
67-
private final String cacheType;
68-
69-
public TestClearRegionBlockCache(String cacheType) {
70-
this.cacheType = cacheType;
71-
}
72-
73-
public static Stream<Arguments> parameters() {
74-
return Stream.of(Arguments.of("lru"), Arguments.of("bucket"));
75-
}
76-
77-
@BeforeEach
78-
public void setup() throws Exception {
79-
if (cacheType.equals("bucket")) {
80-
CONF.set(HConstants.BUCKET_CACHE_IOENGINE_KEY, "offheap");
81-
CONF.setInt(HConstants.BUCKET_CACHE_SIZE_KEY, 30);
82-
}
83-
84-
cluster = HTU.startMiniCluster(NUM_RS);
85-
rs1 = cluster.getRegionServer(0);
86-
rs2 = cluster.getRegionServer(1);
87-
88-
// Create table
89-
table = HTU.createTable(TABLE_NAME, FAMILY, SPLIT_KEY);
90-
91-
HTU.loadNumericRows(table, FAMILY, 1, 10);
92-
HTU.flush(TABLE_NAME);
93-
}
94-
95-
@AfterEach
96-
public void teardown() throws Exception {
97-
HTU.shutdownMiniCluster();
98-
}
27+
public class TestClearRegionBlockCache extends ClearRegionBlockCacheTestBase {
9928

100-
@TestTemplate
101-
public void testClearBlockCache() throws Exception {
102-
BlockCache blockCache1 = rs1.getBlockCache().get();
103-
BlockCache blockCache2 = rs2.getBlockCache().get();
104-
105-
long initialBlockCount1 = blockCache1.getBlockCount();
106-
long initialBlockCount2 = blockCache2.getBlockCount();
107-
108-
// scan will cause blocks to be added in BlockCache
109-
scanAllRegionsForRS(rs1);
110-
assertEquals(blockCache1.getBlockCount() - initialBlockCount1,
111-
HTU.getNumHFilesForRS(rs1, TABLE_NAME, FAMILY));
112-
clearRegionBlockCache(rs1);
113-
114-
scanAllRegionsForRS(rs2);
115-
assertEquals(blockCache2.getBlockCount() - initialBlockCount2,
116-
HTU.getNumHFilesForRS(rs2, TABLE_NAME, FAMILY));
117-
clearRegionBlockCache(rs2);
118-
119-
assertEquals(initialBlockCount1, blockCache1.getBlockCount(), "" + blockCache1.getBlockCount());
120-
assertEquals(initialBlockCount2, blockCache2.getBlockCount(), "" + blockCache2.getBlockCount());
121-
}
122-
123-
@TestTemplate
124-
public void testClearBlockCacheFromAdmin() throws Exception {
125-
Admin admin = HTU.getAdmin();
126-
127-
BlockCache blockCache1 = rs1.getBlockCache().get();
128-
BlockCache blockCache2 = rs2.getBlockCache().get();
129-
long initialBlockCount1 = blockCache1.getBlockCount();
130-
long initialBlockCount2 = blockCache2.getBlockCount();
131-
132-
// scan will cause blocks to be added in BlockCache
133-
scanAllRegionsForRS(rs1);
134-
assertEquals(blockCache1.getBlockCount() - initialBlockCount1,
135-
HTU.getNumHFilesForRS(rs1, TABLE_NAME, FAMILY));
136-
scanAllRegionsForRS(rs2);
137-
assertEquals(blockCache2.getBlockCount() - initialBlockCount2,
138-
HTU.getNumHFilesForRS(rs2, TABLE_NAME, FAMILY));
139-
140-
CacheEvictionStats stats = admin.clearBlockCache(TABLE_NAME);
141-
assertEquals(stats.getEvictedBlocks(), HTU.getNumHFilesForRS(rs1, TABLE_NAME, FAMILY)
142-
+ HTU.getNumHFilesForRS(rs2, TABLE_NAME, FAMILY));
143-
assertEquals(initialBlockCount1, blockCache1.getBlockCount());
144-
assertEquals(initialBlockCount2, blockCache2.getBlockCount());
145-
}
146-
147-
@TestTemplate
148-
public void testClearBlockCacheFromAsyncAdmin() throws Exception {
149-
try (AsyncConnection conn =
150-
ConnectionFactory.createAsyncConnection(HTU.getConfiguration()).get()) {
151-
AsyncAdmin admin = conn.getAdmin();
152-
153-
BlockCache blockCache1 = rs1.getBlockCache().get();
154-
BlockCache blockCache2 = rs2.getBlockCache().get();
155-
long initialBlockCount1 = blockCache1.getBlockCount();
156-
long initialBlockCount2 = blockCache2.getBlockCount();
157-
158-
// scan will cause blocks to be added in BlockCache
159-
scanAllRegionsForRS(rs1);
160-
assertEquals(blockCache1.getBlockCount() - initialBlockCount1,
161-
HTU.getNumHFilesForRS(rs1, TABLE_NAME, FAMILY));
162-
scanAllRegionsForRS(rs2);
163-
assertEquals(blockCache2.getBlockCount() - initialBlockCount2,
164-
HTU.getNumHFilesForRS(rs2, TABLE_NAME, FAMILY));
165-
166-
CacheEvictionStats stats = admin.clearBlockCache(TABLE_NAME).get();
167-
assertEquals(stats.getEvictedBlocks(), HTU.getNumHFilesForRS(rs1, TABLE_NAME, FAMILY)
168-
+ HTU.getNumHFilesForRS(rs2, TABLE_NAME, FAMILY));
169-
assertEquals(initialBlockCount1, blockCache1.getBlockCount());
170-
assertEquals(initialBlockCount2, blockCache2.getBlockCount());
171-
}
172-
}
29+
private static final TableName TABLE_NAME =
30+
TableName.valueOf("testClearRegionBlockCacheWithLruBlockCache");
17331

174-
private void scanAllRegionsForRS(HRegionServer rs) throws IOException {
175-
for (Region region : rs.getRegions(TABLE_NAME)) {
176-
RegionScanner scanner = region.getScanner(new Scan());
177-
while (scanner.next(new ArrayList<Cell>()))
178-
;
179-
}
32+
@BeforeAll
33+
public static void setUp() throws Exception {
34+
setUpCluster(TABLE_NAME);
18035
}
18136

182-
private void clearRegionBlockCache(HRegionServer rs) {
183-
for (Region region : rs.getRegions(TABLE_NAME)) {
184-
rs.clearRegionBlockCache(region);
185-
}
37+
@AfterAll
38+
public static void tearDown() throws Exception {
39+
tearDownCluster();
18640
}
18741
}

0 commit comments

Comments
 (0)