use of org.apache.accumulo.server.master.state.TServerInstance in project accumulo by apache.
the class TabletServer method checkTabletMetadata.
static Value checkTabletMetadata(KeyExtent extent, TServerInstance instance, SortedMap<Key, Value> tabletsKeyValues, Text metadataEntry) throws AccumuloException {
TServerInstance future = null;
Value prevEndRow = null;
Value dir = null;
Value time = null;
for (Entry<Key, Value> entry : tabletsKeyValues.entrySet()) {
Key key = entry.getKey();
if (!metadataEntry.equals(key.getRow())) {
log.info("Unexpected row in tablet metadata {} {}", metadataEntry, key.getRow());
return null;
}
Text cf = key.getColumnFamily();
if (cf.equals(TabletsSection.FutureLocationColumnFamily.NAME)) {
if (future != null) {
throw new AccumuloException("Tablet has multiple future locations " + extent);
}
future = new TServerInstance(entry.getValue(), key.getColumnQualifier());
} else if (cf.equals(TabletsSection.CurrentLocationColumnFamily.NAME)) {
log.info("Tablet seems to be already assigned to {} {}", new TServerInstance(entry.getValue(), key.getColumnQualifier()));
return null;
} else if (TabletsSection.TabletColumnFamily.PREV_ROW_COLUMN.hasColumns(key)) {
prevEndRow = entry.getValue();
} else if (TabletsSection.ServerColumnFamily.DIRECTORY_COLUMN.hasColumns(key)) {
dir = entry.getValue();
} else if (TabletsSection.ServerColumnFamily.TIME_COLUMN.hasColumns(key)) {
time = entry.getValue();
}
}
if (prevEndRow == null) {
throw new AccumuloException("Metadata entry does not have prev row (" + metadataEntry + ")");
} else {
KeyExtent ke2 = new KeyExtent(metadataEntry, prevEndRow);
if (!extent.equals(ke2)) {
log.info("Tablet prev end row mismatch {} {}", extent, ke2.getPrevEndRow());
return null;
}
}
if (dir == null) {
throw new AccumuloException("Metadata entry does not have directory (" + metadataEntry + ")");
}
if (time == null && !extent.equals(RootTable.OLD_EXTENT)) {
throw new AccumuloException("Metadata entry does not have time (" + metadataEntry + ")");
}
if (future == null) {
log.info("The master has not assigned {} to ", extent, instance);
return null;
}
if (!instance.equals(future)) {
log.info("Table {} has been assigned to {} which is not {}", extent, future, instance);
return null;
}
return dir;
}
use of org.apache.accumulo.server.master.state.TServerInstance in project accumulo by apache.
the class WalStateManager method getAllState.
// utility combination of getAllMarkers and state
public Map<Path, WalState> getAllState() throws WalMarkerException {
Map<Path, WalState> result = new HashMap<>();
for (Entry<TServerInstance, List<UUID>> entry : getAllMarkers().entrySet()) {
for (UUID id : entry.getValue()) {
Pair<WalState, Path> state = state(entry.getKey(), id);
result.put(state.getSecond(), state.getFirst());
}
}
return result;
}
use of org.apache.accumulo.server.master.state.TServerInstance in project accumulo by apache.
the class WalStateManager method getAllMarkers.
// garbage collector wants the list of logs markers for all servers
public Map<TServerInstance, List<UUID>> getAllMarkers() throws WalMarkerException {
Map<TServerInstance, List<UUID>> result = new HashMap<>();
try {
String path = root();
for (String child : zoo.getChildren(path)) {
TServerInstance inst = new TServerInstance(child);
List<UUID> logs = result.get(inst);
if (logs == null) {
result.put(inst, logs = new ArrayList<>());
}
for (String idString : zoo.getChildren(path + "/" + child)) {
logs.add(UUID.fromString(idString));
}
}
} catch (KeeperException | InterruptedException e) {
throw new WalMarkerException(e);
}
return result;
}
use of org.apache.accumulo.server.master.state.TServerInstance in project accumulo by apache.
the class LiveTServerSet method checkServer.
private synchronized void checkServer(final Set<TServerInstance> updates, final Set<TServerInstance> doomed, final String path, final String zPath) throws TException, InterruptedException, KeeperException {
TServerInfo info = current.get(zPath);
final String lockPath = path + "/" + zPath;
ZcStat stat = new ZcStat();
byte[] lockData = ZooLock.getLockData(getZooCache(), lockPath, stat);
if (lockData == null) {
if (info != null) {
doomed.add(info.instance);
current.remove(zPath);
currentInstances.remove(info.instance);
}
Long firstSeen = locklessServers.get(zPath);
if (firstSeen == null) {
locklessServers.put(zPath, System.currentTimeMillis());
} else if (System.currentTimeMillis() - firstSeen > 10 * 60 * 1000) {
deleteServerNode(path + "/" + zPath);
locklessServers.remove(zPath);
}
} else {
locklessServers.remove(zPath);
ServerServices services = new ServerServices(new String(lockData, UTF_8));
HostAndPort client = services.getAddress(ServerServices.Service.TSERV_CLIENT);
TServerInstance instance = new TServerInstance(client, stat.getEphemeralOwner());
if (info == null) {
updates.add(instance);
TServerInfo tServerInfo = new TServerInfo(instance, new TServerConnection(client));
current.put(zPath, tServerInfo);
currentInstances.put(instance, tServerInfo);
} else if (!info.instance.equals(instance)) {
doomed.add(info.instance);
updates.add(instance);
TServerInfo tServerInfo = new TServerInfo(instance, new TServerConnection(client));
current.put(zPath, tServerInfo);
currentInstances.remove(info.instance);
currentInstances.put(instance, tServerInfo);
}
}
}
use of org.apache.accumulo.server.master.state.TServerInstance in project accumulo by apache.
the class ChaoticLoadBalancer method balance.
@Override
public long balance(SortedMap<TServerInstance, TabletServerStatus> current, Set<KeyExtent> migrations, List<TabletMigration> migrationsOut) {
Map<TServerInstance, Long> numTablets = new HashMap<>();
List<TServerInstance> underCapacityTServer = new ArrayList<>();
if (!migrations.isEmpty()) {
outstandingMigrations.migrations = migrations;
constraintNotMet(outstandingMigrations);
return 100;
}
resetBalancerErrors();
boolean moveMetadata = r.nextInt(4) == 0;
long totalTablets = 0;
for (Entry<TServerInstance, TabletServerStatus> e : current.entrySet()) {
long tabletCount = 0;
for (TableInfo ti : e.getValue().getTableMap().values()) {
tabletCount += ti.tablets;
}
numTablets.put(e.getKey(), tabletCount);
underCapacityTServer.add(e.getKey());
totalTablets += tabletCount;
}
// totalTablets is fuzzy due to asynchronicity of the stats
// *1.2 to handle fuzziness, and prevent locking for 'perfect' balancing scenarios
long avg = (long) Math.ceil(((double) totalTablets) / current.size() * 1.2);
for (Entry<TServerInstance, TabletServerStatus> e : current.entrySet()) {
for (String tableId : e.getValue().getTableMap().keySet()) {
Table.ID id = Table.ID.of(tableId);
if (!moveMetadata && MetadataTable.ID.equals(id))
continue;
try {
for (TabletStats ts : getOnlineTabletsForTable(e.getKey(), id)) {
KeyExtent ke = new KeyExtent(ts.extent);
int index = r.nextInt(underCapacityTServer.size());
TServerInstance dest = underCapacityTServer.get(index);
if (dest.equals(e.getKey()))
continue;
migrationsOut.add(new TabletMigration(ke, e.getKey(), dest));
if (numTablets.put(dest, numTablets.get(dest) + 1) > avg)
underCapacityTServer.remove(index);
if (numTablets.put(e.getKey(), numTablets.get(e.getKey()) - 1) <= avg && !underCapacityTServer.contains(e.getKey()))
underCapacityTServer.add(e.getKey());
// We can get some craziness with only 1 tserver, so lets make sure there's always an option!
if (underCapacityTServer.isEmpty())
underCapacityTServer.addAll(numTablets.keySet());
}
} catch (ThriftSecurityException e1) {
// Shouldn't happen, but carry on if it does
log.debug("Encountered ThriftSecurityException. This should not happen. Carrying on anyway.", e1);
} catch (TException e1) {
// Shouldn't happen, but carry on if it does
log.debug("Encountered TException. This should not happen. Carrying on anyway.", e1);
}
}
}
return 100;
}
Aggregations