accumulo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From brianloss <>
Subject [GitHub] accumulo pull request: ACCUMULO-4173: Host Regex Table Load Balanc...
Date Wed, 30 Mar 2016 17:28:25 GMT
Github user brianloss commented on a diff in the pull request:
    --- Diff: server/base/src/main/java/org/apache/accumulo/server/master/balancer/
    @@ -0,0 +1,314 @@
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +package org.apache.accumulo.server.master.balancer;
    +import java.util.ArrayList;
    +import java.util.Collections;
    +import java.util.HashMap;
    +import java.util.List;
    +import java.util.Map;
    +import java.util.Map.Entry;
    +import java.util.Set;
    +import java.util.SortedMap;
    +import java.util.TreeMap;
    +import java.util.regex.Pattern;
    +import org.apache.accumulo.core.client.admin.TableOperations;
    +import org.apache.accumulo.core.conf.AccumuloConfiguration;
    +import org.apache.accumulo.core.conf.Property;
    +import org.apache.accumulo.core.master.thrift.TabletServerStatus;
    +import org.apache.accumulo.core.tabletserver.thrift.TabletStats;
    +import org.apache.accumulo.server.conf.ServerConfiguration;
    +import org.apache.accumulo.server.master.state.TServerInstance;
    +import org.apache.accumulo.server.master.state.TabletMigration;
    +import org.apache.thrift.TException;
    +import org.slf4j.Logger;
    +import org.slf4j.LoggerFactory;
    + * This balancer will create pools of tablet servers by grouping tablet servers that
match a regex into the same pool and calling the balancer set on the table
    + * to balance within the set of matching tablet servers. <br>
    + * Regex properties for this balancer are specified as:<br>
    + * <b>;tablename&gt;=&lt;regex&gt;</b><br>
    + * Periodically (default 5m) this balancer will check to see if a tablet server is hosting
tablets that it should not be according to the regex configuration.
    + * If this occurs then the offending tablets will be reassigned. This would cover the
case where the configuration is changed and the master is restarted while
    + * the tablet servers are up. To change the out of bounds check time period, set the
following property:<br>
    + * <b></b><br>
    + * Periodically (default 5m) this balancer will regroup the set of current tablet servers
into pools based on regexes applied to the tserver host names. This
    + * would cover the case of tservers dying or coming online. To change the host pool check
time period, set the following property: <br>
    + * <b></b><br>
    + * Regex matching can be based on either the host name (default) or host ip address.
To set this balancer to match the regular expressions to the tablet server
    + * IP address, then set the following property:<br>
    + * <b></b>
    + *
    + */
    +public class HostRegexTableLoadBalancer extends TableLoadBalancer {
    +  private static final Logger LOG = LoggerFactory.getLogger(HostRegexTableLoadBalancer.class);
    +  public static final String HOST_BALANCER_PREFIX = Property.TABLE_ARBITRARY_PROP_PREFIX.getKey()
+ "";
    +  public static final String HOST_BALANCER_OOB_CHECK = Property.TABLE_ARBITRARY_PROP_PREFIX.getKey()
+ "";
    +  private static final String HOST_BALANCER_OOB_DEFAULT = "5m";
    +  public static final String HOST_BALANCER_POOL_RECHECK_KEY = Property.TABLE_ARBITRARY_PROP_PREFIX.getKey()
+ "";
    +  private static final String HOST_BALANCER_POOL_RECHECK_DEFAULT = "5m";
    +  public static final String HOST_BALANCER_REGEX_USING_IPS = Property.TABLE_ARBITRARY_PROP_PREFIX.getKey()
+ "";
    +  protected static final String DEFAULT_POOL = "HostTableLoadBalancer.ALL";
    +  protected long oobCheckMillis = AccumuloConfiguration.getTimeInMillis(HOST_BALANCER_OOB_DEFAULT);
    +  protected long poolRecheckMillis = AccumuloConfiguration.getTimeInMillis(HOST_BALANCER_POOL_RECHECK_DEFAULT);
    +  private Map<String,String> tableIdToTableName = null;
    +  private Map<String,Pattern> poolNameToRegexPattern = null;
    +  private long lastOOBCheck = System.currentTimeMillis();
    +  private long lastPoolRecheck = 0;
    +  private boolean isIpBasedRegex = false;
    +  private Map<String,SortedMap<TServerInstance,TabletServerStatus>> pools
= new HashMap<String,SortedMap<TServerInstance,TabletServerStatus>>();
    +  /**
    +   * Group the set of current tservers by pool name. Tservers that don't match a regex
are put into a default ppol.
    +   *
    +   * @param current
    +   *          map of current tservers
    +   * @return current servers grouped by pool name, if not a match it is put into a default
    +   */
    +  protected synchronized Map<String,SortedMap<TServerInstance,TabletServerStatus>>
splitCurrentByRegex(SortedMap<TServerInstance,TabletServerStatus> current) {
    +    if ((System.currentTimeMillis() - lastPoolRecheck) > poolRecheckMillis) {
    +      Map<String,SortedMap<TServerInstance,TabletServerStatus>> newPools
= new HashMap<String,SortedMap<TServerInstance,TabletServerStatus>>();
    +      for (Entry<TServerInstance,TabletServerStatus> e : current.entrySet()) {
    +        String tableName = getPoolNameForHost(e.getKey().host());
    +        if (!newPools.containsKey(tableName)) {
    +          newPools.put(tableName, new TreeMap<TServerInstance,TabletServerStatus>());
    +        }
    +        newPools.get(tableName).put(e.getKey(), e.getValue());
    +      }
    +      // Ensure that no host is in more than one pool
    +      // TODO: I'm not sure that I need to check for disjoint as the call to getPoolNameForHost
checks for more than one match
    +      boolean error = false;
    +      for (SortedMap<TServerInstance,TabletServerStatus> s1 : newPools.values())
    --- End diff --
    This nested loop is doing a lot more disjoint checks than need to be done. You could change
the inner loop to iterate over a tailMap starting from the current outer loop value to get
rid of the dups.
    That being said, I can also think of cases where you might actually want disjoint pools.
For example, one pool could be for "archive" data which is large and not accessed very often,
so you want to spread it across all tservers. Then other pools, for hot tables would be on
subsets of the tservers. To support this would mean some re-architecting of the code since
the check would need to be get pool for host and table name.

If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at or file a JIRA ticket
with INFRA.

View raw message