Search in sources :

Example 6 with TServerStatus

use of org.apache.accumulo.core.spi.balancer.data.TServerStatus in project accumulo by apache.

the class SimpleLoadBalancerTest method testAssignMigrations.

@Test
public void testAssignMigrations() {
    servers.put(new TabletServerIdImpl("127.0.0.1", 1234, "a"), new FakeTServer());
    servers.put(new TabletServerIdImpl("127.0.0.2", 1234, "b"), new FakeTServer());
    servers.put(new TabletServerIdImpl("127.0.0.3", 1234, "c"), new FakeTServer());
    List<TabletId> metadataTable = new ArrayList<>();
    String table = "t1";
    metadataTable.add(makeTablet(table, null, null));
    table = "t2";
    metadataTable.add(makeTablet(table, "a", null));
    metadataTable.add(makeTablet(table, null, "a"));
    table = "t3";
    metadataTable.add(makeTablet(table, "a", null));
    metadataTable.add(makeTablet(table, "b", "a"));
    metadataTable.add(makeTablet(table, "c", "b"));
    metadataTable.add(makeTablet(table, "d", "c"));
    metadataTable.add(makeTablet(table, "e", "d"));
    metadataTable.add(makeTablet(table, null, "e"));
    Collections.sort(metadataTable);
    TestSimpleLoadBalancer balancer = new TestSimpleLoadBalancer();
    SortedMap<TabletServerId, TServerStatus> current = new TreeMap<>();
    for (Entry<TabletServerId, FakeTServer> entry : servers.entrySet()) {
        current.put(entry.getKey(), entry.getValue().getStatus());
    }
    assignTablets(metadataTable, servers, current, balancer);
    // Verify that the counts on the tables are correct
    Map<String, Integer> expectedCounts = new HashMap<>();
    expectedCounts.put("t1", 1);
    expectedCounts.put("t2", 1);
    expectedCounts.put("t3", 2);
    checkBalance(metadataTable, servers, expectedCounts);
    // Rebalance once
    for (Entry<TabletServerId, FakeTServer> entry : servers.entrySet()) {
        current.put(entry.getKey(), entry.getValue().getStatus());
    }
    // Nothing should happen, we are balanced
    ArrayList<TabletMigration> out = new ArrayList<>();
    balancer.getMigrations(current, out);
    assertEquals(out.size(), 0);
    // Take down a tabletServer
    TabletServerId first = current.keySet().iterator().next();
    current.remove(first);
    FakeTServer remove = servers.remove(first);
    // reassign offline extents
    assignTablets(remove.tablets, servers, current, balancer);
    checkBalance(metadataTable, servers, null);
}
Also used : TabletMigration(org.apache.accumulo.core.spi.balancer.data.TabletMigration) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) TServerStatus(org.apache.accumulo.core.spi.balancer.data.TServerStatus) TabletServerIdImpl(org.apache.accumulo.core.manager.balancer.TabletServerIdImpl) TreeMap(java.util.TreeMap) TabletServerId(org.apache.accumulo.core.spi.balancer.data.TabletServerId) TabletId(org.apache.accumulo.core.data.TabletId) Test(org.junit.jupiter.api.Test)

Example 7 with TServerStatus

use of org.apache.accumulo.core.spi.balancer.data.TServerStatus in project accumulo by apache.

the class HostRegexTableLoadBalancer method getAssignments.

