View Javadoc

1   /**
2    * Copyright The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one or more
5    * contributor license agreements. See the NOTICE file distributed with this
6    * work for additional information regarding copyright ownership. The ASF
7    * licenses this file to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   *
11   * http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16   * License for the specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.hadoop.hbase.io.hfile;
20  
21  import java.util.Iterator;
22  
23  import org.apache.hadoop.hbase.classification.InterfaceAudience;
24  import org.apache.hadoop.hbase.io.HeapSize;
25  import org.apache.hadoop.hbase.io.hfile.BlockType.BlockCategory;
26  import org.apache.hadoop.hbase.io.hfile.bucket.BucketCache;
27  
28  
29  /**
30   * CombinedBlockCache is an abstraction layer that combines
31   * {@link LruBlockCache} and {@link BucketCache}. The smaller lruCache is used
32   * to cache bloom blocks and index blocks.  The larger l2Cache is used to
33   * cache data blocks. {@link #getBlock(BlockCacheKey, boolean, boolean, boolean)} reads
34   * first from the smaller lruCache before looking for the block in the l2Cache.  Blocks evicted
35   * from lruCache are put into the bucket cache. 
36   * Metrics are the combined size and hits and misses of both caches.
37   * 
38   */
39  @InterfaceAudience.Private
40  public class CombinedBlockCache implements ResizableBlockCache, HeapSize {
41    protected final LruBlockCache lruCache;
42    protected final BlockCache l2Cache;
43    protected final CombinedCacheStats combinedCacheStats;
44  
45    public CombinedBlockCache(LruBlockCache lruCache, BlockCache l2Cache) {
46      this.lruCache = lruCache;
47      this.l2Cache = l2Cache;
48      this.combinedCacheStats = new CombinedCacheStats(lruCache.getStats(),
49          l2Cache.getStats());
50    }
51  
52    @Override
53    public long heapSize() {
54      long l2size = 0;
55      if (l2Cache instanceof HeapSize) {
56        l2size = ((HeapSize) l2Cache).heapSize();
57      }
58      return lruCache.heapSize() + l2size;
59    }
60  
61    @Override
62    public void cacheBlock(BlockCacheKey cacheKey, Cacheable buf, boolean inMemory,
63        final boolean cacheDataInL1) {
64      boolean metaBlock = buf.getBlockType().getCategory() != BlockCategory.DATA;
65      if (metaBlock || cacheDataInL1) {
66        lruCache.cacheBlock(cacheKey, buf, inMemory, cacheDataInL1);
67      } else {
68        l2Cache.cacheBlock(cacheKey, buf, inMemory, false);
69      }
70    }
71  
72    @Override
73    public void cacheBlock(BlockCacheKey cacheKey, Cacheable buf) {
74      cacheBlock(cacheKey, buf, false, false);
75    }
76  
77    @Override
78    public Cacheable getBlock(BlockCacheKey cacheKey, boolean caching,
79        boolean repeat, boolean updateCacheMetrics) {
80      // TODO: is there a hole here, or just awkwardness since in the lruCache getBlock
81      // we end up calling l2Cache.getBlock.
82      return lruCache.containsBlock(cacheKey)?
83          lruCache.getBlock(cacheKey, caching, repeat, updateCacheMetrics):
84          l2Cache.getBlock(cacheKey, caching, repeat, updateCacheMetrics);
85    }
86  
87    @Override
88    public boolean evictBlock(BlockCacheKey cacheKey) {
89      return lruCache.evictBlock(cacheKey) || l2Cache.evictBlock(cacheKey);
90    }
91  
92    @Override
93    public int evictBlocksByHfileName(String hfileName) {
94      return lruCache.evictBlocksByHfileName(hfileName)
95          + l2Cache.evictBlocksByHfileName(hfileName);
96    }
97  
98    @Override
99    public CacheStats getStats() {
100     return this.combinedCacheStats;
101   }
102 
103   @Override
104   public void shutdown() {
105     lruCache.shutdown();
106     l2Cache.shutdown();
107   }
108 
109   @Override
110   public long size() {
111     return lruCache.size() + l2Cache.size();
112   }
113 
114   @Override
115   public long getMaxSize() {
116     return lruCache.getMaxSize() + l2Cache.getMaxSize();
117   }
118 
119   @Override
120   public long getFreeSize() {
121     return lruCache.getFreeSize() + l2Cache.getFreeSize();
122   }
123 
124   @Override
125   public long getCurrentSize() {
126     return lruCache.getCurrentSize() + l2Cache.getCurrentSize();
127   }
128 
129   @Override
130   public long getCurrentDataSize() {
131     return lruCache.getCurrentDataSize() + l2Cache.getCurrentDataSize();
132   }
133 
134   @Override
135   public long getBlockCount() {
136     return lruCache.getBlockCount() + l2Cache.getBlockCount();
137   }
138 
139   @Override
140   public long getDataBlockCount() {
141     return lruCache.getDataBlockCount() + l2Cache.getDataBlockCount();
142   }
143 
144   public static class CombinedCacheStats extends CacheStats {
145     private final CacheStats lruCacheStats;
146     private final CacheStats bucketCacheStats;
147 
148     CombinedCacheStats(CacheStats lbcStats, CacheStats fcStats) {
149       super("CombinedBlockCache");
150       this.lruCacheStats = lbcStats;
151       this.bucketCacheStats = fcStats;
152     }
153 
154     @Override
155     public long getDataMissCount() {
156       return lruCacheStats.getDataMissCount() + bucketCacheStats.getDataMissCount();
157     }
158 
159     @Override
160     public long getLeafIndexMissCount() {
161       return lruCacheStats.getLeafIndexMissCount() + bucketCacheStats.getLeafIndexMissCount();
162     }
163 
164     @Override
165     public long getBloomChunkMissCount() {
166       return lruCacheStats.getBloomChunkMissCount() + bucketCacheStats.getBloomChunkMissCount();
167     }
168 
169     @Override
170     public long getMetaMissCount() {
171       return lruCacheStats.getMetaMissCount() + bucketCacheStats.getMetaMissCount();
172     }
173 
174     @Override
175     public long getRootIndexMissCount() {
176       return lruCacheStats.getRootIndexMissCount() + bucketCacheStats.getRootIndexMissCount();
177     }
178 
179     @Override
180     public long getIntermediateIndexMissCount() {
181       return lruCacheStats.getIntermediateIndexMissCount() +
182           bucketCacheStats.getIntermediateIndexMissCount();
183     }
184 
185     @Override
186     public long getFileInfoMissCount() {
187       return lruCacheStats.getFileInfoMissCount() + bucketCacheStats.getFileInfoMissCount();
188     }
189 
190     @Override
191     public long getGeneralBloomMetaMissCount() {
192       return lruCacheStats.getGeneralBloomMetaMissCount() +
193           bucketCacheStats.getGeneralBloomMetaMissCount();
194     }
195 
196     @Override
197     public long getDeleteFamilyBloomMissCount() {
198       return lruCacheStats.getDeleteFamilyBloomMissCount() +
199           bucketCacheStats.getDeleteFamilyBloomMissCount();
200     }
201 
202     @Override
203     public long getTrailerMissCount() {
204       return lruCacheStats.getTrailerMissCount() + bucketCacheStats.getTrailerMissCount();
205     }
206 
207     @Override
208     public long getDataHitCount() {
209       return lruCacheStats.getDataHitCount() + bucketCacheStats.getDataHitCount();
210     }
211 
212     @Override
213     public long getLeafIndexHitCount() {
214       return lruCacheStats.getLeafIndexHitCount() + bucketCacheStats.getLeafIndexHitCount();
215     }
216 
217     @Override
218     public long getBloomChunkHitCount() {
219       return lruCacheStats.getBloomChunkHitCount() + bucketCacheStats.getBloomChunkHitCount();
220     }
221 
222     @Override
223     public long getMetaHitCount() {
224       return lruCacheStats.getMetaHitCount() + bucketCacheStats.getMetaHitCount();
225     }
226 
227     @Override
228     public long getRootIndexHitCount() {
229       return lruCacheStats.getRootIndexHitCount() + bucketCacheStats.getRootIndexHitCount();
230     }
231 
232     @Override
233     public long getIntermediateIndexHitCount() {
234       return lruCacheStats.getIntermediateIndexHitCount() +
235           bucketCacheStats.getIntermediateIndexHitCount();
236     }
237 
238     @Override
239     public long getFileInfoHitCount() {
240       return lruCacheStats.getFileInfoHitCount() + bucketCacheStats.getFileInfoHitCount();
241     }
242 
243     @Override
244     public long getGeneralBloomMetaHitCount() {
245       return lruCacheStats.getGeneralBloomMetaHitCount() +
246           bucketCacheStats.getGeneralBloomMetaHitCount();
247     }
248 
249     @Override
250     public long getDeleteFamilyBloomHitCount() {
251       return lruCacheStats.getDeleteFamilyBloomHitCount() +
252           bucketCacheStats.getDeleteFamilyBloomHitCount();
253     }
254 
255     @Override
256     public long getTrailerHitCount() {
257       return lruCacheStats.getTrailerHitCount() + bucketCacheStats.getTrailerHitCount();
258     }
259 
260     @Override
261     public long getRequestCount() {
262       return lruCacheStats.getRequestCount()
263           + bucketCacheStats.getRequestCount();
264     }
265 
266     @Override
267     public long getRequestCachingCount() {
268       return lruCacheStats.getRequestCachingCount()
269           + bucketCacheStats.getRequestCachingCount();
270     }
271 
272     @Override
273     public long getMissCount() {
274       return lruCacheStats.getMissCount() + bucketCacheStats.getMissCount();
275     }
276 
277     @Override
278     public long getPrimaryMissCount() {
279       return lruCacheStats.getPrimaryMissCount() + bucketCacheStats.getPrimaryMissCount();
280     }
281 
282     @Override
283     public long getMissCachingCount() {
284       return lruCacheStats.getMissCachingCount()
285           + bucketCacheStats.getMissCachingCount();
286     }
287 
288     @Override
289     public long getHitCount() {
290       return lruCacheStats.getHitCount() + bucketCacheStats.getHitCount();
291     }
292 
293     @Override
294     public long getPrimaryHitCount() {
295       return lruCacheStats.getPrimaryHitCount() + bucketCacheStats.getPrimaryHitCount();
296     }
297     @Override
298     public long getHitCachingCount() {
299       return lruCacheStats.getHitCachingCount()
300           + bucketCacheStats.getHitCachingCount();
301     }
302 
303     @Override
304     public long getEvictionCount() {
305       return lruCacheStats.getEvictionCount()
306           + bucketCacheStats.getEvictionCount();
307     }
308 
309     @Override
310     public long getEvictedCount() {
311       return lruCacheStats.getEvictedCount()
312           + bucketCacheStats.getEvictedCount();
313     }
314 
315     @Override
316     public long getPrimaryEvictedCount() {
317       return lruCacheStats.getPrimaryEvictedCount()
318           + bucketCacheStats.getPrimaryEvictedCount();
319     }
320 
321     @Override
322     public void rollMetricsPeriod() {
323       lruCacheStats.rollMetricsPeriod();
324       bucketCacheStats.rollMetricsPeriod();
325     }
326     
327     @Override
328     public long getFailedInserts() {
329       return lruCacheStats.getFailedInserts() + bucketCacheStats.getFailedInserts();
330     }
331 
332     @Override
333     public long getSumHitCountsPastNPeriods() {
334       return lruCacheStats.getSumHitCountsPastNPeriods()
335           + bucketCacheStats.getSumHitCountsPastNPeriods();
336     }
337     
338     @Override
339     public long getSumRequestCountsPastNPeriods() {
340       return lruCacheStats.getSumRequestCountsPastNPeriods()
341           + bucketCacheStats.getSumRequestCountsPastNPeriods();
342     }
343     
344     @Override
345     public long getSumHitCachingCountsPastNPeriods() {
346       return lruCacheStats.getSumHitCachingCountsPastNPeriods()
347           + bucketCacheStats.getSumHitCachingCountsPastNPeriods();
348     }
349 
350     @Override
351     public long getSumRequestCachingCountsPastNPeriods() {
352       return lruCacheStats.getSumRequestCachingCountsPastNPeriods()
353           + bucketCacheStats.getSumRequestCachingCountsPastNPeriods();
354     }
355   }
356 
357   @Override
358   public Iterator<CachedBlock> iterator() {
359     return new BlockCachesIterator(getBlockCaches());
360   }
361 
362   @Override
363   public BlockCache[] getBlockCaches() {
364     return new BlockCache [] {this.lruCache, this.l2Cache};
365   }
366 
367   @Override
368   public void setMaxSize(long size) {
369     this.lruCache.setMaxSize(size);
370   }
371 }