HBASE-674 Memcache size unreliable

git-svn-id: https://svn.apache.org/repos/asf/hadoop/hbase/trunk@674108 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Jim Kellerman 2008-07-04 19:15:16 +00:00
parent d77d0432c1
commit 1f93bb5708
4 changed files with 23 additions and 34 deletions

View File

@ -167,6 +167,7 @@ Trunk (unreleased changes)
HBASE-719 Find out why users have network problems in HBase and not in Hadoop HBASE-719 Find out why users have network problems in HBase and not in Hadoop
and HConnectionManager (Jean-Daniel Cryans via Stack) and HConnectionManager (Jean-Daniel Cryans via Stack)
HBASE-703 Invalid regions listed by regionserver.jsp (Izaak Rubin via Stack) HBASE-703 Invalid regions listed by regionserver.jsp (Izaak Rubin via Stack)
HBASE-674 Memcache size unreliable
IMPROVEMENTS IMPROVEMENTS
HBASE-559 MR example job to count table rows HBASE-559 MR example job to count table rows

View File

@ -1002,6 +1002,9 @@ public class HRegion implements HConstants {
// to do this for a moment. Its quick. The subsequent sequence id that // to do this for a moment. Its quick. The subsequent sequence id that
// goes into the HLog after we've flushed all these snapshots also goes // goes into the HLog after we've flushed all these snapshots also goes
// into the info file that sits beside the flushed files. // into the info file that sits beside the flushed files.
// We also set the memcache size to zero here before we allow updates
// again so its value will represent the size of the updates received
// during the flush
long sequenceId = -1L; long sequenceId = -1L;
this.updatesLock.writeLock().lock(); this.updatesLock.writeLock().lock();
try { try {
@ -1009,6 +1012,7 @@ public class HRegion implements HConstants {
s.snapshot(); s.snapshot();
} }
sequenceId = log.startCacheFlush(); sequenceId = log.startCacheFlush();
this.memcacheSize.set(0);
} finally { } finally {
this.updatesLock.writeLock().unlock(); this.updatesLock.writeLock().unlock();
} }
@ -1017,20 +1021,13 @@ public class HRegion implements HConstants {
// restart so hlog content can be replayed and put back into the memcache. // restart so hlog content can be replayed and put back into the memcache.
// Otherwise, the snapshot content while backed up in the hlog, it will not // Otherwise, the snapshot content while backed up in the hlog, it will not
// be part of the current running servers state. // be part of the current running servers state.
long flushed = 0;
try { try {
// A. Flush memcache to all the HStores. // A. Flush memcache to all the HStores.
// Keep running vector of all store files that includes both old and the // Keep running vector of all store files that includes both old and the
// just-made new flush store file. // just-made new flush store file.
for (HStore hstore: stores.values()) { for (HStore hstore: stores.values()) {
long flushed = hstore.flushCache(sequenceId); flushed += hstore.flushCache(sequenceId);
// Subtract amount flushed.
long size = this.memcacheSize.addAndGet(-flushed);
if (size < 0) {
if (LOG.isDebugEnabled()) {
LOG.warn("Memcache size went negative " + size + "; resetting");
}
this.memcacheSize.set(0);
}
} }
} catch (Throwable t) { } catch (Throwable t) {
// An exception here means that the snapshot was not persisted. // An exception here means that the snapshot was not persisted.
@ -1068,7 +1065,7 @@ public class HRegion implements HConstants {
" in " + " in " +
(System.currentTimeMillis() - startTime) + "ms, sequence id=" + (System.currentTimeMillis() - startTime) + "ms, sequence id=" +
sequenceId + ", " + sequenceId + ", " +
StringUtils.humanReadableInt(this.memcacheSize.get())); StringUtils.humanReadableInt(flushed));
if (!regionInfo.isMetaRegion()) { if (!regionInfo.isMetaRegion()) {
this.historian.addRegionFlush(regionInfo, timeTaken); this.historian.addRegionFlush(regionInfo, timeTaken);
} }
@ -1538,9 +1535,8 @@ public class HRegion implements HConstants {
long size = 0; long size = 0;
for (Map.Entry<HStoreKey, byte[]> e: updatesByColumn.entrySet()) { for (Map.Entry<HStoreKey, byte[]> e: updatesByColumn.entrySet()) {
HStoreKey key = e.getKey(); HStoreKey key = e.getKey();
byte[] val = e.getValue(); size = this.memcacheSize.addAndGet(
size = this.memcacheSize.addAndGet(getEntrySize(key, val)); getStore(key.getColumn()).add(key, e.getValue()));
getStore(key.getColumn()).add(key, val);
} }
flush = this.flushListener != null && !this.flushRequested && flush = this.flushListener != null && !this.flushRequested &&
size > this.memcacheFlushSize; size > this.memcacheFlushSize;
@ -1578,19 +1574,6 @@ public class HRegion implements HConstants {
return this.stores.get(HStoreKey.getFamilyMapKey(column)); return this.stores.get(HStoreKey.getFamilyMapKey(column));
} }
/*
* Calculate size of passed key/value pair.
* Used here when we update region to figure what to add to this.memcacheSize
* Also used in Store when flushing calculating size of flush. Both need to
* use same method making size calculation.
* @param key
* @param value
* @return Size of the passed key + value
*/
static long getEntrySize(final HStoreKey key, byte [] value) {
return key.getSize() + (value == null ? 0 : value.length);
}
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// Support code // Support code
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////

View File

@ -620,11 +620,12 @@ public class HStore implements HConstants {
* *
* @param key * @param key
* @param value * @param value
* @return memcache size delta
*/ */
protected void add(HStoreKey key, byte[] value) { protected long add(HStoreKey key, byte[] value) {
lock.readLock().lock(); lock.readLock().lock();
try { try {
this.memcache.add(key, value); return this.memcache.add(key, value);
} finally { } finally {
lock.readLock().unlock(); lock.readLock().unlock();
} }
@ -726,7 +727,7 @@ public class HStore implements HConstants {
now < curkey.getTimestamp() + ttl) { now < curkey.getTimestamp() + ttl) {
entries++; entries++;
out.append(curkey, new ImmutableBytesWritable(bytes)); out.append(curkey, new ImmutableBytesWritable(bytes));
flushed += HRegion.getEntrySize(curkey, bytes); flushed += curkey.getSize() + (bytes == null ? 0 : bytes.length);
} else { } else {
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("internalFlushCache: " + curkey + LOG.debug("internalFlushCache: " + curkey +

View File

@ -158,11 +158,15 @@ class Memcache {
* Write an update * Write an update
* @param key * @param key
* @param value * @param value
* @return memcache size delta
*/ */
void add(final HStoreKey key, final byte[] value) { long add(final HStoreKey key, final byte[] value) {
this.lock.readLock().lock(); this.lock.readLock().lock();
try { try {
byte[] oldValue = this.memcache.remove(key);
this.memcache.put(key, value); this.memcache.put(key, value);
return key.getSize() + (value == null ? 0 : value.length) -
(oldValue == null ? 0 : oldValue.length);
} finally { } finally {
this.lock.readLock().unlock(); this.lock.readLock().unlock();
} }