1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.regionserver;
19
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22 import org.apache.hadoop.conf.Configuration;
23 import org.apache.hadoop.hbase.*;
24 import org.apache.hadoop.hbase.client.*;
25 import org.apache.hadoop.hbase.test.MetricsAssertHelper;
26 import org.apache.hadoop.hbase.testclassification.MediumTests;
27 import org.apache.hadoop.hbase.util.Bytes;
28 import org.apache.hadoop.hbase.util.Threads;
29 import org.apache.log4j.Level;
30 import org.apache.log4j.Logger;
31 import org.junit.AfterClass;
32 import org.junit.BeforeClass;
33 import org.junit.Test;
34 import org.junit.experimental.categories.Category;
35 import static org.junit.Assert.*;
36
37 import java.io.IOException;
38 import java.util.ArrayList;
39 import java.util.List;
40
41
42 @Category(MediumTests.class)
43 public class TestRegionServerMetrics {
44 private static final Log LOG = LogFactory.getLog(TestRegionServerMetrics.class);
45 private static MetricsAssertHelper metricsHelper;
46
47 static {
48 Logger.getLogger("org.apache.hadoop.hbase").setLevel(Level.DEBUG);
49 }
50
51 private static MiniHBaseCluster cluster;
52 private static HRegionServer rs;
53 private static Configuration conf;
54 private static HBaseTestingUtility TEST_UTIL;
55 private static MetricsRegionServer metricsRegionServer;
56 private static MetricsRegionServerSource serverSource;
57 private static final int NUM_SCAN_NEXT = 30;
58
59 @BeforeClass
60 public static void startCluster() throws Exception {
61 metricsHelper = CompatibilityFactory.getInstance(MetricsAssertHelper.class);
62 TEST_UTIL = new HBaseTestingUtility();
63 conf = TEST_UTIL.getConfiguration();
64 conf.getLong("hbase.splitlog.max.resubmit", 0);
65
66 conf.setInt("zookeeper.recovery.retry", 0);
67 conf.setInt(HConstants.REGIONSERVER_INFO_PORT, -1);
68
69 TEST_UTIL.startMiniCluster(1, 1);
70 cluster = TEST_UTIL.getHBaseCluster();
71
72 cluster.waitForActiveAndReadyMaster();
73
74 while (cluster.getLiveRegionServerThreads().size() < 1) {
75 Threads.sleep(100);
76 }
77
78 rs = cluster.getRegionServer(0);
79 metricsRegionServer = rs.getMetrics();
80 serverSource = metricsRegionServer.getMetricsSource();
81 }
82
83 @AfterClass
84 public static void after() throws Exception {
85 if (TEST_UTIL != null) {
86 TEST_UTIL.shutdownMiniCluster();
87 }
88 }
89
90 @Test(timeout = 300000)
91 public void testRegionCount() throws Exception {
92 String regionMetricsKey = "regionCount";
93 long regions = metricsHelper.getGaugeLong(regionMetricsKey, serverSource);
94
95 TEST_UTIL.createTable(Bytes.toBytes("table"), Bytes.toBytes("cf"));
96 metricsHelper.assertGaugeGt(regionMetricsKey, regions, serverSource);
97 }
98
99 @Test
100 public void testLocalFiles() throws Exception {
101 metricsHelper.assertGauge("percentFilesLocal", 0, serverSource);
102 }
103
104 @Test
105 public void testRequestCount() throws Exception {
106 String tableNameString = "testRequestCount";
107 byte[] tName = Bytes.toBytes(tableNameString);
108 byte[] cfName = Bytes.toBytes("d");
109 byte[] row = Bytes.toBytes("rk");
110 byte[] qualifier = Bytes.toBytes("qual");
111 byte[] initValue = Bytes.toBytes("Value");
112 byte[] nextValue = Bytes.toBytes("NEXT VAL");
113
114
115 TEST_UTIL.createTable(tName, cfName);
116
117 new HTable(conf, tName).close();
118
119
120 HTable table = new HTable(conf, tName);
121 Put p = new Put(row);
122 p.add(cfName, qualifier, initValue);
123 table.put(p);
124
125 metricsRegionServer.getRegionServerWrapper().forceRecompute();
126 long requests = metricsHelper.getCounter("totalRequestCount", serverSource);
127 long readRequests = metricsHelper.getCounter("readRequestCount", serverSource);
128 long writeRequests = metricsHelper.getCounter("writeRequestCount", serverSource);
129
130 for (int i=0; i< 30; i++) {
131 table.put(p);
132 }
133
134 metricsRegionServer.getRegionServerWrapper().forceRecompute();
135 metricsHelper.assertCounter("totalRequestCount", requests + 30, serverSource);
136 metricsHelper.assertCounter("readRequestCount", readRequests, serverSource);
137 metricsHelper.assertCounter("writeRequestCount", writeRequests + 30, serverSource);
138
139 Get g = new Get(row);
140 for (int i=0; i< 10; i++) {
141 table.get(g);
142 }
143
144 metricsRegionServer.getRegionServerWrapper().forceRecompute();
145 metricsHelper.assertCounter("totalRequestCount", requests + 40, serverSource);
146 metricsHelper.assertCounter("readRequestCount", readRequests + 10, serverSource);
147 metricsHelper.assertCounter("writeRequestCount", writeRequests + 30, serverSource);
148
149 for ( HRegionInfo i:table.getRegionLocations().keySet()) {
150 MetricsRegionAggregateSource agg = rs.getRegion(i.getRegionName())
151 .getMetrics()
152 .getSource()
153 .getAggregateSource();
154 String prefix = "namespace_"+NamespaceDescriptor.DEFAULT_NAMESPACE_NAME_STR+
155 "_table_"+tableNameString +
156 "_region_" + i.getEncodedName()+
157 "_metric";
158 metricsHelper.assertCounter(prefix + "_getNumOps", 10, agg);
159 metricsHelper.assertCounter(prefix + "_mutateCount", 31, agg);
160 }
161
162
163 metricsRegionServer.getRegionServerWrapper().forceRecompute();
164 metricsHelper.assertCounter("totalRequestCount", requests + 40 + 3, serverSource);
165 metricsHelper.assertCounter("readRequestCount", readRequests + 10 + 1, serverSource);
166
167
168 List<Get> gets = new ArrayList<Get>();
169 for (int i=0; i< 10; i++) {
170 gets.add(new Get(row));
171 }
172 table.get(gets);
173
174 metricsRegionServer.getRegionServerWrapper().forceRecompute();
175 metricsHelper.assertCounter("totalRequestCount", requests + 50 + 3, serverSource);
176 metricsHelper.assertCounter("readRequestCount", readRequests + 20 + 1, serverSource);
177 metricsHelper.assertCounter("writeRequestCount", writeRequests + 30, serverSource);
178
179 table.setAutoFlushTo(false);
180 for (int i=0; i< 30; i++) {
181 table.put(p);
182 }
183 table.flushCommits();
184
185 metricsRegionServer.getRegionServerWrapper().forceRecompute();
186 metricsHelper.assertCounter("totalRequestCount", requests + 80 + 3, serverSource);
187 metricsHelper.assertCounter("readRequestCount", readRequests + 20 + 1, serverSource);
188 metricsHelper.assertCounter("writeRequestCount", writeRequests + 60, serverSource);
189
190 table.close();
191 }
192
193 @Test
194 public void testMutationsWithoutWal() throws Exception {
195 byte[] tableName = Bytes.toBytes("testMutationsWithoutWal");
196 byte[] cf = Bytes.toBytes("d");
197 byte[] row = Bytes.toBytes("rk");
198 byte[] qualifier = Bytes.toBytes("qual");
199 byte[] val = Bytes.toBytes("Value");
200
201 metricsRegionServer.getRegionServerWrapper().forceRecompute();
202
203 TEST_UTIL.createTable(tableName, cf);
204
205 HTable t = new HTable(conf, tableName);
206
207 Put p = new Put(row);
208 p.add(cf, qualifier, val);
209 p.setDurability(Durability.SKIP_WAL);
210
211 t.put(p);
212 t.flushCommits();
213
214 metricsRegionServer.getRegionServerWrapper().forceRecompute();
215 metricsHelper.assertGauge("mutationsWithoutWALCount", 1, serverSource);
216 long minLength = row.length + cf.length + qualifier.length + val.length;
217 metricsHelper.assertGaugeGt("mutationsWithoutWALSize", minLength, serverSource);
218
219 t.close();
220 }
221
222 @Test
223 public void testStoreCount() throws Exception {
224 byte[] tableName = Bytes.toBytes("testStoreCount");
225 byte[] cf = Bytes.toBytes("d");
226 byte[] row = Bytes.toBytes("rk");
227 byte[] qualifier = Bytes.toBytes("qual");
228 byte[] val = Bytes.toBytes("Value");
229
230 metricsRegionServer.getRegionServerWrapper().forceRecompute();
231 long stores = metricsHelper.getGaugeLong("storeCount", serverSource);
232 long storeFiles = metricsHelper.getGaugeLong("storeFileCount", serverSource);
233
234 TEST_UTIL.createTable(tableName, cf);
235
236
237 HTable t = new HTable(conf, tableName);
238 Put p = new Put(row);
239 p.add(cf, qualifier, val);
240 t.put(p);
241 t.flushCommits();
242 TEST_UTIL.getHBaseAdmin().flush(tableName);
243
244 metricsRegionServer.getRegionServerWrapper().forceRecompute();
245 metricsHelper.assertGauge("storeCount", stores +1, serverSource);
246 metricsHelper.assertGauge("storeFileCount", storeFiles + 1, serverSource);
247
248 t.close();
249 }
250
251 @Test
252 public void testStoreFileAge() throws Exception {
253 TableName tableName = TableName.valueOf("testStoreFileAge");
254 byte[] cf = Bytes.toBytes("d");
255 byte[] row = Bytes.toBytes("rk");
256 byte[] qualifier = Bytes.toBytes("qual");
257 byte[] val = Bytes.toBytes("Value");
258
259
260 HTable t = TEST_UTIL.createTable(tableName, cf);
261 Put p = new Put(row);
262 p.add(cf, qualifier, val);
263 t.put(p);
264 TEST_UTIL.getHBaseAdmin().flush(tableName.getNameAsString());
265
266 metricsRegionServer.getRegionServerWrapper().forceRecompute();
267 assertTrue(metricsHelper.getGaugeLong("maxStoreFileAge", serverSource) > 0);
268 assertTrue(metricsHelper.getGaugeLong("minStoreFileAge", serverSource) > 0);
269 assertTrue(metricsHelper.getGaugeLong("avgStoreFileAge", serverSource) > 0);
270
271 t.close();
272 }
273
274 @Test
275 public void testCheckAndPutCount() throws Exception {
276 String tableNameString = "testCheckAndPutCount";
277 byte[] tableName = Bytes.toBytes(tableNameString);
278 byte[] cf = Bytes.toBytes("d");
279 byte[] row = Bytes.toBytes("rk");
280 byte[] qualifier = Bytes.toBytes("qual");
281 byte[] valOne = Bytes.toBytes("Value");
282 byte[] valTwo = Bytes.toBytes("ValueTwo");
283 byte[] valThree = Bytes.toBytes("ValueThree");
284
285 TEST_UTIL.createTable(tableName, cf);
286 HTable t = new HTable(conf, tableName);
287 Put p = new Put(row);
288 p.add(cf, qualifier, valOne);
289 t.put(p);
290 t.flushCommits();
291
292 Put pTwo = new Put(row);
293 pTwo.add(cf, qualifier, valTwo);
294 t.checkAndPut(row, cf, qualifier, valOne, pTwo);
295 t.flushCommits();
296
297 Put pThree = new Put(row);
298 pThree.add(cf, qualifier, valThree);
299 t.checkAndPut(row, cf, qualifier, valOne, pThree);
300 t.flushCommits();
301
302
303 metricsRegionServer.getRegionServerWrapper().forceRecompute();
304 metricsHelper.assertCounter("checkMutateFailedCount", 1, serverSource);
305 metricsHelper.assertCounter("checkMutatePassedCount", 1, serverSource);
306
307 t.close();
308 }
309
310 @Test
311 public void testIncrement() throws Exception {
312 String tableNameString = "testIncrement";
313 byte[] tableName = Bytes.toBytes(tableNameString);
314 byte[] cf = Bytes.toBytes("d");
315 byte[] row = Bytes.toBytes("rk");
316 byte[] qualifier = Bytes.toBytes("qual");
317 byte[] val = Bytes.toBytes(0l);
318
319
320 TEST_UTIL.createTable(tableName, cf);
321 HTable t = new HTable(conf, tableName);
322
323 Put p = new Put(row);
324 p.add(cf, qualifier, val);
325 t.put(p);
326 t.flushCommits();
327
328 for(int count = 0; count< 13; count++) {
329 Increment inc = new Increment(row);
330 inc.addColumn(cf, qualifier, 100);
331 t.increment(inc);
332 }
333
334 t.flushCommits();
335
336 metricsRegionServer.getRegionServerWrapper().forceRecompute();
337 metricsHelper.assertCounter("incrementNumOps", 13, serverSource);
338
339 t.close();
340 }
341
342 @Test
343 public void testAppend() throws Exception {
344 String tableNameString = "testAppend";
345 byte[] tableName = Bytes.toBytes(tableNameString);
346 byte[] cf = Bytes.toBytes("d");
347 byte[] row = Bytes.toBytes("rk");
348 byte[] qualifier = Bytes.toBytes("qual");
349 byte[] val = Bytes.toBytes("One");
350
351
352 TEST_UTIL.createTable(tableName, cf);
353 HTable t = new HTable(conf, tableName);
354
355 Put p = new Put(row);
356 p.add(cf, qualifier, val);
357 t.put(p);
358 t.flushCommits();
359
360 for(int count = 0; count< 73; count++) {
361 Append append = new Append(row);
362 append.add(cf, qualifier, Bytes.toBytes(",Test"));
363 t.append(append);
364 }
365
366 t.flushCommits();
367
368 metricsRegionServer.getRegionServerWrapper().forceRecompute();
369 metricsHelper.assertCounter("appendNumOps", 73, serverSource);
370
371 t.close();
372 }
373
374 @Test
375 public void testScanNext() throws IOException {
376 String tableNameString = "testScanNext";
377 byte[] tableName = Bytes.toBytes(tableNameString);
378 byte[] cf = Bytes.toBytes("d");
379 byte[] qualifier = Bytes.toBytes("qual");
380 byte[] val = Bytes.toBytes("One");
381
382 TEST_UTIL.createTable(tableName, cf);
383 HTable t = new HTable(conf, tableName);
384 t.setAutoFlush(false, true);
385 for (int insertCount =0; insertCount < 100; insertCount++) {
386 Put p = new Put(Bytes.toBytes("" + insertCount + "row"));
387 p.add(cf, qualifier, val);
388 t.put(p);
389 }
390 t.flushCommits();
391
392 Scan s = new Scan();
393 s.setBatch(1);
394 s.setCaching(1);
395 ResultScanner resultScanners = t.getScanner(s);
396
397 long numScanNext = metricsHelper.getCounter("ScanNext_num_ops", serverSource);
398 for (int nextCount = 0; nextCount < NUM_SCAN_NEXT; nextCount++) {
399 Result result = resultScanners.next();
400 assertNotNull(result);
401 assertEquals(1, result.size());
402 }
403 numScanNext += NUM_SCAN_NEXT;
404 metricsHelper.assertCounter("ScanNext_num_ops", numScanNext, serverSource);
405 for ( HRegionInfo i:t.getRegionLocations().keySet()) {
406 MetricsRegionAggregateSource agg = rs.getRegion(i.getRegionName())
407 .getMetrics()
408 .getSource()
409 .getAggregateSource();
410 String prefix = "namespace_"+NamespaceDescriptor.DEFAULT_NAMESPACE_NAME_STR+
411 "_table_"+tableNameString +
412 "_region_" + i.getEncodedName()+
413 "_metric";
414 metricsHelper.assertCounter(prefix + "_scanNextNumOps", NUM_SCAN_NEXT, agg);
415 }
416
417 HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
418 admin.disableTable(tableName);
419 admin.deleteTable(tableName);
420 }
421
422 @Test
423 public void testScanNextForSmallScan() throws IOException {
424 String tableNameString = "testScanNextSmall";
425 TableName tableName = TableName.valueOf(tableNameString);
426 byte[] cf = Bytes.toBytes("d");
427 byte[] qualifier = Bytes.toBytes("qual");
428 byte[] val = Bytes.toBytes("One");
429
430 TEST_UTIL.createTable(tableName, cf);
431 HTable t = new HTable(conf, tableName);
432 t.setAutoFlush(false, true);
433 for (int insertCount =0; insertCount < 100; insertCount++) {
434 Put p = new Put(Bytes.toBytes("" + insertCount + "row"));
435 p.add(cf, qualifier, val);
436 t.put(p);
437 }
438 t.flushCommits();
439
440 Scan s = new Scan();
441 s.setSmall(true);
442 s.setCaching(1);
443 ResultScanner resultScanners = t.getScanner(s);
444
445 long numScanNext = metricsHelper.getCounter("ScanNext_num_ops", serverSource);
446 for (int nextCount = 0; nextCount < NUM_SCAN_NEXT; nextCount++) {
447 Result result = resultScanners.next();
448 assertNotNull(result);
449 assertEquals(1, result.size());
450 }
451 numScanNext += NUM_SCAN_NEXT;
452 metricsHelper.assertCounter("ScanNext_num_ops", numScanNext, serverSource);
453 for ( HRegionInfo i:t.getRegionLocations().keySet()) {
454 MetricsRegionAggregateSource agg = rs.getRegion(i.getRegionName())
455 .getMetrics()
456 .getSource()
457 .getAggregateSource();
458 String prefix = "namespace_"+NamespaceDescriptor.DEFAULT_NAMESPACE_NAME_STR+
459 "_table_"+tableNameString +
460 "_region_" + i.getEncodedName()+
461 "_metric";
462 metricsHelper.assertCounter(prefix + "_scanNextNumOps", NUM_SCAN_NEXT, agg);
463 }
464
465 HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
466 admin.disableTable(tableName);
467 admin.deleteTable(tableName);
468 }
469
470 @Test
471 public void testRangeCountMetrics() throws Exception {
472 String tableNameString = "testRangeCountMetrics";
473 final long[] timeranges =
474 { 1, 3, 10, 30, 100, 300, 1000, 3000, 10000, 30000, 60000, 120000, 300000, 600000 };
475 final String timeRangeType = "TimeRangeCount";
476 final String timeRangeMetricName = "Mutate";
477 boolean timeRangeCountUpdated = false;
478
479 byte[] tName = Bytes.toBytes(tableNameString);
480 byte[] cfName = Bytes.toBytes("d");
481 byte[] row = Bytes.toBytes("rk");
482 byte[] qualifier = Bytes.toBytes("qual");
483 byte[] initValue = Bytes.toBytes("Value");
484
485 TEST_UTIL.createTable(tName, cfName);
486
487 new HTable(conf, tName).close();
488
489
490 HTable table = new HTable(conf, tName);
491 Put p = new Put(row);
492 p.add(cfName, qualifier, initValue);
493 table.put(p);
494
495
496 for (int i = 0; i < 10; i++) {
497 table.put(p);
498 }
499
500 Get g = new Get(row);
501 for (int i = 0; i < 10; i++) {
502 table.get(g);
503 }
504
505 metricsRegionServer.getRegionServerWrapper().forceRecompute();
506
507
508 long prior = 0;
509
510 String dynamicMetricName;
511 for (int i = 0; i < timeranges.length; i++) {
512 dynamicMetricName =
513 timeRangeMetricName + "_" + timeRangeType + "_" + prior + "-" + timeranges[i];
514 if (metricsHelper.checkCounterExists(dynamicMetricName, serverSource)) {
515 long count = metricsHelper.getCounter(dynamicMetricName, serverSource);
516 if (count > 0) {
517 timeRangeCountUpdated = true;
518 break;
519 }
520 }
521 prior = timeranges[i];
522 }
523 dynamicMetricName =
524 timeRangeMetricName + "_" + timeRangeType + "_" + timeranges[timeranges.length - 1] + "-inf";
525 if (metricsHelper.checkCounterExists(dynamicMetricName, serverSource)) {
526 long count = metricsHelper.getCounter(dynamicMetricName, serverSource);
527 if (count > 0) {
528 timeRangeCountUpdated = true;
529 }
530 }
531 assertEquals(true, timeRangeCountUpdated);
532
533 table.close();
534 }
535
536 @Test
537 public void testAverageRegionSize() throws Exception {
538 TableName tableName = TableName.valueOf("testAverageRegionSize");
539 byte[] cf = Bytes.toBytes("d");
540 byte[] row = Bytes.toBytes("rk");
541 byte[] qualifier = Bytes.toBytes("qual");
542 byte[] val = Bytes.toBytes("Value");
543
544
545 HTable t = TEST_UTIL.createTable(tableName, cf);
546 Put p = new Put(row);
547 p.add(cf, qualifier, val);
548 t.put(p);
549 TEST_UTIL.getHBaseAdmin().flush(tableName.getName());
550
551 metricsRegionServer.getRegionServerWrapper().forceRecompute();
552 assertTrue(metricsHelper.getGaugeDouble("averageRegionSize", serverSource) > 0.0);
553
554 t.close();
555 }
556 }