HBASE-1460 Concurrent LRU Block Cache

git-svn-id: https://svn.apache.org/repos/asf/hadoop/hbase/trunk@788888 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael Stack 2009-06-26 22:16:40 +00:00
parent 831e975a5d
commit 9be89e60cd
9 changed files with 654 additions and 1118 deletions

View File

@ -423,6 +423,7 @@ Release 0.20.0 - Unreleased
HBASE-1412 Change values for delete column and column family in KeyValue
HBASE-1535 Add client ability to perform mutations without the WAL
(Jon Gray via Stack)
HBASE-1460 Concurrent LRU Block Cache (Jon Gray via Stack)
Release 0.19.0 - 01/21/2009
INCOMPATIBLE CHANGES

View File

@ -2,7 +2,7 @@
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!--
/**
* Copyright 2007 The Apache Software Foundation
* Copyright 2009 The Apache Software Foundation
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -342,9 +342,11 @@
</property>
<property>
<name>hfile.block.cache.size</name>
<value>50000000</value>
<value>0.2</value>
<description>
The size of the block cache used by HFile/StoreFile. Set to 0 to disable.
Percentage of maximum heap (-Xmx setting) to allocate to block cache
used by HFile/StoreFile. Default of 0.2 means allocate 20%.
Set to 0 to disable.
</description>
</property>
<property>

View File

@ -2,7 +2,7 @@
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!--
/**
* Copyright 2007 The Apache Software Foundation
* Copyright 2009 The Apache Software Foundation
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file

View File

@ -30,6 +30,14 @@ public interface BlockCache {
* Add block to cache.
* @param blockName Zero-based file block number.
* @param buf The block contents wrapped in a ByteBuffer.
* @param inMemory Whether block should be treated as in-memory
*/
public void cacheBlock(String blockName, ByteBuffer buf, boolean inMemory);
/**
* Add block to cache (defaults to not in-memory).
* @param blockName Zero-based file block number.
* @param buf The block contents wrapped in a ByteBuffer.
*/
public void cacheBlock(String blockName, ByteBuffer buf);

File diff suppressed because it is too large Load Diff

View File

@ -46,7 +46,7 @@ public class SimpleBlockCache implements BlockCache {
processQueue();
return cache.size();
}
@Override
public synchronized ByteBuffer getBlock(String blockName) {
processQueue(); // clear out some crap.
Ref ref = cache.get(blockName);
@ -55,8 +55,12 @@ public class SimpleBlockCache implements BlockCache {
return ref.get();
}
@Override
public synchronized void cacheBlock(String blockName, ByteBuffer buf) {
cache.put(blockName, new Ref(blockName, buf, q));
}
public synchronized void cacheBlock(String blockName, ByteBuffer buf,
boolean inMemory) {
cache.put(blockName, new Ref(blockName, buf, q));
}
}

View File

@ -1090,9 +1090,9 @@ public class HRegionServer implements HConstants, HRegionInterface,
LruBlockCache lruBlockCache = (LruBlockCache)StoreFile.getBlockCache(conf);
if (lruBlockCache != null) {
this.metrics.blockCacheCount.set(lruBlockCache.size());
this.metrics.blockCacheFree.set(lruBlockCache.getMemFree());
this.metrics.blockCacheSize.set(lruBlockCache.getMemUsed());
double ratio = lruBlockCache.getHitRatio();
this.metrics.blockCacheFree.set(lruBlockCache.getFreeSize());
this.metrics.blockCacheSize.set(lruBlockCache.getCurrentSize());
double ratio = lruBlockCache.getStats().getHitRatio();
int percent = (int) (ratio * 100);
this.metrics.blockCacheHitRatio.set(percent);
}
@ -2364,7 +2364,7 @@ public class HRegionServer implements HConstants, HRegionInterface,
// LocalHBaseCluster. It manages 'local' clusters.
if (LocalHBaseCluster.isLocal(conf)) {
LOG.warn("Not starting a distinct region server because " +
"hbase.master is set to 'local' mode");
HConstants.CLUSTER_DISTRIBUTED + " is false");
} else {
RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
if (runtime != null) {

View File

@ -19,6 +19,16 @@
*/
package org.apache.hadoop.hbase.regionserver;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryUsage;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.fs.FileSystem;
@ -33,14 +43,7 @@ import org.apache.hadoop.hbase.io.hfile.Compression;
import org.apache.hadoop.hbase.io.hfile.HFile;
import org.apache.hadoop.hbase.io.hfile.LruBlockCache;
import org.apache.hadoop.hbase.util.Bytes;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.hadoop.util.StringUtils;
/**
* A Store data file. Stores usually have one or more of these files. They
@ -58,7 +61,7 @@ public class StoreFile implements HConstants {
private static final String HFILE_CACHE_SIZE_KEY = "hfile.block.cache.size";
private static BlockCache hfileBlockCache = null;
// Make default block size for StoreFiles 8k while testing. TODO: FIX!
// Need to make it 8k for testing.
private static final int DEFAULT_BLOCKSIZE_SMALL = 8 * 1024;
@ -218,15 +221,22 @@ public class StoreFile implements HConstants {
* @return The block cache or <code>null</code>.
*/
public static synchronized BlockCache getBlockCache(HBaseConfiguration conf) {
if (hfileBlockCache != null)
return hfileBlockCache;
if (hfileBlockCache != null) return hfileBlockCache;
long cacheSize = conf.getLong(HFILE_CACHE_SIZE_KEY, 0L);
float cachePercentage = conf.getFloat(HFILE_CACHE_SIZE_KEY, 0.0f);
// There should be a better way to optimize this. But oh well.
if (cacheSize == 0L)
return null;
if (cachePercentage == 0L) return null;
if (cachePercentage > 1.0) {
throw new IllegalArgumentException(HFILE_CACHE_SIZE_KEY +
" must be between 0.0 and 1.0, not > 1.0");
}
hfileBlockCache = new LruBlockCache(cacheSize);
// Calculate the amount of heap to give the heap.
MemoryUsage mu = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
long cacheSize = (long)(mu.getMax() * cachePercentage);
LOG.info("Allocating LruBlockCache with maximum size " +
StringUtils.humanReadableInt(cacheSize));
hfileBlockCache = new LruBlockCache(cacheSize, DEFAULT_BLOCKSIZE_SMALL);
return hfileBlockCache;
}

View File

@ -48,7 +48,7 @@ public class TestHeapSize extends TestCase {
//LruBlockCache
cl = LruBlockCache.class;
expected = ClassSize.estimateBase(cl, false);
LruBlockCache c = new LruBlockCache(1,1,200);
LruBlockCache c = new LruBlockCache(102400,1024);
//Since minimum size for the for a LruBlockCache is 1
//we need to remove one reference from the heapsize
actual = c.heapSize();// - ClassSize.REFERENCE_SIZE;