You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by li...@apache.org on 2013/11/28 19:13:29 UTC

svn commit: r1546430 - in /hbase/branches/0.89-fb/src: main/java/org/apache/hadoop/hbase/io/hfile/ main/java/org/apache/hadoop/hbase/io/hfile/bucket/ main/java/org/apache/hadoop/hbase/regionserver/ test/java/org/apache/hadoop/hbase/io/hfile/

Author: liyin
Date: Thu Nov 28 18:13:28 2013
New Revision: 1546430

URL: http://svn.apache.org/r1546430
Log:
[master] Make L2 cache online configurable

Author: arjen

Summary: This diff allows the L2 cache to be disabled or L2 cache policies to be modified without restarting the RS. This is a preliminary diff to get some eyes on as I am not fully done testing.

Test Plan: Unit tests.

Reviewers: liyintang, gauravm

Reviewed By: liyintang

CC: hbase-eng@

Differential Revision: https://phabricator.fb.com/D1059239

Modified:
    hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/io/hfile/CacheConfig.java
    hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/io/hfile/L2BucketCache.java
    hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/io/hfile/L2Cache.java
    hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/io/hfile/bucket/BucketCache.java
    hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java
    hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/io/hfile/TestL2BucketCache.java

Modified: hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/io/hfile/CacheConfig.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/io/hfile/CacheConfig.java?rev=1546430&r1=1546429&r2=1546430&view=diff
==============================================================================
--- hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/io/hfile/CacheConfig.java (original)
+++ hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/io/hfile/CacheConfig.java Thu Nov 28 18:13:28 2013
@@ -19,6 +19,7 @@ package org.apache.hadoop.hbase.io.hfile
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.conf.ConfigurationObserver;
 import org.apache.hadoop.hbase.io.hfile.BlockType.BlockCategory;
 import org.apache.hadoop.hbase.io.hfile.bucket.IOEngine;
 import org.apache.hadoop.hbase.util.Strings;
@@ -28,7 +29,7 @@ import java.util.Arrays;
 /**
  * Stores all of the cache objects and configuration for a single HFile.
  */
