View Javadoc

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