Search in sources :

Example 6 with TabletMigration

use of org.apache.accumulo.server.master.state.TabletMigration in project accumulo by apache.

the class GroupBalancer method populateMigrations.

private void populateMigrations(Set<TServerInstance> current, List<TabletMigration> migrationsOut, Moves moves) {
    if (moves.size() == 0) {
        return;
    }
    Function<KeyExtent, String> partitioner = getPartitioner();
    for (Pair<KeyExtent, Location> entry : getLocationProvider()) {
        String group = partitioner.apply(entry.getFirst());
        Location loc = entry.getSecond();
        if (loc.equals(Location.NONE) || !current.contains(loc.getTserverInstance())) {
            migrationsOut.clear();
            return;
        }
        TServerInstance dest = moves.removeMove(loc.getTserverInstance(), group);
        if (dest != null) {
            migrationsOut.add(new TabletMigration(entry.getFirst(), loc.getTserverInstance(), dest));
            if (moves.size() == 0) {
                break;
            }
        }
    }
}
Also used : TabletMigration(org.apache.accumulo.server.master.state.TabletMigration) KeyExtent(org.apache.accumulo.core.data.impl.KeyExtent) TServerInstance(org.apache.accumulo.server.master.state.TServerInstance)

Example 7 with TabletMigration

use of org.apache.accumulo.server.master.state.TabletMigration in project accumulo by apache.

the class TableLoadBalancer method balance.

@Override
public long balance(SortedMap<TServerInstance, TabletServerStatus> current, Set<KeyExtent> migrations, List<TabletMigration> migrationsOut) {
    long minBalanceTime = 5 * 1000;
    // Iterate over the tables and balance each of them
    TableOperations t = getTableOperations();
    if (t == null)
        return minBalanceTime;
    for (String s : t.tableIdMap().values()) {
        ArrayList<TabletMigration> newMigrations = new ArrayList<>();
        long tableBalanceTime = getBalancerForTable(Table.ID.of(s)).balance(current, migrations, newMigrations);
        if (tableBalanceTime < minBalanceTime)
            minBalanceTime = tableBalanceTime;
        migrationsOut.addAll(newMigrations);
    }
    return minBalanceTime;
}
Also used : TableOperations(org.apache.accumulo.core.client.admin.TableOperations) TabletMigration(org.apache.accumulo.server.master.state.TabletMigration) ArrayList(java.util.ArrayList)

Example 8 with TabletMigration

use of org.apache.accumulo.server.master.state.TabletMigration in project accumulo by apache.

the class HostRegexTableLoadBalancer method balance.

