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      boolean existInL1 = lruCache.containsBlock(cacheKey);
81      if (!existInL1 && updateCacheMetrics && !repeat) {
82        // If the block does not exist in L1, this check should be counted as a miss.
83        combinedCacheStats.lruCacheStats
84          .miss(caching, cacheKey.isPrimary(), cacheKey.getBlockType());
85      }
86      return existInL1 ?
87          lruCache.getBlock(cacheKey, caching, repeat, updateCacheMetrics):
88          l2Cache.getBlock(cacheKey, caching, repeat, updateCacheMetrics);
89    }
90  
91    @Override
92    public boolean evictBlock(BlockCacheKey cacheKey) {
93      return lruCache.evictBlock(cacheKey) || l2Cache.evictBlock(cacheKey);
94    }
95  
96    @Override
97    public int evictBlocksByHfileName(String hfileName) {
98      return lruCache.evictBlocksByHfileName(hfileName)
99          + l2Cache.evictBlocksByHfileName(hfileName);
100   }
101 
102   @Override
103   public CacheStats getStats() {
104     return this.combinedCacheStats;
105   }
106 
107   @Override
108   public void shutdown() {
109     lruCache.shutdown();
110     l2Cache.shutdown();
111   }
112 
113   @Override
114   public long size() {
115     return lruCache.size() + l2Cache.size();
116   }
117 
118   @Override
119   public long getMaxSize() {
120     return lruCache.getMaxSize() + l2Cache.getMaxSize();
121   }
122 
123   @Override
124   public long getFreeSize() {
125     return lruCache.getFreeSize() + l2Cache.getFreeSize();
126   }
127 
128   @Override
129   public long getCurrentSize() {
130     return lruCache.getCurrentSize() + l2Cache.getCurrentSize();
131   }
132 
133   @Override
134   public long getCurrentDataSize() {
135     return lruCache.getCurrentDataSize() + l2Cache.getCurrentDataSize();
136   }
137 
138   @Override
139   public long getBlockCount() {
140     return lruCache.getBlockCount() + l2Cache.getBlockCount();
141   }
142 
143   @Override
144   public long getDataBlockCount() {
145     return lruCache.getDataBlockCount() + l2Cache.getDataBlockCount();
146   }
147 
148   public static class CombinedCacheStats extends CacheStats {
149     private final CacheStats lruCacheStats;
150     private final CacheStats bucketCacheStats;
151 
152     CombinedCacheStats(CacheStats lbcStats, CacheStats fcStats) {
153       super("CombinedBlockCache");
154       this.lruCacheStats = lbcStats;
155       this.bucketCacheStats = fcStats;
156     }
157 
158     @Override
159     public long getDataMissCount() {
160       return lruCacheStats.getDataMissCount() + bucketCacheStats.getDataMissCount();
161     }
162 
163     @Override
164     public long getLeafIndexMissCount() {
165       return lruCacheStats.getLeafIndexMissCount() + bucketCacheStats.getLeafIndexMissCount();
166     }
167 
168     @Override
169     public long getBloomChunkMissCount() {
170       return lruCacheStats.getBloomChunkMissCount() + bucketCacheStats.getBloomChunkMissCount();
171     }
172 
173     @Override
174     public long getMetaMissCount() {
175       return lruCacheStats.getMetaMissCount() + bucketCacheStats.getMetaMissCount();
176     }
177 
178     @Override
179     public long getRootIndexMissCount() {
180       return lruCacheStats.getRootIndexMissCount() + bucketCacheStats.getRootIndexMissCount();
181     }
182 
183     @Override
184     public long getIntermediateIndexMissCount() {
185       return lruCacheStats.getIntermediateIndexMissCount() +
186           bucketCacheStats.getIntermediateIndexMissCount();
187     }
188 
189     @Override
190     public long getFileInfoMissCount() {
191       return lruCacheStats.getFileInfoMissCount() + bucketCacheStats.getFileInfoMissCount();
192     }
193 
194     @Override
195     public long getGeneralBloomMetaMissCount() {
196       return lruCacheStats.getGeneralBloomMetaMissCount() +
197           bucketCacheStats.getGeneralBloomMetaMissCount();
198     }
199 
200     @Override
201     public long getDeleteFamilyBloomMissCount() {
202       return lruCacheStats.getDeleteFamilyBloomMissCount() +
203           bucketCacheStats.getDeleteFamilyBloomMissCount();
204     }
205 
206     @Override
207     public long getTrailerMissCount() {
208       return lruCacheStats.getTrailerMissCount() + bucketCacheStats.getTrailerMissCount();
209     }
210 
211     @Override
212     public long getDataHitCount() {
213       return lruCacheStats.getDataHitCount() + bucketCacheStats.getDataHitCount();
214     }
215 
216     @Override
217     public long getLeafIndexHitCount() {
218       return lruCacheStats.getLeafIndexHitCount() + bucketCacheStats.getLeafIndexHitCount();
219     }
220 
221     @Override
222     public long getBloomChunkHitCount() {
223       return lruCacheStats.getBloomChunkHitCount() + bucketCacheStats.getBloomChunkHitCount();
224     }
225 
226     @Override
227     public long getMetaHitCount() {
228       return lruCacheStats.getMetaHitCount() + bucketCacheStats.getMetaHitCount();
229     }
230 
231     @Override
232     public long getRootIndexHitCount() {
233       return lruCacheStats.getRootIndexHitCount() + bucketCacheStats.getRootIndexHitCount();
234     }
235 
236     @Override
237     public long getIntermediateIndexHitCount() {
238       return lruCacheStats.getIntermediateIndexHitCount() +
239           bucketCacheStats.getIntermediateIndexHitCount();
240     }
241 
242     @Override
243     public long getFileInfoHitCount() {
244       return lruCacheStats.getFileInfoHitCount() + bucketCacheStats.getFileInfoHitCount();
245     }
246 
247     @Override
248     public long getGeneralBloomMetaHitCount() {
249       return lruCacheStats.getGeneralBloomMetaHitCount() +
250           bucketCacheStats.getGeneralBloomMetaHitCount();
251     }
252 
253     @Override
254     public long getDeleteFamilyBloomHitCount() {
255       return lruCacheStats.getDeleteFamilyBloomHitCount() +
256           bucketCacheStats.getDeleteFamilyBloomHitCount();
257     }
258 
259     @Override
260     public long getTrailerHitCount() {
261       return lruCacheStats.getTrailerHitCount() + bucketCacheStats.getTrailerHitCount();
262     }
263 
264     @Override
265     public long getRequestCount() {
266       return lruCacheStats.getRequestCount()
267           + bucketCacheStats.getRequestCount();
268     }
269 
270     @Override
271     public long getRequestCachingCount() {
272       return lruCacheStats.getRequestCachingCount()
273           + bucketCacheStats.getRequestCachingCount();
274     }
275 
276     @Override
277     public long getMissCount() {
278       return lruCacheStats.getMissCount() + bucketCacheStats.getMissCount();
279     }
280 
281     @Override
282     public long getPrimaryMissCount() {
283       return lruCacheStats.getPrimaryMissCount() + bucketCacheStats.getPrimaryMissCount();
284     }
285 
286     @Override
287     public long getMissCachingCount() {
288       return lruCacheStats.getMissCachingCount()
289           + bucketCacheStats.getMissCachingCount();
290     }
291 
292     @Override
293     public long getHitCount() {
294       return lruCacheStats.getHitCount() + bucketCacheStats.getHitCount();
295     }
296 
297     @Override
298     public long getPrimaryHitCount() {
299       return lruCacheStats.getPrimaryHitCount() + bucketCacheStats.getPrimaryHitCount();
300     }
301     @Override
302     public long getHitCachingCount() {
303       return lruCacheStats.getHitCachingCount()
304           + bucketCacheStats.getHitCachingCount();
305     }
306 
307     @Override
308     public long getEvictionCount() {
309       return lruCacheStats.getEvictionCount()
310           + bucketCacheStats.getEvictionCount();
311     }
312 
313     @Override
314     public long getEvictedCount() {
315       return lruCacheStats.getEvictedCount()
316           + bucketCacheStats.getEvictedCount();
317     }
318 
319     @Override
320     public long getPrimaryEvictedCount() {
321       return lruCacheStats.getPrimaryEvictedCount()
322           + bucketCacheStats.getPrimaryEvictedCount();
323     }
324 
325     @Override
326     public void rollMetricsPeriod() {
327       lruCacheStats.rollMetricsPeriod();
328       bucketCacheStats.rollMetricsPeriod();
329     }
330     
331     @Override
332     public long getFailedInserts() {
333       return lruCacheStats.getFailedInserts() + bucketCacheStats.getFailedInserts();
334     }
335 
336     @Override
337     public long getSumHitCountsPastNPeriods() {
338       return lruCacheStats.getSumHitCountsPastNPeriods()
339           + bucketCacheStats.getSumHitCountsPastNPeriods();
340     }
341     
342     @Override
343     public long getSumRequestCountsPastNPeriods() {
344       return lruCacheStats.getSumRequestCountsPastNPeriods()
345           + bucketCacheStats.getSumRequestCountsPastNPeriods();
346     }
347     
348     @Override
349     public long getSumHitCachingCountsPastNPeriods() {
350       return lruCacheStats.getSumHitCachingCountsPastNPeriods()
351           + bucketCacheStats.getSumHitCachingCountsPastNPeriods();
352     }
353 
354     @Override
355     public long getSumRequestCachingCountsPastNPeriods() {
356       return lruCacheStats.getSumRequestCachingCountsPastNPeriods()
357           + bucketCacheStats.getSumRequestCachingCountsPastNPeriods();
358     }
359   }
360 
361   @Override
362   public Iterator<CachedBlock> iterator() {
363     return new BlockCachesIterator(getBlockCaches());
364   }
365 
366   @Override
367   public BlockCache[] getBlockCaches() {
368     return new BlockCache [] {this.lruCache, this.l2Cache};
369   }
370 
371   @Override
372   public void setMaxSize(long size) {
373     this.lruCache.setMaxSize(size);
374   }
375 }