Return-Path: X-Original-To: apmail-hbase-commits-archive@www.apache.org Delivered-To: apmail-hbase-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id CB4A218298 for ; Mon, 21 Sep 2015 13:45:13 +0000 (UTC) Received: (qmail 58578 invoked by uid 500); 21 Sep 2015 13:45:13 -0000 Delivered-To: apmail-hbase-commits-archive@hbase.apache.org Received: (qmail 58538 invoked by uid 500); 21 Sep 2015 13:45:13 -0000 Mailing-List: contact commits-help@hbase.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@hbase.apache.org Delivered-To: mailing list commits@hbase.apache.org Received: (qmail 58529 invoked by uid 99); 21 Sep 2015 13:45:13 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 21 Sep 2015 13:45:13 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 701CEE027D; Mon, 21 Sep 2015 13:45:13 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: tedyu@apache.org To: commits@hbase.apache.org Message-Id: <613e1ca086aa4c34aadaebf2d75171fa@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: hbase git commit: HBASE-14448 Refine RegionGroupingProvider Phase-2: remove provider nesting and formalize wal group name (Yu Li) Date: Mon, 21 Sep 2015 13:45:13 +0000 (UTC) Repository: hbase Updated Branches: refs/heads/branch-1 566a20145 -> 81d04cde2 HBASE-14448 Refine RegionGroupingProvider Phase-2: remove provider nesting and formalize wal group name (Yu Li) Project: http://git-wip-us.apache.org/repos/asf/hbase/repo Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/81d04cde Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/81d04cde Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/81d04cde Branch: refs/heads/branch-1 Commit: 81d04cde275addcef5730943721c0f3601f74a72 Parents: 566a201 Author: tedyu Authored: Mon Sep 21 06:45:02 2015 -0700 Committer: tedyu Committed: Mon Sep 21 06:45:02 2015 -0700 ---------------------------------------------------------------------- .../hbase/wal/BoundedGroupingStrategy.java | 2 +- .../hadoop/hbase/wal/DefaultWALProvider.java | 19 +-- .../hbase/wal/RegionGroupingProvider.java | 136 ++++++++++++------- 3 files changed, 98 insertions(+), 59 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hbase/blob/81d04cde/hbase-server/src/main/java/org/apache/hadoop/hbase/wal/BoundedGroupingStrategy.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/wal/BoundedGroupingStrategy.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/wal/BoundedGroupingStrategy.java index 14c5594..c8f434f 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/wal/BoundedGroupingStrategy.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/wal/BoundedGroupingStrategy.java @@ -27,7 +27,7 @@ import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.wal.RegionGroupingProvider.RegionGroupingStrategy; /** - * A WAL grouping strategy that limits the number of delegate providers (i.e. wal group) to + * A WAL grouping strategy that limits the number of wal groups to * "hbase.wal.regiongrouping.numgroups". */ @InterfaceAudience.Private http://git-wip-us.apache.org/repos/asf/hbase/blob/81d04cde/hbase-server/src/main/java/org/apache/hadoop/hbase/wal/DefaultWALProvider.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/wal/DefaultWALProvider.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/wal/DefaultWALProvider.java index 5e65f47..23dd79e 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/wal/DefaultWALProvider.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/wal/DefaultWALProvider.java @@ -76,7 +76,7 @@ public class DefaultWALProvider implements WALProvider { void init(FileSystem fs, Path path, Configuration c, boolean overwritable) throws IOException; } - protected FSHLog log = null; + protected volatile FSHLog log = null; private WALFactory factory = null; private Configuration conf = null; private List listeners = null; @@ -121,13 +121,16 @@ public class DefaultWALProvider implements WALProvider { @Override public WAL getWAL(final byte[] identifier) throws IOException { - // must lock since getWAL will create hlog on fs which is time consuming - synchronized (walCreateLock) { - if (log == null) { - log = new FSHLog(FileSystem.get(conf), FSUtils.getRootDir(conf), - getWALDirectoryName(factory.factoryId), HConstants.HREGION_OLDLOGDIR_NAME, conf, - listeners, true, logPrefix, - META_WAL_PROVIDER_ID.equals(providerId) ? META_WAL_PROVIDER_ID : null); + if (log == null) { + // only lock when need to create wal, and need to lock since + // creating hlog on fs is time consuming + synchronized (walCreateLock) { + if (log == null) { + log = new FSHLog(FileSystem.get(conf), FSUtils.getRootDir(conf), + getWALDirectoryName(factory.factoryId), HConstants.HREGION_OLDLOGDIR_NAME, conf, + listeners, true, logPrefix, + META_WAL_PROVIDER_ID.equals(providerId) ? META_WAL_PROVIDER_ID : null); + } } } return log; http://git-wip-us.apache.org/repos/asf/hbase/blob/81d04cde/hbase-server/src/main/java/org/apache/hadoop/hbase/wal/RegionGroupingProvider.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/wal/RegionGroupingProvider.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/wal/RegionGroupingProvider.java index 8395818..00a5651 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/wal/RegionGroupingProvider.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/wal/RegionGroupingProvider.java @@ -18,23 +18,30 @@ */ package org.apache.hadoop.hbase.wal; +import static org.apache.hadoop.hbase.wal.DefaultWALProvider.META_WAL_PROVIDER_ID; +import static org.apache.hadoop.hbase.wal.DefaultWALProvider.WAL_FILE_NAME_DELIMITER; + import java.io.IOException; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.hbase.classification.InterfaceAudience; import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.FileSystem; +import org.apache.hadoop.hbase.HConstants; +import org.apache.hadoop.hbase.regionserver.wal.FSHLog; +import org.apache.hadoop.hbase.regionserver.wal.MetricsWAL; // imports for classes still in regionserver.wal import org.apache.hadoop.hbase.regionserver.wal.WALActionsListener; import org.apache.hadoop.hbase.util.Bytes; +import org.apache.hadoop.hbase.util.FSUtils; /** * A WAL Provider that returns a WAL per group of regions. @@ -43,14 +50,11 @@ import org.apache.hadoop.hbase.util.Bytes; * property "hbase.wal.regiongrouping.strategy". Current strategy choices are *
    *
  • defaultStrategy : Whatever strategy this version of HBase picks. currently - * "identity".
  • + * "bounded". *
  • identity : each region belongs to its own group.
  • + *
  • bounded : bounded number of groups and region evenly assigned to each group.
  • *
