use of org.apache.accumulo.server.master.state.TServerInstance in project accumulo by apache.
the class ChaoticLoadBalancer method getAssignments.
@Override
public void getAssignments(SortedMap<TServerInstance, TabletServerStatus> current, Map<KeyExtent, TServerInstance> unassigned, Map<KeyExtent, TServerInstance> assignments) {
long total = assignments.size() + unassigned.size();
long avg = (long) Math.ceil(((double) total) / current.size());
Map<TServerInstance, Long> toAssign = new HashMap<>();
List<TServerInstance> tServerArray = new ArrayList<>();
for (Entry<TServerInstance, TabletServerStatus> e : current.entrySet()) {
long numTablets = 0;
for (TableInfo ti : e.getValue().getTableMap().values()) {
numTablets += ti.tablets;
}
if (numTablets <= avg) {
tServerArray.add(e.getKey());
toAssign.put(e.getKey(), avg - numTablets);
}
}
if (tServerArray.isEmpty()) {
// No tservers to assign to
return;
}
for (KeyExtent ke : unassigned.keySet()) {
int index = r.nextInt(tServerArray.size());
TServerInstance dest = tServerArray.get(index);
assignments.put(ke, dest);
long remaining = toAssign.get(dest) - 1;
if (remaining == 0) {
tServerArray.remove(index);
toAssign.remove(dest);
} else {
toAssign.put(dest, remaining);
}
}
}
use of org.apache.accumulo.server.master.state.TServerInstance in project accumulo by apache.
the class DefaultLoadBalancer method getAssignment.
public TServerInstance getAssignment(SortedMap<TServerInstance, TabletServerStatus> locations, KeyExtent extent, TServerInstance last) {
if (locations.size() == 0)
return null;
if (last != null) {
// Maintain locality
String fakeSessionID = " ";
TServerInstance simple = new TServerInstance(last.getLocation(), fakeSessionID);
Iterator<TServerInstance> find = locations.tailMap(simple).keySet().iterator();
if (find.hasNext()) {
TServerInstance current = find.next();
if (current.host().equals(last.host()))
return current;
}
}
// Grab an iterator off of the set of options; use a new iterator if it hands back something not in the current list.
if (assignments == null || !assignments.hasNext())
assignments = randomize(locations.keySet()).iterator();
TServerInstance result = assignments.next();
if (!locations.containsKey(result)) {
assignments = null;
return randomize(locations.keySet()).iterator().next();
}
return result;
}
use of org.apache.accumulo.server.master.state.TServerInstance in project accumulo by apache.
the class GroupBalancer method getAssignments.
@Override
public void getAssignments(SortedMap<TServerInstance, TabletServerStatus> current, Map<KeyExtent, TServerInstance> unassigned, Map<KeyExtent, TServerInstance> assignments) {
if (current.size() == 0) {
return;
}
Function<KeyExtent, String> partitioner = getPartitioner();
List<ComparablePair<String, KeyExtent>> tabletsByGroup = new ArrayList<>();
for (Entry<KeyExtent, TServerInstance> entry : unassigned.entrySet()) {
TServerInstance last = entry.getValue();
if (last != null) {
// Maintain locality
String fakeSessionID = " ";
TServerInstance simple = new TServerInstance(last.getLocation(), fakeSessionID);
Iterator<TServerInstance> find = current.tailMap(simple).keySet().iterator();
if (find.hasNext()) {
TServerInstance tserver = find.next();
if (tserver.host().equals(last.host())) {
assignments.put(entry.getKey(), tserver);
continue;
}
}
}
tabletsByGroup.add(new ComparablePair<>(partitioner.apply(entry.getKey()), entry.getKey()));
}
Collections.sort(tabletsByGroup);
Iterator<TServerInstance> tserverIter = Iterators.cycle(current.keySet());
for (ComparablePair<String, KeyExtent> pair : tabletsByGroup) {
KeyExtent ke = pair.getSecond();
assignments.put(ke, tserverIter.next());
}
}
use of org.apache.accumulo.server.master.state.TServerInstance in project accumulo by apache.
the class GroupBalancer method balance.
@Override
public long balance(SortedMap<TServerInstance, TabletServerStatus> current, Set<KeyExtent> migrations, List<TabletMigration> migrationsOut) {
if (!shouldBalance(current, migrations)) {
return 5000;
}
if (System.currentTimeMillis() - lastRun < getWaitTime()) {
return 5000;
}
MapCounter<String> groupCounts = new MapCounter<>();
Map<TServerInstance, TserverGroupInfo> tservers = new HashMap<>();
for (TServerInstance tsi : current.keySet()) {
tservers.put(tsi, new TserverGroupInfo(tsi));
}
Function<KeyExtent, String> partitioner = getPartitioner();
// collect stats about current state
for (Pair<KeyExtent, Location> entry : getLocationProvider()) {
String group = partitioner.apply(entry.getFirst());
Location loc = entry.getSecond();
if (loc.equals(Location.NONE) || !tservers.containsKey(loc.getTserverInstance())) {
return 5000;
}
groupCounts.increment(group, 1);
TserverGroupInfo tgi = tservers.get(loc.getTserverInstance());
tgi.addGroup(group);
}
Map<String, Integer> expectedCounts = new HashMap<>();
int totalExtra = 0;
for (String group : groupCounts.keySet()) {
long groupCount = groupCounts.get(group);
totalExtra += groupCount % current.size();
expectedCounts.put(group, (int) (groupCount / current.size()));
}
// The number of extra tablets from all groups that each tserver must have.
int expectedExtra = totalExtra / current.size();
int maxExtraGroups = expectedExtra + 1;
expectedCounts = Collections.unmodifiableMap(expectedCounts);
tservers = Collections.unmodifiableMap(tservers);
for (TserverGroupInfo tgi : tservers.values()) {
tgi.finishedAdding(expectedCounts);
}
Moves moves = new Moves();
// The order of the following steps is important, because as ordered each step should not move any tablets moved by a previous step.
balanceExpected(tservers, moves);
if (moves.size() < getMaxMigrations()) {
balanceExtraExpected(tservers, expectedExtra, moves);
if (moves.size() < getMaxMigrations()) {
boolean cont = balanceExtraMultiple(tservers, maxExtraGroups, moves);
if (cont && moves.size() < getMaxMigrations()) {
balanceExtraExtra(tservers, maxExtraGroups, moves);
}
}
}
populateMigrations(tservers.keySet(), migrationsOut, moves);
lastRun = System.currentTimeMillis();
return 5000;
}
use of org.apache.accumulo.server.master.state.TServerInstance 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;
}
}
}
}
Aggregations