@Override
public long balance(SortedMap<TServerInstance, TabletServerStatus> current, Set<KeyExtent> migrations, List<TabletMigration> migrationsOut) {
    long minBalanceTime = 20 * 1000;
    // Iterate over the tables and balance each of them
    TableOperations t = getTableOperations();
    if (t == null)
        return minBalanceTime;
    Map<String, String> tableIdMap = t.tableIdMap();
    long now = System.currentTimeMillis();
    Map<String, SortedMap<TServerInstance, TabletServerStatus>> currentGrouped = splitCurrentByRegex(current);
    if ((now - this.lastOOBCheck) > this.oobCheckMillis) {
        try {
            // Check to see if a tablet is assigned outside the bounds of the pool. If so, migrate it.
            for (String table : t.list()) {
                LOG.debug("Checking for out of bounds tablets for table {}", table);
                String tablePoolName = getPoolNameForTable(table);
                for (Entry<TServerInstance, TabletServerStatus> e : current.entrySet()) {
                    // pool names are the same as table names, except in the DEFAULT case.
                    // If this table is assigned to a pool for this host, then move on.
                    List<String> hostPools = getPoolNamesForHost(e.getKey().host());
                    if (hostPools.contains(tablePoolName)) {
                        continue;
                    }
                    String tid = tableIdMap.get(table);
                    if (null == tid) {
                        LOG.warn("Unable to check for out of bounds tablets for table {}, it may have been deleted or renamed.", table);
                        continue;
                    }
                    try {
                        List<TabletStats> outOfBoundsTablets = getOnlineTabletsForTable(e.getKey(), Table.ID.of(tid));
                        if (null == outOfBoundsTablets) {
                            continue;
                        }
                        Random random = new Random();
                        for (TabletStats ts : outOfBoundsTablets) {
                            KeyExtent ke = new KeyExtent(ts.getExtent());
                            if (migrations.contains(ke)) {
                                LOG.debug("Migration for out of bounds tablet {} has already been requested", ke);
                                continue;
                            }
                            String poolName = getPoolNameForTable(table);
                            SortedMap<TServerInstance, TabletServerStatus> currentView = currentGrouped.get(poolName);
                            if (null != currentView) {
                                int skip = random.nextInt(currentView.size());
                                Iterator<TServerInstance> iter = currentView.keySet().iterator();
                                for (int i = 0; i < skip; i++) {
                                    iter.next();
                                }
                                TServerInstance nextTS = iter.next();
                                LOG.info("Tablet {} is currently outside the bounds of the regex, migrating from {} to {}", ke, e.getKey(), nextTS);
                                migrationsOut.add(new TabletMigration(ke, e.getKey(), nextTS));
                                if (migrationsOut.size() >= this.maxTServerMigrations) {
                                    break;
                                }
                            } else {
                                LOG.warn("No tablet servers online for pool {}, unable to migrate out of bounds tablets", poolName);
                            }
                        }
                    } catch (TException e1) {
                        LOG.error("Error in OOB check getting tablets for table {} from server {}", tid, e.getKey().host(), e);
                    }
                }
            }
        } finally {
            // this could have taken a while...get a new time
            this.lastOOBCheck = System.currentTimeMillis();
        }
    }
    if (migrationsOut.size() > 0) {
        LOG.warn("Not balancing tables due to moving {} out of bounds tablets", migrationsOut.size());
        LOG.info("Migrating out of bounds tablets: {}", migrationsOut);
        return minBalanceTime;
    }
    if (migrations != null && migrations.size() > 0) {
        if (migrations.size() >= maxOutstandingMigrations) {
            LOG.warn("Not balancing tables due to {} outstanding migrations", migrations.size());
            if (LOG.isTraceEnabled()) {
                LOG.trace("Sample up to 10 outstanding migrations: {}", Iterables.limit(migrations, 10));
            }
            return minBalanceTime;
        }
        LOG.debug("Current outstanding migrations of {} being applied", migrations.size());
        if (LOG.isTraceEnabled()) {
            LOG.trace("Sample up to 10 outstanding migrations: {}", Iterables.limit(migrations, 10));
        }
        migrationsFromLastPass.keySet().retainAll(migrations);
        SortedMap<TServerInstance, TabletServerStatus> currentCopy = new TreeMap<>(current);
        Multimap<TServerInstance, String> serverTableIdCopied = HashMultimap.create();
        for (TabletMigration migration : migrationsFromLastPass.values()) {
            TableInfo fromInfo = getTableInfo(currentCopy, serverTableIdCopied, migration.tablet.getTableId().toString(), migration.oldServer);
            if (fromInfo != null) {
                fromInfo.setOnlineTablets(fromInfo.getOnlineTablets() - 1);
            }
            TableInfo toInfo = getTableInfo(currentCopy, serverTableIdCopied, migration.tablet.getTableId().toString(), migration.newServer);
            if (toInfo != null) {
                toInfo.setOnlineTablets(toInfo.getOnlineTablets() + 1);
            }
        }
        migrations = EMPTY_MIGRATIONS;
    } else {
        migrationsFromLastPass.clear();
    }
    for (String s : tableIdMap.values()) {
        Table.ID tableId = Table.ID.of(s);
        String tableName = tableIdToTableName.get(tableId);
        String regexTableName = getPoolNameForTable(tableName);
        SortedMap<TServerInstance, TabletServerStatus> currentView = currentGrouped.get(regexTableName);
        if (null == currentView) {
            LOG.warn("Skipping balance for table {} as no tablet servers are online.", tableName);
            continue;
        }
        ArrayList<TabletMigration> newMigrations = new ArrayList<>();
        getBalancerForTable(tableId).balance(currentView, migrations, newMigrations);
        if (newMigrations.isEmpty()) {
            tableToTimeSinceNoMigrations.remove(s);
        } else if (tableToTimeSinceNoMigrations.containsKey(s)) {
            if ((now - tableToTimeSinceNoMigrations.get(s)) > ONE_HOUR) {
                LOG.warn("We have been consistently producing migrations for {}: {}", tableName, Iterables.limit(newMigrations, 10));
            }
        } else {
            tableToTimeSinceNoMigrations.put(s, now);
        }
        migrationsOut.addAll(newMigrations);
        if (migrationsOut.size() >= this.maxTServerMigrations) {
            break;
        }
    }
    for (TabletMigration migration : migrationsOut) {
        migrationsFromLastPass.put(migration.tablet, migration);
    }
    LOG.info("Migrating tablets for balance: {}", migrationsOut);
    return minBalanceTime;
}
Also used : TException(org.apache.thrift.TException) ArrayList(java.util.ArrayList) KeyExtent(org.apache.accumulo.core.data.impl.KeyExtent) TableOperations(org.apache.accumulo.core.client.admin.TableOperations) Random(java.util.Random) TableInfo(org.apache.accumulo.core.master.thrift.TableInfo) TabletServerStatus(org.apache.accumulo.core.master.thrift.TabletServerStatus) Table(org.apache.accumulo.core.client.impl.Table) TabletMigration(org.apache.accumulo.server.master.state.TabletMigration) TabletStats(org.apache.accumulo.core.tabletserver.thrift.TabletStats) TreeMap(java.util.TreeMap) TServerInstance(org.apache.accumulo.server.master.state.TServerInstance) SortedMap(java.util.SortedMap)

Example 9 with TabletMigration

use of org.apache.accumulo.server.master.state.TabletMigration in project accumulo by apache.

the class DefaultLoadBalancerTest method testUnevenAssignment2.