@Override
public void getAssignments(AssignmentParameters params) {
    Map<String, SortedMap<TabletServerId, TServerStatus>> pools = splitCurrentByRegex(params.currentStatus());
    // group the unassigned into tables
    Map<TableId, Map<TabletId, TabletServerId>> groupedUnassigned = new HashMap<>();
    params.unassignedTablets().forEach((ke, lastTserver) -> groupedUnassigned.computeIfAbsent(ke.getTable(), k -> new HashMap<>()).put(ke, lastTserver));
    Map<TableId, String> tableIdToTableName = environment.getTableIdMap().entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
    // Send a view of the current servers to the tables tablet balancer
    for (Entry<TableId, Map<TabletId, TabletServerId>> e : groupedUnassigned.entrySet()) {
        Map<TabletId, TabletServerId> newAssignments = new HashMap<>();
        String tableName = tableIdToTableName.get(e.getKey());
        String poolName = getPoolNameForTable(tableName);
        SortedMap<TabletServerId, TServerStatus> currentView = pools.get(poolName);
        if (currentView == null || currentView.isEmpty()) {
            LOG.warn("No tablet servers online for table {}, assigning within default pool", tableName);
            currentView = pools.get(DEFAULT_POOL);
            if (currentView == null) {
                LOG.error("No tablet servers exist in the default pool, unable to assign tablets for table {}", tableName);
                continue;
            }
        }
        LOG.debug("Sending {} tablets to balancer for table {} for assignment within tservers {}", e.getValue().size(), tableName, currentView.keySet());
        getBalancerForTable(e.getKey()).getAssignments(new AssignmentParamsImpl(currentView, e.getValue(), newAssignments));
        newAssignments.forEach(params::addAssignment);
    }
}
Also used : TableId(org.apache.accumulo.core.data.TableId) HashMap(java.util.HashMap) TServerStatus(org.apache.accumulo.core.spi.balancer.data.TServerStatus) AssignmentParamsImpl(org.apache.accumulo.core.manager.balancer.AssignmentParamsImpl) TabletServerId(org.apache.accumulo.core.spi.balancer.data.TabletServerId) SortedMap(java.util.SortedMap) TabletId(org.apache.accumulo.core.data.TabletId) HashMap(java.util.HashMap) Map(java.util.Map) TreeMap(java.util.TreeMap) SortedMap(java.util.SortedMap)

Example 8 with TServerStatus

use of org.apache.accumulo.core.spi.balancer.data.TServerStatus in project accumulo by apache.

the class HostRegexTableLoadBalancer method balance.

