View Javadoc

1   /**
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  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,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  package org.apache.hadoop.hbase.io.hfile;
20  
21  import java.io.IOException;
22  import java.util.List;
23  
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  import org.apache.hadoop.classification.InterfaceAudience;
27  import org.apache.hadoop.conf.Configuration;
28  import org.apache.hadoop.hbase.io.HeapSize;
29  import org.apache.hadoop.hbase.io.hfile.slab.SlabCache;
30  import org.apache.hadoop.util.StringUtils;
31  
32  /**
33   * DoubleBlockCache is an abstraction layer that combines two caches, the
34   * smaller onHeapCache and the larger offHeapCache. CacheBlock attempts to cache
35   * the block in both caches, while readblock reads first from the faster on heap
36   * cache before looking for the block in the off heap cache. Metrics are the
37   * combined size and hits and misses of both caches.
38   *
39   **/
40  @InterfaceAudience.Private
41  public class DoubleBlockCache implements ResizableBlockCache, HeapSize {
42  
43    static final Log LOG = LogFactory.getLog(DoubleBlockCache.class.getName());
44  
45    private final LruBlockCache onHeapCache;
46    private final SlabCache offHeapCache;
47    private final CacheStats stats;
48  
49    /**
50     * Default constructor. Specify maximum size and expected average block size
51     * (approximation is fine).
52     * <p>
53     * All other factors will be calculated based on defaults specified in this
54     * class.
55     *
56     * @param onHeapSize maximum size of the onHeapCache, in bytes.
57     * @param offHeapSize maximum size of the offHeapCache, in bytes.
58     * @param onHeapBlockSize average block size of the on heap cache.
59     * @param offHeapBlockSize average block size for the off heap cache
60     * @param conf configuration file. currently used only by the off heap cache.
61     */
62    public DoubleBlockCache(long onHeapSize, long offHeapSize,
63        long onHeapBlockSize, long offHeapBlockSize, Configuration conf) {
64  
65      LOG.info("Creating on-heap cache of size "
66          + StringUtils.humanReadableInt(onHeapSize)
67          + "bytes with an average block size of "
68          + StringUtils.humanReadableInt(onHeapBlockSize) + " bytes.");
69      onHeapCache = new LruBlockCache(onHeapSize, onHeapBlockSize, conf);
70  
71      LOG.info("Creating off-heap cache of size "
72          + StringUtils.humanReadableInt(offHeapSize)
73          + "bytes with an average block size of "
74          + StringUtils.humanReadableInt(offHeapBlockSize) + " bytes.");
75      offHeapCache = new SlabCache(offHeapSize, offHeapBlockSize);
76  
77      offHeapCache.addSlabByConf(conf);
78      this.stats = new CacheStats();
79    }
80  
81    @Override
82    public void cacheBlock(BlockCacheKey cacheKey, Cacheable buf, boolean inMemory) {
83      onHeapCache.cacheBlock(cacheKey, buf, inMemory);
84      offHeapCache.cacheBlock(cacheKey, buf);
85    }
86  
87    @Override
88    public void cacheBlock(BlockCacheKey cacheKey, Cacheable buf) {
89      onHeapCache.cacheBlock(cacheKey, buf);
90      offHeapCache.cacheBlock(cacheKey, buf);
91    }
92  
93    @Override
94    public Cacheable getBlock(BlockCacheKey cacheKey, boolean caching, boolean repeat) {
95      Cacheable cachedBlock;
96  
97      if ((cachedBlock = onHeapCache.getBlock(cacheKey, caching, repeat)) != null) {
98        stats.hit(caching);
99        return cachedBlock;
100 
101     } else if ((cachedBlock = offHeapCache.getBlock(cacheKey, caching, repeat)) != null) {
102       if (caching) {
103         onHeapCache.cacheBlock(cacheKey, cachedBlock);
104       }
105       stats.hit(caching);
106       return cachedBlock;
107     }
108 
109     if (!repeat) stats.miss(caching);
110     return null;
111   }
112 
113   @Override
114   public boolean evictBlock(BlockCacheKey cacheKey) {
115     stats.evict();
116     boolean cacheA = onHeapCache.evictBlock(cacheKey);
117     boolean cacheB = offHeapCache.evictBlock(cacheKey);
118     boolean evicted = cacheA || cacheB;
119     if (evicted) {
120       stats.evicted();
121     }
122     return evicted;
123   }
124 
125   @Override
126   public CacheStats getStats() {
127     return this.stats;
128   }
129 
130   @Override
131   public void shutdown() {
132     onHeapCache.shutdown();
133     offHeapCache.shutdown();
134   }
135 
136   @Override
137   public long heapSize() {
138     return onHeapCache.heapSize() + offHeapCache.heapSize();
139   }
140 
141   public long size() {
142     return onHeapCache.size() + offHeapCache.size();
143   }
144 
145   public long getFreeSize() {
146     return onHeapCache.getFreeSize() + offHeapCache.getFreeSize();
147   }
148 
149   public long getCurrentSize() {
150     return onHeapCache.getCurrentSize() + offHeapCache.getCurrentSize();
151   }
152 
153   public long getEvictedCount() {
154     return onHeapCache.getEvictedCount() + offHeapCache.getEvictedCount();
155   }
156 
157   @Override
158   public int evictBlocksByHfileName(String hfileName) {
159     onHeapCache.evictBlocksByHfileName(hfileName);
160     offHeapCache.evictBlocksByHfileName(hfileName);
161     return 0;
162   }
163 
164   @Override
165   public List<BlockCacheColumnFamilySummary> getBlockCacheColumnFamilySummaries(
166       Configuration conf) throws IOException {
167     return onHeapCache.getBlockCacheColumnFamilySummaries(conf);
168   }
169 
170   @Override
171   public long getBlockCount() {
172     return onHeapCache.getBlockCount() + offHeapCache.getBlockCount();
173   }
174 
175   @Override
176   public void setMaxSize(long size) {
177     this.onHeapCache.setMaxSize(size);
178   }
179 }