@Test
public void testUnevenAssignment2() {
    // make 26 servers
    for (char c : "abcdefghijklmnopqrstuvwxyz".toCharArray()) {
        String cString = Character.toString(c);
        HostAndPort fakeAddress = HostAndPort.fromParts("127.0.0.1", c);
        String fakeInstance = cString;
        TServerInstance tsi = new TServerInstance(fakeAddress, fakeInstance);
        FakeTServer fakeTServer = new FakeTServer();
        servers.put(tsi, fakeTServer);
    }
    // put 60 tablets on 25 of them
    List<Entry<TServerInstance, FakeTServer>> shortList = new ArrayList<>(servers.entrySet());
    Entry<TServerInstance, FakeTServer> shortServer = shortList.remove(0);
    int c = 0;
    for (int i = 0; i < 60; i++) {
        for (Entry<TServerInstance, FakeTServer> entry : shortList) {
            entry.getValue().extents.add(makeExtent("t" + c, null, null));
        }
    }
    // put 10 on the that short server:
    for (int i = 0; i < 10; i++) {
        shortServer.getValue().extents.add(makeExtent("s" + i, null, null));
    }
    TestDefaultLoadBalancer balancer = new TestDefaultLoadBalancer();
    Set<KeyExtent> migrations = Collections.emptySet();
    int moved = 0;
    // balance until we can't balance no more!
    while (true) {
        List<TabletMigration> migrationsOut = new ArrayList<>();
        balancer.balance(getAssignments(servers), migrations, migrationsOut);
        if (migrationsOut.size() == 0)
            break;
        for (TabletMigration migration : migrationsOut) {
            if (servers.get(migration.oldServer).extents.remove(migration.tablet))
                moved++;
            last.remove(migration.tablet);
            servers.get(migration.newServer).extents.add(migration.tablet);
            last.put(migration.tablet, migration.newServer);
        }
    }
    // average is 58, with 2 at 59: we need 48 more moved to the short server
    assertEquals(48, moved);
}
Also used : TabletMigration(org.apache.accumulo.server.master.state.TabletMigration) ArrayList(java.util.ArrayList) KeyExtent(org.apache.accumulo.core.data.impl.KeyExtent) TServerInstance(org.apache.accumulo.server.master.state.TServerInstance) HostAndPort(org.apache.accumulo.core.util.HostAndPort) Entry(java.util.Map.Entry) Test(org.junit.Test)

Example 10 with TabletMigration

use of org.apache.accumulo.server.master.state.TabletMigration in project accumulo by apache.

the class HostRegexTableLoadBalancerTest method testBalanceWithTooManyOutstandingMigrations.

@Test
public void testBalanceWithTooManyOutstandingMigrations() {
    List<TabletMigration> migrationsOut = new ArrayList<>();
    init(new AccumuloServerContext(instance, factory));
    // lets say we already have migrations ongoing for the FOO and BAR table extends (should be 5 of each of them) for a total of 10
    Set<KeyExtent> migrations = new HashSet<>();
    migrations.addAll(tableExtents.get(FOO.getTableName()));
    migrations.addAll(tableExtents.get(BAR.getTableName()));
    long wait = this.balance(Collections.unmodifiableSortedMap(createCurrent(15)), migrations, migrationsOut);
    Assert.assertEquals(20000, wait);
    // no migrations should have occurred as 10 is the maxOutstandingMigrations
    Assert.assertEquals(0, migrationsOut.size());
}
Also used : AccumuloServerContext(org.apache.accumulo.server.AccumuloServerContext) TabletMigration(org.apache.accumulo.server.master.state.TabletMigration) ArrayList(java.util.ArrayList) TKeyExtent(org.apache.accumulo.core.data.thrift.TKeyExtent) KeyExtent(org.apache.accumulo.core.data.impl.KeyExtent) HashSet(java.util.HashSet) Test(org.junit.Test)

Aggregations

TabletMigration (org.apache.accumulo.server.master.state.TabletMigration)14 ArrayList (java.util.ArrayList)13 KeyExtent (org.apache.accumulo.core.data.impl.KeyExtent)13 TServerInstance (org.apache.accumulo.server.master.state.TServerInstance)9 Test (org.junit.Test)9 AccumuloServerContext (org.apache.accumulo.server.AccumuloServerContext)5 HashMap (java.util.HashMap)4 HashSet (java.util.HashSet)4 Table (org.apache.accumulo.core.client.impl.Table)4 TKeyExtent (org.apache.accumulo.core.data.thrift.TKeyExtent)3 TabletServerStatus (org.apache.accumulo.core.master.thrift.TabletServerStatus)3 TabletStats (org.apache.accumulo.core.tabletserver.thrift.TabletStats)3 HostAndPort (org.apache.accumulo.core.util.HostAndPort)3 TreeMap (java.util.TreeMap)2 TableOperations (org.apache.accumulo.core.client.admin.TableOperations)2 TableInfo (org.apache.accumulo.core.master.thrift.TableInfo)2 TException (org.apache.thrift.TException)2 Entry (java.util.Map.Entry)1 Random (java.util.Random)1 SortedMap (java.util.SortedMap)1