* Optionally, a FQCN to a custom implementation may be given. - * - * WAL creation is delegated to another WALProvider, configured via the property - * "hbase.wal.regiongrouping.delegate". The property takes the same options as "hbase.wal.provider" - * (ref {@link WALFactory}) and defaults to the defaultProvider. */ @InterfaceAudience.Private class RegionGroupingProvider implements WALProvider { @@ -120,21 +124,22 @@ class RegionGroupingProvider implements WALProvider { public static final String REGION_GROUPING_STRATEGY = "hbase.wal.regiongrouping.strategy"; public static final String DEFAULT_REGION_GROUPING_STRATEGY = Strategies.defaultStrategy.name(); - static final String DELEGATE_PROVIDER = "hbase.wal.regiongrouping.delegate"; - static final String DEFAULT_DELEGATE_PROVIDER = WALFactory.Providers.defaultProvider.name(); + private static final String META_WAL_GROUP_NAME = "meta"; - /** A group-provider mapping, recommended to make sure one-one rather than many-one mapping */ - protected final ConcurrentMap cached = - new ConcurrentHashMap(); - /** Stores delegation providers (no duplicated) used by this RegionGroupingProvider */ - private final Set providers = Collections - .synchronizedSet(new HashSet()); + /** A group-wal mapping, recommended to make sure one-one rather than many-one mapping */ + protected final Map cached = new HashMap(); + /** Stores unique wals generated by this RegionGroupingProvider */ + private final Set logs = Collections.synchronizedSet(new HashSet()); + /** + * we synchronize on walCacheLock to prevent wal recreation in different threads + */ + final Object walCacheLock = new Object(); protected RegionGroupingStrategy strategy = null; - private WALFactory factory = null; private List listeners = null; private String providerId = null; + private Configuration conf = null; @Override public void init(final WALFactory factory, final Configuration conf, @@ -142,49 +147,80 @@ class RegionGroupingProvider implements WALProvider { if (null != strategy) { throw new IllegalStateException("WALProvider.init should only be called once."); } - this.factory = factory; this.listeners = null == listeners ? null : Collections.unmodifiableList(listeners); - this.providerId = providerId; + StringBuilder sb = new StringBuilder().append(factory.factoryId); + if (providerId != null) { + if (providerId.startsWith(WAL_FILE_NAME_DELIMITER)) { + sb.append(providerId); + } else { + sb.append(WAL_FILE_NAME_DELIMITER).append(providerId); + } + } + this.providerId = sb.toString(); this.strategy = getStrategy(conf, REGION_GROUPING_STRATEGY, DEFAULT_REGION_GROUPING_STRATEGY); + this.conf = conf; } /** * Populate the cache for this group. */ - WALProvider populateCache(final String group) throws IOException { - final WALProvider temp = factory.getProvider(DELEGATE_PROVIDER, DEFAULT_DELEGATE_PROVIDER, - listeners, providerId + "-" + UUID.randomUUID()); - final WALProvider extant = cached.putIfAbsent(group, temp); - if (null != extant) { - // someone else beat us to initializing, just take what they set. - temp.close(); - return extant; + FSHLog populateCache(String groupName) throws IOException { + boolean isMeta = META_WAL_PROVIDER_ID.equals(providerId); + String hlogPrefix; + List listeners; + if (isMeta) { + hlogPrefix = this.providerId; + // don't watch log roll for meta + listeners = Collections. singletonList(new MetricsWAL()); + } else { + hlogPrefix = groupName; + listeners = this.listeners; + } + FSHLog log = new FSHLog(FileSystem.get(conf), FSUtils.getRootDir(conf), + DefaultWALProvider.getWALDirectoryName(providerId), HConstants.HREGION_OLDLOGDIR_NAME, + conf, listeners, true, hlogPrefix, isMeta ? META_WAL_PROVIDER_ID : null); + cached.put(groupName, log); + logs.add(log); + return log; + } + + private WAL getWAL(final String group) throws IOException { + WAL log = cached.get(walCacheLock); + if (null == log) { + // only lock when need to create wal, and need to lock since + // creating hlog on fs is time consuming + synchronized (this.walCacheLock) { + log = cached.get(group);// check again + if (null == log) { + log = populateCache(group); + } + } } - providers.add(temp); - return temp; + return log; } @Override public WAL getWAL(final byte[] identifier) throws IOException { - final String group = strategy.group(identifier); - WALProvider provider = cached.get(group); - if (null == provider) { - provider = populateCache(group); + final String group; + if (META_WAL_PROVIDER_ID.equals(this.providerId)) { + group = META_WAL_GROUP_NAME; + } else { + group = strategy.group(identifier); } - return provider.getWAL(identifier); + return getWAL(group); } @Override public void shutdown() throws IOException { // save the last exception and rethrow IOException failure = null; - synchronized (providers) { - for (WALProvider provider : providers) { + synchronized (logs) { + for (FSHLog wal : logs) { try { - provider.shutdown(); + wal.shutdown(); } catch (IOException exception) { - LOG.error("Problem shutting down provider '" + provider + "': " + exception.getMessage()); - LOG.debug("Details of problem shutting down provider '" + provider + "'", exception); + LOG.error("Problem shutting down log '" + wal + "': " + exception.getMessage()); + LOG.debug("Details of problem shutting down log '" + wal + "'", exception); failure = exception; } } @@ -198,13 +234,13 @@ class RegionGroupingProvider implements WALProvider { public void close() throws IOException { // save the last exception and rethrow IOException failure = null; - synchronized (providers) { - for (WALProvider provider : providers) { + synchronized (logs) { + for (FSHLog wal : logs) { try { - provider.close(); + wal.close(); } catch (IOException exception) { - LOG.error("Problem closing provider '" + provider + "': " + exception.getMessage()); - LOG.debug("Details of problem shutting down provider '" + provider + "'", exception); + LOG.error("Problem closing log '" + wal + "': " + exception.getMessage()); + LOG.debug("Details of problem closing wal '" + wal + "'", exception); failure = exception; } } @@ -226,9 +262,9 @@ class RegionGroupingProvider implements WALProvider { @Override public long getNumLogFiles() { long numLogFiles = 0; - synchronized (providers) { - for (WALProvider provider : providers) { - numLogFiles += provider.getNumLogFiles(); + synchronized (logs) { + for (FSHLog wal : logs) { + numLogFiles += wal.getNumLogFiles(); } } return numLogFiles; @@ -237,9 +273,9 @@ class RegionGroupingProvider implements WALProvider { @Override public long getLogFileSize() { long logFileSize = 0; - synchronized (providers) { - for (WALProvider provider : providers) { - logFileSize += provider.getLogFileSize(); + synchronized (logs) { + for (FSHLog wal : logs) { + logFileSize += wal.getLogFileSize(); } } return logFileSize;