-public class CacheConfig {
+public class CacheConfig implements ConfigurationObserver {
   private static final Log LOG = LogFactory.getLog(CacheConfig.class.getName());
 
   /**
@@ -221,20 +222,23 @@ public class CacheConfig {
   /** Threshold for caching hot data blocks during compaction */
   private final float cacheOnCompactionThreshold;
 
+  /** Size of the L2 cache */
+  private volatile float l2CacheSize;
+
   /** Whether to cache all blocks on write in the L2 cache */
-  private final boolean l2CacheDataOnWrite;
+  private volatile boolean l2CacheDataOnWrite;
 
   /**
    * TODO (avf): once implemented, whether to evict blocks from the L2
    *             cache once they have been cached in the L1 cache
    */
-  private final boolean l2EvictOnPromotion;
+  private volatile boolean l2EvictOnPromotion;
 
   /**
    * Whether blocks of a file should be evicted from the L2 cache when the file
    * is closed.
    */
-  private final boolean l2EvictOnClose;
+  private volatile boolean l2EvictOnClose;
 
   /**
    * Parses a comma separated list of bucket sizes and returns a list of
@@ -284,6 +288,7 @@ public class CacheConfig {
                 DEFAULT_CACHE_DATA_BLOCKS_ON_COMPACTION),
             conf.getFloat(CACHE_DATA_BLOCKS_ON_COMPACTION_THRESHOLD,
                 DEFAULT_CACHE_DATA_BLOCKS_ON_COMPACTION_THRESHOLD),
+        conf.getFloat(L2_BUCKET_CACHE_SIZE_KEY, 0F),
         conf.getBoolean(L2_CACHE_BLOCKS_ON_FLUSH_KEY,
             DEFAULT_L2_CACHE_BLOCKS_ON_FLUSH),
         conf.getBoolean(L2_EVICT_ON_PROMOTION_KEY, DEFAULT_L2_EVICT_ON_PROMOTION),
@@ -297,21 +302,26 @@ public class CacheConfig {
    * @param blockCache reference to block cache, null if completely disabled
    * @param cacheDataOnRead whether data blocks should be cached on read
    * @param inMemory whether blocks should be flagged as in-memory
-   * @param cacheDataOnWrite whether data blocks should be cached on write
+   * @param cacheDataOnFlush whether data blocks should be cached on write
    * @param cacheIndexesOnWrite whether index blocks should be cached on write
-   * @param cacheBloomsOnFlush whether blooms should be cached on write
+   * @param cacheBloomsOnWrite whether blooms should be cached on write
    * @param evictOnClose whether blocks should be evicted when HFile is closed
    * @param cacheCompressed whether to store blocks as compressed in the cache
    * @param cacheOnCompaction whether to cache blocks during compaction
    * @param cacheOnCompactionThreshold threshold used of caching of blocks during compaction
+   * @param l2CacheSize size of the L2 cache
+   * @param l2CacheDataOnWrite whether blocks should be cached on write
+   * @param l2EvictOnPromotion whether blocks should be evicted from L2 upon promotion
+   * @param l2EvictOnClose whether blocks should be evicted from L2 when HFile is closed
    */
   CacheConfig(final BlockCache blockCache, final L2Cache l2Cache,
       final boolean cacheDataOnRead, final boolean inMemory,
       final boolean cacheDataOnFlush, final boolean cacheIndexesOnWrite,
       final boolean cacheBloomsOnWrite, final boolean evictOnClose,
       final boolean cacheCompressed, final boolean cacheOnCompaction,
-      final float cacheOnCompactionThreshold, final boolean l2CacheDataOnWrite,
-      final boolean l2EvictOnPromotion, final boolean l2EvictOnClose) {
+      final float cacheOnCompactionThreshold, final float l2CacheSize,
+      final boolean l2CacheDataOnWrite, final boolean l2EvictOnPromotion,
+      final boolean l2EvictOnClose) {
     this.blockCache = blockCache;
     this.l2Cache = l2Cache;
     this.cacheDataOnRead = cacheDataOnRead;
@@ -323,6 +333,7 @@ public class CacheConfig {
     this.cacheCompressed = cacheCompressed;
     this.cacheOnCompaction = cacheOnCompaction;
     this.cacheOnCompactionThreshold = cacheOnCompactionThreshold;
+    this.l2CacheSize = l2CacheSize;
     this.l2CacheDataOnWrite = l2CacheDataOnWrite;
     this.l2EvictOnPromotion = l2EvictOnPromotion;
     this.l2EvictOnClose = l2EvictOnClose;
@@ -338,8 +349,9 @@ public class CacheConfig {
         cacheConf.cacheDataOnFlush, cacheConf.cacheIndexesOnWrite,
         cacheConf.cacheBloomsOnWrite, cacheConf.evictOnClose,
         cacheConf.cacheCompressed, cacheConf.cacheOnCompaction,
-        cacheConf.cacheOnCompactionThreshold, cacheConf.l2CacheDataOnWrite,
-        cacheConf.l2EvictOnPromotion, cacheConf.l2EvictOnClose);
+        cacheConf.cacheOnCompactionThreshold, cacheConf.l2CacheSize,
+        cacheConf.l2CacheDataOnWrite, cacheConf.l2EvictOnPromotion,
+        cacheConf.l2EvictOnClose);
   }
 
   /**
@@ -395,7 +407,7 @@ public class CacheConfig {
 
   /**
    * Only used for testing.
-   * @param cacheDataOnWrite whether data blocks should be written to the cache
+   * @param cacheDataOnFlush whether data blocks should be written to the cache
    *                         when an HFile is written
    */
   public void setCacheDataOnFlush(boolean cacheDataOnFlush) {
@@ -458,6 +470,18 @@ public class CacheConfig {
     return cacheOnCompactionThreshold;
   }
 
+  public void setL2CacheDataOnWrite(final boolean l2CacheDataOnWrite) {
+    this.l2CacheDataOnWrite = l2CacheDataOnWrite;
+  }
+
+  public void setL2EvictOnPromotion(final boolean l2EvictOnPromotion) {
+    this.l2EvictOnPromotion = l2EvictOnPromotion;
+  }
+
+  public void setL2EvictOnClose(final boolean l2EvictOnClose) {
+    this.l2EvictOnClose = l2EvictOnClose;
+  }
+
   public boolean shouldL2CacheDataOnWrite() {
     return l2CacheDataOnWrite;
   }
@@ -502,13 +526,18 @@ public class CacheConfig {
   }
 
   public boolean isL2CacheEnabled() {
-    return l2Cache != null;
+    return l2Cache != null && !l2Cache.isShutdown();
   }
 
   public L2Cache getL2Cache() {
     return l2Cache;
   }
 
+  @Override
+  public void notifyOnChange(Configuration conf) {
+    new CacheConfigBuilder(conf).update(this);
+  }
+
   /**
    * A builder for the CacheConfig class. Used to avoid having multiple
    * constructors.
@@ -529,6 +558,7 @@ public class CacheConfig {
     private boolean cacheCompressed;
     private boolean cacheOnCompaction;
     private float cacheOnCompactionThreshold;
+    private float l2CacheSize;
     private boolean l2CacheDataOnWrite;
     private boolean l2EvictOnPromotion;
     private boolean l2EvictOnClose;
@@ -579,6 +609,7 @@ public class CacheConfig {
       cacheOnCompactionThreshold = conf.getFloat(
           CACHE_DATA_BLOCKS_ON_COMPACTION_THRESHOLD,
           DEFAULT_CACHE_DATA_BLOCKS_ON_COMPACTION_THRESHOLD);
+      l2CacheSize = conf.getFloat(L2_BUCKET_CACHE_SIZE_KEY, 0F);
       l2CacheDataOnWrite = conf.getBoolean(
           L2_CACHE_BLOCKS_ON_FLUSH_KEY, DEFAULT_L2_CACHE_BLOCKS_ON_FLUSH);
       l2EvictOnPromotion = conf.getBoolean(
@@ -678,8 +709,34 @@ public class CacheConfig {
           cacheDataOnFlush, cacheIndexesOnWrite,
           cacheBloomsOnWrite, evictOnClose,
           cacheCompressed, cacheOnCompaction,
-          cacheOnCompactionThreshold, l2CacheDataOnWrite,
-          l2EvictOnPromotion, l2EvictOnClose);
+          cacheOnCompactionThreshold, l2CacheSize,
+          l2CacheDataOnWrite, l2EvictOnPromotion,
+          l2EvictOnClose);
+    }
+
+    public CacheConfig update(CacheConfig cacheConf) {
+      if (l2CacheDataOnWrite != cacheConf.shouldL2CacheDataOnWrite()) {
+        LOG.info("Updating " + CacheConfig.L2_CACHE_BLOCKS_ON_FLUSH_KEY +
+                " from " + cacheConf.shouldL2CacheDataOnWrite() + " to " +
+                l2CacheDataOnWrite);
+        cacheConf.setL2CacheDataOnWrite(l2CacheDataOnWrite);
+      }
+      if (l2EvictOnPromotion != cacheConf.shouldL2EvictOnPromotion()) {
+        LOG.info("Updating " + CacheConfig.L2_EVICT_ON_PROMOTION_KEY +
+                " from " + cacheConf.shouldL2EvictOnPromotion() + " to " +
+                l2EvictOnPromotion);
+        cacheConf.setL2EvictOnPromotion(l2EvictOnPromotion);
+      }
+      if (l2EvictOnClose != cacheConf.shouldL2EvictOnClose()) {
+        LOG.info("Updating " + CacheConfig.L2_EVICT_ON_CLOSE_KEY + " from " +
+                cacheConf.shouldL2EvictOnClose() + " to " + l2EvictOnClose);
+        cacheConf.setL2EvictOnClose(l2EvictOnClose);
+      }
+      if (l2CacheSize == 0F && cacheConf.isL2CacheEnabled()) {
+        cacheConf.getL2Cache().shutdown();
+        LOG.info("L2 cache disabled");
+      }
+      return cacheConf;
     }
   }
 }

Modified: hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/io/hfile/L2BucketCache.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/io/hfile/L2BucketCache.java?rev=1546430&r1=1546429&r2=1546430&view=diff
==============================================================================
--- hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/io/hfile/L2BucketCache.java (original)
+++ hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/io/hfile/L2BucketCache.java Thu Nov 28 18:13:28 2013
@@ -77,6 +77,11 @@ public class L2BucketCache implements L2
   }
 
   @Override
+  public boolean isShutdown() {
+    return !bucketCache.isEnabled();
+  }
+
+  @Override
   public void shutdown() {
     bucketCache.shutdown();
   }

Modified: hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/io/hfile/L2Cache.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/io/hfile/L2Cache.java?rev=1546430&r1=1546429&r2=1546430&view=diff
==============================================================================
--- hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/io/hfile/L2Cache.java (original)
+++ hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/io/hfile/L2Cache.java Thu Nov 28 18:13:28 2013
@@ -53,6 +53,11 @@ public interface L2Cache {
   public int evictBlocksByHfileName(String hfileName);
 
   /**
+   * @return true if the cache has been shutdown
+   */
+  public boolean isShutdown();
+
+  /**
    * Shutdown the cache
    */
   public void shutdown();

Modified: hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/io/hfile/bucket/BucketCache.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/io/hfile/bucket/BucketCache.java?rev=1546430&r1=1546429&r2=1546430&view=diff
==============================================================================
--- hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/io/hfile/bucket/BucketCache.java (original)
+++ hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/io/hfile/bucket/BucketCache.java Thu Nov 28 18:13:28 2013
@@ -772,6 +772,7 @@ public class BucketCache implements Heap
       writerThreads[i].interrupt();
     this.ramCache.clear();
     this.backingMap.clear();
+    this.cacheStats.reset();
   }
 
   private void join() throws InterruptedException {
@@ -796,6 +797,10 @@ public class BucketCache implements Heap
     return this.heapSize.get();
   }
 
+  public boolean isEnabled() {
+    return cacheEnabled;
+  }
+
   /**
    * Returns the total size of the block cache, in bytes.
    * @return size of cache, in bytes

Modified: hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java?rev=1546430&r1=1546429&r2=1546430&view=diff
==============================================================================
--- hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java (original)
+++ hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java Thu Nov 28 18:13:28 2013
@@ -446,6 +446,7 @@ public class HRegionServer implements HR
     reinitialize();
     SchemaMetrics.configureGlobally(conf);
     cacheConfig = new CacheConfig(conf);
+    configurationManager.registerObserver(cacheConfig);
 
     minCheckFSIntervalMillis =
         conf.getInt("hbase.regionserver.min.check.fs.interval", 30000);

Modified: hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/io/hfile/TestL2BucketCache.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/io/hfile/TestL2BucketCache.java?rev=1546430&r1=1546429&r2=1546430&view=diff
==============================================================================
--- hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/io/hfile/TestL2BucketCache.java (original)
+++ hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/io/hfile/TestL2BucketCache.java Thu Nov 28 18:13:28 2013
@@ -21,6 +21,7 @@ package org.apache.hadoop.hbase.io.hfile
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.ClientConfigurationUtil;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
@@ -44,9 +45,7 @@ import java.util.Collection;
 import java.util.Random;
 import java.util.concurrent.atomic.AtomicBoolean;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
 
 /**
  * Tests L2 bucket cache for correctness
@@ -109,7 +108,6 @@ public class TestL2BucketCache {
         conf);
     mockedL2Cache = new MockedL2Cache(underlyingCache);
 
-
     fs = FileSystem.get(conf);
     cacheConf = new CacheConfig.CacheConfigBuilder(conf)
         .withL2Cache(mockedL2Cache)
@@ -192,6 +190,42 @@ public class TestL2BucketCache {
     assertTrue("This test must have read > 0 blocks", offset > 0);
   }
 
+  @Test
+  public void testOnlinePolicyChanges() {
+    boolean oldL2CacheDataOnWrite = cacheConf.shouldL2CacheDataOnWrite();
+    boolean oldL2EvictOnPromotion = cacheConf.shouldL2EvictOnPromotion();
+    boolean oldL2EvictOnClose = cacheConf.shouldL2EvictOnClose();
+
+    Configuration newConf = new Configuration(conf);
+    newConf.setBoolean(CacheConfig.L2_CACHE_BLOCKS_ON_FLUSH_KEY,
+            !oldL2CacheDataOnWrite);
+    newConf.setBoolean(CacheConfig.L2_EVICT_ON_PROMOTION_KEY,
+            !oldL2EvictOnPromotion);
+    newConf.setBoolean(CacheConfig.L2_EVICT_ON_CLOSE_KEY,
+            !oldL2EvictOnClose);
+    cacheConf.notifyOnChange(newConf);
+
+    assertNotSame("L2 caching on flush should be negated",
+            oldL2CacheDataOnWrite,
+            cacheConf.shouldL2CacheDataOnWrite());
+    assertNotSame("L2 eviction on promotion should be negated",
+            oldL2EvictOnPromotion,
+            cacheConf.shouldL2EvictOnPromotion());
+    assertNotSame("L2 eviction on close should be negated",
+            oldL2EvictOnClose,
+            cacheConf.shouldL2EvictOnClose());
+  }
+
+  @Test
+  public void testOnlineCacheDisable() {
+    Configuration newConf = new Configuration(conf);
+    newConf.setFloat(CacheConfig.L2_BUCKET_CACHE_SIZE_KEY, 0F);
+
+    assertTrue(cacheConf.isL2CacheEnabled());
+    cacheConf.notifyOnChange(newConf);
+    assertFalse(cacheConf.isL2CacheEnabled());
+  }
+
   private void writeStoreFile() throws IOException {
     Path storeFileParentDir = new Path(TEST_UTIL.getTestDir(),
         "test_cache_on_write");
@@ -264,6 +298,11 @@ public class TestL2BucketCache {
     }
 
     @Override
+    public boolean isShutdown() {
+      return underlying.isShutdown();
+    }
+
+    @Override
     public void shutdown() {
       underlying.shutdown();
     }