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
25 import org.apache.hadoop.hbase.util.Counter;
26 import org.apache.hadoop.hbase.util.FastLongHistogram;
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) this.ageAtEviction.add(t - this.startTime,1);
251 this.evictedBlockCount.increment();
252 if (primary) {
253 primaryEvictedBlockCount.increment();
254 }
255 }
256
257 public long failInsert() {
258 return failedInserts.incrementAndGet();
259 }
260
261
262
263 public long getDataMissCount() {
264 return dataMissCount.get();
265 }
266
267 public long getLeafIndexMissCount() {
268 return leafIndexMissCount.get();
269 }
270
271 public long getBloomChunkMissCount() {
272 return bloomChunkMissCount.get();
273 }
274
275 public long getMetaMissCount() {
276 return metaMissCount.get();
277 }
278
279 public long getRootIndexMissCount() {
280 return rootIndexMissCount.get();
281 }
282
283 public long getIntermediateIndexMissCount() {
284 return intermediateIndexMissCount.get();
285 }
286
287 public long getFileInfoMissCount() {
288 return fileInfoMissCount.get();
289 }
290
291 public long getGeneralBloomMetaMissCount() {
292 return generalBloomMetaMissCount.get();
293 }
294
295 public long getDeleteFamilyBloomMissCount() {
296 return deleteFamilyBloomMissCount.get();
297 }
298
299 public long getTrailerMissCount() {
300 return trailerMissCount.get();
301 }
302
303 public long getDataHitCount() {
304 return dataHitCount.get();
305 }
306
307 public long getLeafIndexHitCount() {
308 return leafIndexHitCount.get();
309 }
310
311 public long getBloomChunkHitCount() {
312 return bloomChunkHitCount.get();
313 }
314
315 public long getMetaHitCount() {
316 return metaHitCount.get();
317 }
318
319 public long getRootIndexHitCount() {
320 return rootIndexHitCount.get();
321 }
322
323 public long getIntermediateIndexHitCount() {
324 return intermediateIndexHitCount.get();
325 }
326
327 public long getFileInfoHitCount() {
328 return fileInfoHitCount.get();
329 }
330
331 public long getGeneralBloomMetaHitCount() {
332 return generalBloomMetaHitCount.get();
333 }
334
335 public long getDeleteFamilyBloomHitCount() {
336 return deleteFamilyBloomHitCount.get();
337 }
338
339 public long getTrailerHitCount() {
340 return trailerHitCount.get();
341 }
342
343 public long getRequestCount() {
344 return getHitCount() + getMissCount();
345 }
346
347 public long getRequestCachingCount() {
348 return getHitCachingCount() + getMissCachingCount();
349 }
350
351 public long getMissCount() {
352 return missCount.get();
353 }
354
355 public long getPrimaryMissCount() {
356 return primaryMissCount.get();
357 }
358
359 public long getMissCachingCount() {
360 return missCachingCount.get();
361 }
362
363 public long getHitCount() {
364 return hitCount.get();
365 }
366
367 public long getPrimaryHitCount() {
368 return primaryHitCount.get();
369 }
370
371 public long getHitCachingCount() {
372 return hitCachingCount.get();
373 }
374
375 public long getEvictionCount() {
376 return evictionCount.get();
377 }
378
379 public long getEvictedCount() {
380 return this.evictedBlockCount.get();
381 }
382
383 public long getPrimaryEvictedCount() {
384 return primaryEvictedBlockCount.get();
385 }
386
387 public double getHitRatio() {
388 double requestCount = getRequestCount();
389
390 if (requestCount == 0) {
391 return 0;
392 }
393
394 return getHitCount() / requestCount;
395 }
396
397 public double getHitCachingRatio() {
398 double requestCachingCount = getRequestCachingCount();
399
400 if (requestCachingCount == 0) {
401 return 0;
402 }
403
404 return getHitCachingCount() / requestCachingCount;
405 }
406
407 public double getMissRatio() {
408 double requestCount = getRequestCount();
409
410 if (requestCount == 0) {
411 return 0;
412 }
413
414 return getMissCount() / requestCount;
415 }
416
417 public double getMissCachingRatio() {
418 double requestCachingCount = getRequestCachingCount();
419
420 if (requestCachingCount == 0) {
421 return 0;
422 }
423
424 return getMissCachingCount() / requestCachingCount;
425 }
426
427 public double evictedPerEviction() {
428 double evictionCount = getEvictionCount();
429
430 if (evictionCount == 0) {
431 return 0;
432 }
433
434 return getEvictedCount() / evictionCount;
435 }
436
437 public long getFailedInserts() {
438 return failedInserts.get();
439 }
440
441 public void rollMetricsPeriod() {
442 hitCounts[windowIndex] = getHitCount() - lastHitCount;
443 lastHitCount = getHitCount();
444 hitCachingCounts[windowIndex] =
445 getHitCachingCount() - lastHitCachingCount;
446 lastHitCachingCount = getHitCachingCount();
447 requestCounts[windowIndex] = getRequestCount() - lastRequestCount;
448 lastRequestCount = getRequestCount();
449 requestCachingCounts[windowIndex] =
450 getRequestCachingCount() - lastRequestCachingCount;
451 lastRequestCachingCount = getRequestCachingCount();
452 windowIndex = (windowIndex + 1) % numPeriodsInWindow;
453 }
454
455 public long getSumHitCountsPastNPeriods() {
456 return sum(hitCounts);
457 }
458
459 public long getSumRequestCountsPastNPeriods() {
460 return sum(requestCounts);
461 }
462
463 public long getSumHitCachingCountsPastNPeriods() {
464 return sum(hitCachingCounts);
465 }
466
467 public long getSumRequestCachingCountsPastNPeriods() {
468 return sum(requestCachingCounts);
469 }
470
471 public double getHitRatioPastNPeriods() {
472 double ratio = ((double)getSumHitCountsPastNPeriods() /
473 (double)getSumRequestCountsPastNPeriods());
474 return Double.isNaN(ratio) ? 0 : ratio;
475 }
476
477 public double getHitCachingRatioPastNPeriods() {
478 double ratio = ((double)getSumHitCachingCountsPastNPeriods() /
479 (double)getSumRequestCachingCountsPastNPeriods());
480 return Double.isNaN(ratio) ? 0 : ratio;
481 }
482
483 public AgeSnapshot getAgeAtEvictionSnapshot() {
484 return new AgeSnapshot(this.ageAtEviction);
485 }
486
487 private static long sum(long [] counts) {
488 long sum = 0;
489 for (long count : counts) sum += count;
490 return sum;
491 }
492
493 private static long [] initializeZeros(int n) {
494 long [] zeros = new long [n];
495 for (int i=0; i<n; i++) {
496 zeros[i] = 0L;
497 }
498 return zeros;
499 }
500 }