use of org.apache.accumulo.core.metadata.TServerInstance in project accumulo by apache.
the class TabletMetadata method checkServer.
/**
* Check for tserver ZooLock at the ZK location. Return Optional containing TServerInstance if a
* valid Zoolock exists.
*/
private static Optional<TServerInstance> checkServer(ClientContext context, String path, String zPath) {
Optional<TServerInstance> server = Optional.empty();
final var lockPath = ServiceLock.path(path + "/" + zPath);
ZooCache.ZcStat stat = new ZooCache.ZcStat();
byte[] lockData = ServiceLock.getLockData(context.getZooCache(), lockPath, stat);
log.trace("Checking server at ZK path = " + lockPath);
if (lockData != null) {
ServerServices services = new ServerServices(new String(lockData, UTF_8));
HostAndPort client = services.getAddress(ServerServices.Service.TSERV_CLIENT);
server = Optional.of(new TServerInstance(client, stat.getEphemeralOwner()));
}
return server;
}
use of org.apache.accumulo.core.metadata.TServerInstance in project accumulo by apache.
the class TabletMetadata method getTabletState.
public TabletState getTabletState(Set<TServerInstance> liveTServers) {
ensureFetched(ColumnType.LOCATION);
ensureFetched(ColumnType.LAST);
ensureFetched(ColumnType.SUSPEND);
try {
TServerInstance current = null;
TServerInstance future = null;
if (hasCurrent()) {
current = location;
} else {
future = location;
}
// only care about the state so don't need walogs and chopped params
var tls = new TabletLocationState(extent, future, current, last, suspend, null, false);
return tls.getState(liveTServers);
} catch (TabletLocationState.BadLocationStateException blse) {
throw new IllegalArgumentException("Error creating TabletLocationState", blse);
}
}
use of org.apache.accumulo.core.metadata.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 (var tablet : getLocationProvider().entrySet()) {
String group = partitioner.apply(tablet.getKey());
var loc = tablet.getValue();
if (loc == null || !current.contains(loc)) {
migrationsOut.clear();
return;
}
TServerInstance dest = moves.removeMove(loc, group);
if (dest != null) {
migrationsOut.add(new TabletMigration(tablet.getKey(), loc, dest));
if (moves.size() == 0) {
break;
}
}
}
}
use of org.apache.accumulo.core.metadata.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.isEmpty()) {
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.getHostAndPort(), fakeSessionID);
Iterator<TServerInstance> find = current.tailMap(simple).keySet().iterator();
if (find.hasNext()) {
TServerInstance tserver = find.next();
if (tserver.getHost().equals(last.getHost())) {
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.core.metadata.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 (var tablet : getLocationProvider().entrySet()) {
String group = partitioner.apply(tablet.getKey());
var loc = tablet.getValue();
if (loc == null || !tservers.containsKey(loc)) {
return 5000;
}
groupCounts.increment(group, 1);
TserverGroupInfo tgi = tservers.get(loc);
tgi.addGroup(group);
}
Map<String, Integer> expectedCounts = new HashMap<>();
int totalExtra = 0;
for (String group : groupCounts.keySet()) {
int groupCount = groupCounts.getInt(group);
totalExtra += groupCount % current.size();
expectedCounts.put(group, (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;
}
Aggregations