@Override
public long balance(BalanceParameters params) {
    long minBalanceTime = 20_000;
    // Iterate over the tables and balance each of them
    Map<String, TableId> tableIdMap = environment.getTableIdMap();
    Map<TableId, String> tableIdToTableName = tableIdMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
    tableIdToTableName.keySet().forEach(this::checkTableConfig);
    long now = System.currentTimeMillis();
    HrtlbConf myConf = hrtlbConf.get();
    SortedMap<TabletServerId, TServerStatus> current = params.currentStatus();
    Set<TabletId> migrations = params.currentMigrations();
    List<TabletMigration> migrationsOut = params.migrationsOut();
    Map<String, SortedMap<TabletServerId, TServerStatus>> currentGrouped = splitCurrentByRegex(params.currentStatus());
    if ((now - this.lastOOBCheck) > myConf.oobCheckMillis) {
        try {
            // Check to see if a tablet is assigned outside the bounds of the pool. If so, migrate it.
            for (String table : tableIdMap.keySet()) {
                LOG.debug("Checking for out of bounds tablets for table {}", table);
                String tablePoolName = getPoolNameForTable(table);
                for (Entry<TabletServerId, TServerStatus> 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());
                    if (hostPools.contains(tablePoolName)) {
                        continue;
                    }
                    TableId tid = tableIdMap.get(table);
                    if (tid == null) {
                        LOG.warn("Unable to check for out of bounds tablets for table {}," + " it may have been deleted or renamed.", table);
                        continue;
                    }
                    try {
                        List<TabletStatistics> outOfBoundsTablets = getOnlineTabletsForTable(e.getKey(), tid);
                        if (outOfBoundsTablets == null) {
                            continue;
                        }
                        for (TabletStatistics ts : outOfBoundsTablets) {
                            if (migrations.contains(ts.getTabletId())) {
                                LOG.debug("Migration for out of bounds tablet {} has already been requested", ts.getTabletId());
                                continue;
                            }
                            String poolName = getPoolNameForTable(table);
                            SortedMap<TabletServerId, TServerStatus> currentView = currentGrouped.get(poolName);
                            if (currentView != null) {
                                int skip = random.nextInt(currentView.size());
                                Iterator<TabletServerId> iter = currentView.keySet().iterator();
                                for (int i = 0; i < skip; i++) {
                                    iter.next();
                                }
                                TabletServerId nextTS = iter.next();
                                LOG.info("Tablet {} is currently outside the bounds of the" + " regex, migrating from {} to {}", ts.getTabletId(), e.getKey(), nextTS);
                                migrationsOut.add(new TabletMigration(ts.getTabletId(), e.getKey(), nextTS));
                                if (migrationsOut.size() >= myConf.maxTServerMigrations) {
                                    break;
                                }
                            } else {
                                LOG.warn("No tablet servers online for pool {}, unable to" + " migrate out of bounds tablets", poolName);
                            }
                        }
                    } catch (AccumuloException | AccumuloSecurityException e1) {
                        LOG.error("Error in OOB check getting tablets for table {} from server {} {}", tid, e.getKey().getHost(), e);
                    }
                }
            }
        } finally {
            // this could have taken a while...get a new time
            this.lastOOBCheck = System.currentTimeMillis();
        }
    }
    if (!migrationsOut.isEmpty()) {
        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.isEmpty()) {
        if (migrations.size() >= myConf.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<TabletServerId, TServerStatusImpl> currentCopy = new TreeMap<>();
        current.forEach((tid, status) -> currentCopy.put(tid, (TServerStatusImpl) status));
        Multimap<TabletServerId, String> serverTableIdCopied = HashMultimap.create();
        for (TabletMigration migration : migrationsFromLastPass.values()) {
            TableStatisticsImpl fromInfo = getTableInfo(currentCopy, serverTableIdCopied, migration.getTablet().getTable().canonical(), migration.getOldTabletServer());
            if (fromInfo != null) {
                fromInfo.setOnlineTabletCount(fromInfo.getOnlineTabletCount() - 1);
            }
            TableStatisticsImpl toInfo = getTableInfo(currentCopy, serverTableIdCopied, migration.getTablet().getTable().canonical(), migration.getNewTabletServer());
            if (toInfo != null) {
                toInfo.setOnlineTabletCount(toInfo.getOnlineTabletCount() + 1);
            }
        }
        migrations = EMPTY_MIGRATIONS;
    } else {
        migrationsFromLastPass.clear();
    }
    for (TableId tableId : tableIdMap.values()) {
        String tableName = tableIdToTableName.get(tableId);
        String regexTableName = getPoolNameForTable(tableName);
        SortedMap<TabletServerId, TServerStatus> currentView = currentGrouped.get(regexTableName);
        if (currentView == null) {
            LOG.warn("Skipping balance for table {} as no tablet servers are online.", tableName);
            continue;
        }
        ArrayList<TabletMigration> newMigrations = new ArrayList<>();
        getBalancerForTable(tableId).balance(new BalanceParamsImpl(currentView, migrations, newMigrations));
        if (newMigrations.isEmpty()) {
            tableToTimeSinceNoMigrations.remove(tableId);
        } else if (tableToTimeSinceNoMigrations.containsKey(tableId)) {
            if ((now - tableToTimeSinceNoMigrations.get(tableId)) > HOURS.toMillis(1)) {
                LOG.warn("We have been consistently producing migrations for {}: {}", tableName, Iterables.limit(newMigrations, 10));
            }
        } else {
            tableToTimeSinceNoMigrations.put(tableId, now);
        }
        migrationsOut.addAll(newMigrations);
        if (migrationsOut.size() >= myConf.maxTServerMigrations) {
            break;
        }
    }
    for (TabletMigration migration : migrationsOut) {
        migrationsFromLastPass.put(migration.getTablet(), migration);
    }
    LOG.info("Migrating tablets for balance: {}", migrationsOut);
    return minBalanceTime;
}
Also used : TableId(org.apache.accumulo.core.data.TableId) ArrayList(java.util.ArrayList) TServerStatusImpl(org.apache.accumulo.core.manager.balancer.TServerStatusImpl) TabletServerId(org.apache.accumulo.core.spi.balancer.data.TabletServerId) TabletStatistics(org.apache.accumulo.core.spi.balancer.data.TabletStatistics) AccumuloSecurityException(org.apache.accumulo.core.client.AccumuloSecurityException) AccumuloException(org.apache.accumulo.core.client.AccumuloException) BalanceParamsImpl(org.apache.accumulo.core.manager.balancer.BalanceParamsImpl) TabletMigration(org.apache.accumulo.core.spi.balancer.data.TabletMigration) TServerStatus(org.apache.accumulo.core.spi.balancer.data.TServerStatus) TreeMap(java.util.TreeMap) TableStatisticsImpl(org.apache.accumulo.core.manager.balancer.TableStatisticsImpl) SortedMap(java.util.SortedMap) TabletId(org.apache.accumulo.core.data.TabletId) HashMap(java.util.HashMap) Map(java.util.Map) TreeMap(java.util.TreeMap) SortedMap(java.util.SortedMap)

Example 9 with TServerStatus

use of org.apache.accumulo.core.spi.balancer.data.TServerStatus in project accumulo by apache.

the class TableLoadBalancerTest method generateFakeTablets.

