1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.io.hfile;
20
21 import java.util.concurrent.atomic.AtomicLong;
22
23 import org.apache.hadoop.hbase.classification.InterfaceAudience;
24 import org.apache.hadoop.hbase.metrics.impl.FastLongHistogram;
25
26 import org.apache.hadoop.hbase.util.Counter;
27
28
29
30
31 @InterfaceAudience.Private
32 public class CacheStats {
33
34
35
36
37 static final int DEFAULT_WINDOW_PERIODS = 5;
38
39
40 private final Counter hitCount = new Counter();
41
42
43 private final Counter primaryHitCount = new Counter();
44
45
46
47
48
49
50
51 private final Counter hitCachingCount = new Counter();
52
53
54 private final Counter missCount = new Counter();
55
56
57 private final Counter primaryMissCount = new Counter();
58
59
60
61
62 private final Counter missCachingCount = new Counter();
63
64
65 private final Counter evictionCount = new Counter();
66
67
68 private final Counter evictedBlockCount = new Counter();
69
70
71 private final Counter primaryEvictedBlockCount = new Counter();
72
73
74 private final AtomicLong failedInserts = new AtomicLong(0);
75
76
77 private final Counter dataMissCount = new Counter(0);
78 private final Counter leafIndexMissCount = new Counter(0);
79 private final Counter bloomChunkMissCount = new Counter(0);
80 private final Counter metaMissCount = new Counter(0);
81 private final Counter rootIndexMissCount = new Counter(0);
82 private final Counter intermediateIndexMissCount = new Counter(0);
83 private final Counter fileInfoMissCount = new Counter(0);
84 private final Counter generalBloomMetaMissCount = new Counter(0);
85 private final Counter deleteFamilyBloomMissCount = new Counter(0);
86 private final Counter trailerMissCount = new Counter(0);
87
88 private final Counter dataHitCount = new Counter(0);
89 private final Counter leafIndexHitCount = new Counter(0);
90 private final Counter bloomChunkHitCount = new Counter(0);
91 private final Counter metaHitCount = new Counter(0);
92 private final Counter rootIndexHitCount = new Counter(0);
93 private final Counter intermediateIndexHitCount = new Counter(0);
94 private final Counter fileInfoHitCount = new Counter(0);
95 private final Counter generalBloomMetaHitCount = new Counter(0);
96 private final Counter deleteFamilyBloomHitCount = new Counter(0);
97 private final Counter trailerHitCount = new Counter(0);
98
99
100 private final int numPeriodsInWindow;
101
102 private final long [] hitCounts;
103
104 private final long [] hitCachingCounts;
105
106 private final long [] requestCounts;
107
108 private final long [] requestCachingCounts;
109
110 private long lastHitCount = 0;
111
112 private long lastHitCachingCount = 0;
113
114 private long lastRequestCount = 0;
115
116 private long lastRequestCachingCount = 0;
117
118 private int windowIndex = 0;
119
120
121
122 private FastLongHistogram ageAtEviction;
123 private long startTime = System.nanoTime();
124
125 public CacheStats(final String name) {
126 this(name, DEFAULT_WINDOW_PERIODS);
127 }
128
129 public CacheStats(final String name, int numPeriodsInWindow) {
130 this.numPeriodsInWindow = numPeriodsInWindow;
131 this.hitCounts = initializeZeros(numPeriodsInWindow);
132 this.hitCachingCounts = initializeZeros(numPeriodsInWindow);
133 this.requestCounts = initializeZeros(numPeriodsInWindow);
134 this.requestCachingCounts = initializeZeros(numPeriodsInWindow);
135 this.ageAtEviction = new FastLongHistogram();
136 }
137
138 @Override
139 public String toString() {
140 AgeSnapshot snapshot = getAgeAtEvictionSnapshot();
141 return "hitCount=" + getHitCount() + ", hitCachingCount=" + getHitCachingCount() +
142 ", missCount=" + getMissCount() + ", missCachingCount=" + getMissCachingCount() +
143 ", evictionCount=" + getEvictionCount() +
144 ", evictedBlockCount=" + getEvictedCount() +
145 ", primaryMissCount=" + getPrimaryMissCount() +
146 ", primaryHitCount=" + getPrimaryHitCount() +
147 ", evictedAgeMean=" + snapshot.getMean();
148 }
149
150
151 public void miss(boolean caching, boolean primary, BlockType type) {
152 missCount.increment();
153 if (primary) primaryMissCount.increment();
154 if (caching) missCachingCount.increment();
155 if (type == null) {
156 return;
157 }
158 switch (type) {
159 case DATA:
160 case ENCODED_DATA:
161 dataMissCount.increment();
162 break;
163 case LEAF_INDEX:
164 leafIndexMissCount.increment();
165 break;
166 case BLOOM_CHUNK:
167 bloomChunkMissCount.increment();
168 break;
169 case META:
170 metaMissCount.increment();
171 break;
172 case INTERMEDIATE_INDEX:
173 intermediateIndexMissCount.increment();
174 break;
175 case ROOT_INDEX:
176 rootIndexMissCount.increment();
177 break;
178 case FILE_INFO:
179 fileInfoMissCount.increment();
180 break;
181 case GENERAL_BLOOM_META:
182 generalBloomMetaMissCount.increment();
183 break;
184 case DELETE_FAMILY_BLOOM_META:
185 deleteFamilyBloomMissCount.increment();
186 break;
187 case TRAILER:
188 trailerMissCount.increment();
189 break;
190 default:
191
192
193 break;
194 }
195 }
196
197 public void hit(boolean caching, boolean primary, BlockType type) {
198 hitCount.increment();
199 if (primary) primaryHitCount.increment();
200 if (caching) hitCachingCount.increment();
201
202
203 if (type == null) {
204 return;
205 }
206 switch (type) {
207 case DATA:
208 case ENCODED_DATA:
209 dataHitCount.increment();
210 break;
211 case LEAF_INDEX:
212 leafIndexHitCount.increment();
213 break;
214 case BLOOM_CHUNK:
215 bloomChunkHitCount.increment();
216 break;
217 case META:
218 metaHitCount.increment();
219 break;
220 case INTERMEDIATE_INDEX:
221 intermediateIndexHitCount.increment();
222 break;
223 case ROOT_INDEX:
224 rootIndexHitCount.increment();
225 break;
226 case FILE_INFO:
227 fileInfoHitCount.increment();
228 break;
229 case GENERAL_BLOOM_META:
230 generalBloomMetaHitCount.increment();
231 break;
232 case DELETE_FAMILY_BLOOM_META:
233 deleteFamilyBloomHitCount.increment();
234 break;
235 case TRAILER:
236 trailerHitCount.increment();
237 break;
238 default:
239
240
241 break;
242 }
243 }
244
245 public void evict() {
246 evictionCount.increment();
247 }
248
249 public void evicted(final long t, boolean primary) {
250 if (t > this.startTime) {
251 this.ageAtEviction.add((t - this.startTime) / BlockCacheUtil.NANOS_PER_SECOND, 1);
252 }
253 this.evictedBlockCount.increment();
254 if (primary) {
255 primaryEvictedBlockCount.increment();
256 }
257 }
258
259 public long failInsert() {
260 return failedInserts.incrementAndGet();
261 }
262
263
264
265 public long getDataMissCount() {
266 return dataMissCount.get();
267 }
268
269 public long getLeafIndexMissCount() {
270 return leafIndexMissCount.get();
271 }
272
273 public long getBloomChunkMissCount() {
274 return bloomChunkMissCount.get();
275 }
276
277 public long getMetaMissCount() {
278 return metaMissCount.get();
279 }
280
281 public long getRootIndexMissCount() {
282 return rootIndexMissCount.get();
283 }
284
285 public long getIntermediateIndexMissCount() {
286 return intermediateIndexMissCount.get();
287 }
288
289 public long getFileInfoMissCount() {
290 return fileInfoMissCount.get();
291 }
292
293 public long getGeneralBloomMetaMissCount() {
294 return generalBloomMetaMissCount.get();
295 }
296
297 public long getDeleteFamilyBloomMissCount() {
298 return deleteFamilyBloomMissCount.get();
299 }
300
301 public long getTrailerMissCount() {
302 return trailerMissCount.get();
303 }
304
305 public long getDataHitCount() {
306 return dataHitCount.get();
307 }
308
309 public long getLeafIndexHitCount() {
310 return leafIndexHitCount.get();
311 }
312
313 public long getBloomChunkHitCount() {
314 return bloomChunkHitCount.get();
315 }
316
317 public long getMetaHitCount() {
318 return metaHitCount.get();
319 }
320
321 public long getRootIndexHitCount() {
322 return rootIndexHitCount.get();
323 }
324
325 public long getIntermediateIndexHitCount() {
326 return intermediateIndexHitCount.get();
327 }
328
329 public long getFileInfoHitCount() {
330 return fileInfoHitCount.get();
331 }
332
333 public long getGeneralBloomMetaHitCount() {
334 return generalBloomMetaHitCount.get();
335 }
336
337 public long getDeleteFamilyBloomHitCount() {
338 return deleteFamilyBloomHitCount.get();
339 }
340
341 public long getTrailerHitCount() {
342 return trailerHitCount.get();
343 }
344
345 public long getRequestCount() {
346 return getHitCount() + getMissCount();
347 }
348
349 public long getRequestCachingCount() {
350 return getHitCachingCount() + getMissCachingCount();
351 }
352
353 public long getMissCount() {
354 return missCount.get();
355 }
356
357 public long getPrimaryMissCount() {
358 return primaryMissCount.get();
359 }
360
361 public long getMissCachingCount() {
362 return missCachingCount.get();
363 }
364
365 public long getHitCount() {
366 return hitCount.get();
367 }
368
369 public long getPrimaryHitCount() {
370 return primaryHitCount.get();
371 }
372
373 public long getHitCachingCount() {
374 return hitCachingCount.get();
375 }
376
377 public long getEvictionCount() {
378 return evictionCount.get();
379 }
380
381 public long getEvictedCount() {
382 return this.evictedBlockCount.get();
383 }
384
385 public long getPrimaryEvictedCount() {
386 return primaryEvictedBlockCount.get();
387 }
388
389 public double getHitRatio() {
390 double requestCount = getRequestCount();
391
392 if (requestCount == 0) {
393 return 0;
394 }
395
396 return getHitCount() / requestCount;
397 }
398
399 public double getHitCachingRatio() {
400 double requestCachingCount = getRequestCachingCount();
401
402 if (requestCachingCount == 0) {
403 return 0;
404 }
405
406 return getHitCachingCount() / requestCachingCount;
407 }
408
409 public double getMissRatio() {
410 double requestCount = getRequestCount();
411
412 if (requestCount == 0) {
413 return 0;
414 }
415
416 return getMissCount() / requestCount;
417 }
418
419 public double getMissCachingRatio() {
420 double requestCachingCount = getRequestCachingCount();
421
422 if (requestCachingCount == 0) {
423 return 0;
424 }
425
426 return getMissCachingCount() / requestCachingCount;
427 }
428
429 public double evictedPerEviction() {
430 double evictionCount = getEvictionCount();
431
432 if (evictionCount == 0) {
433 return 0;
434 }
435
436 return getEvictedCount() / evictionCount;
437 }
438
439 public long getFailedInserts() {
440 return failedInserts.get();
441 }
442
443 public void rollMetricsPeriod() {
444 hitCounts[windowIndex] = getHitCount() - lastHitCount;
445 lastHitCount = getHitCount();
446 hitCachingCounts[windowIndex] =
447 getHitCachingCount() - lastHitCachingCount;
448 lastHitCachingCount = getHitCachingCount();
449 requestCounts[windowIndex] = getRequestCount() - lastRequestCount;
450 lastRequestCount = getRequestCount();
451 requestCachingCounts[windowIndex] =
452 getRequestCachingCount() - lastRequestCachingCount;
453 lastRequestCachingCount = getRequestCachingCount();
454 windowIndex = (windowIndex + 1) % numPeriodsInWindow;
455 }
456
457 public long getSumHitCountsPastNPeriods() {
458 return sum(hitCounts);
459 }
460
461 public long getSumRequestCountsPastNPeriods() {
462 return sum(requestCounts);
463 }
464
465 public long getSumHitCachingCountsPastNPeriods() {
466 return sum(hitCachingCounts);
467 }
468
469 public long getSumRequestCachingCountsPastNPeriods() {
470 return sum(requestCachingCounts);
471 }
472
473 public double getHitRatioPastNPeriods() {
474 double ratio = ((double)getSumHitCountsPastNPeriods() /
475 (double)getSumRequestCountsPastNPeriods());
476 return Double.isNaN(ratio) ? 0 : ratio;
477 }
478
479 public double getHitCachingRatioPastNPeriods() {
480 double ratio = ((double)getSumHitCachingCountsPastNPeriods() /
481 (double)getSumRequestCachingCountsPastNPeriods());
482 return Double.isNaN(ratio) ? 0 : ratio;
483 }
484
485 public AgeSnapshot getAgeAtEvictionSnapshot() {
486 return new AgeSnapshot(this.ageAtEviction);
487 }
488
489 private static long sum(long [] counts) {
490 long sum = 0;
491 for (long count : counts) sum += count;
492 return sum;
493 }
494
495 private static long [] initializeZeros(int n) {
496 long [] zeros = new long [n];
497 for (int i=0; i<n; i++) {
498 zeros[i] = 0L;
499 }
500 return zeros;
501 }
502 }