static List<TabletStatistics> generateFakeTablets(TabletServerId tserver, TableId tableId) {
    List<TabletStatistics> result = new ArrayList<>();
    TServerStatus tableInfo = state.get(tserver);
    // generate some fake tablets
    for (int i = 0; i < tableInfo.getTableMap().get(tableId.canonical()).getOnlineTabletCount(); i++) {
        TabletStats stats = new TabletStats();
        stats.extent = new KeyExtent(tableId, new Text(tserver.getHost() + String.format("%03d", i + 1)), new Text(tserver.getHost() + String.format("%03d", i))).toThrift();
        result.add(new TabletStatisticsImpl(stats));
    }
    return result;
}
Also used : TabletStats(org.apache.accumulo.core.tabletserver.thrift.TabletStats) ArrayList(java.util.ArrayList) TServerStatus(org.apache.accumulo.core.spi.balancer.data.TServerStatus) TabletStatistics(org.apache.accumulo.core.spi.balancer.data.TabletStatistics) Text(org.apache.hadoop.io.Text) KeyExtent(org.apache.accumulo.core.dataImpl.KeyExtent) TabletStatisticsImpl(org.apache.accumulo.core.manager.balancer.TabletStatisticsImpl)

Example 10 with TServerStatus

use of org.apache.accumulo.core.spi.balancer.data.TServerStatus in project accumulo by apache.

the class ChaoticLoadBalancer method getAssignments.

@Override
public void getAssignments(AssignmentParameters params) {
    long total = params.unassignedTablets().size();
    long avg = (long) Math.ceil(((double) total) / params.currentStatus().size());
    Map<TabletServerId, Long> toAssign = new HashMap<>();
    List<TabletServerId> tServerArray = new ArrayList<>();
    for (Entry<TabletServerId, TServerStatus> e : params.currentStatus().entrySet()) {
        long numTablets = 0;
        for (TableStatistics ti : e.getValue().getTableMap().values()) {
            numTablets += ti.getTabletCount();
        }
        if (numTablets <= avg) {
            tServerArray.add(e.getKey());
            toAssign.put(e.getKey(), avg - numTablets);
        }
    }
    if (tServerArray.isEmpty()) {
        // No tservers to assign to
        return;
    }
    for (TabletId tabletId : params.unassignedTablets().keySet()) {
        int index = random.nextInt(tServerArray.size());
        TabletServerId dest = tServerArray.get(index);
        params.addAssignment(tabletId, dest);
        long remaining = toAssign.get(dest) - 1;
        if (remaining == 0) {
            tServerArray.remove(index);
            toAssign.remove(dest);
        } else {
            toAssign.put(dest, remaining);
        }
    }
}
Also used : HashMap(java.util.HashMap) TabletServerId(org.apache.accumulo.core.spi.balancer.data.TabletServerId) ArrayList(java.util.ArrayList) TServerStatus(org.apache.accumulo.core.spi.balancer.data.TServerStatus) TableStatistics(org.apache.accumulo.core.spi.balancer.data.TableStatistics) TabletId(org.apache.accumulo.core.data.TabletId)

Aggregations

TServerStatus (org.apache.accumulo.core.spi.balancer.data.TServerStatus)10 HashMap (java.util.HashMap)9 TabletServerId (org.apache.accumulo.core.spi.balancer.data.TabletServerId)9 ArrayList (java.util.ArrayList)8 TabletId (org.apache.accumulo.core.data.TabletId)6 TreeMap (java.util.TreeMap)5 TableId (org.apache.accumulo.core.data.TableId)5 Map (java.util.Map)4 SortedMap (java.util.SortedMap)4 AssignmentParamsImpl (org.apache.accumulo.core.manager.balancer.AssignmentParamsImpl)4 TabletMigration (org.apache.accumulo.core.spi.balancer.data.TabletMigration)4 TServerStatusImpl (org.apache.accumulo.core.manager.balancer.TServerStatusImpl)3 TabletServerIdImpl (org.apache.accumulo.core.manager.balancer.TabletServerIdImpl)3 TableStatistics (org.apache.accumulo.core.spi.balancer.data.TableStatistics)3 Test (org.junit.jupiter.api.Test)3 TableInfo (org.apache.accumulo.core.master.thrift.TableInfo)2 TabletStatistics (org.apache.accumulo.core.spi.balancer.data.TabletStatistics)2 ImmutableSortedMap (com.google.common.collect.ImmutableSortedMap)1 RateLimiter (com.google.common.util.concurrent.RateLimiter)1 SuppressFBWarnings (edu.umd.cs.findbugs.annotations.SuppressFBWarnings)1