use of org.apache.accumulo.core.dataImpl.KeyExtent in project accumulo by apache.
the class TabletStateChangeIterator method setMerges.
public static void setMerges(IteratorSetting cfg, Collection<MergeInfo> merges) {
DataOutputBuffer buffer = new DataOutputBuffer();
try {
for (MergeInfo info : merges) {
KeyExtent extent = info.getExtent();
if (extent != null && !info.getState().equals(MergeState.NONE)) {
info.write(buffer);
}
}
} catch (Exception ex) {
throw new RuntimeException(ex);
}
String encoded = Base64.getEncoder().encodeToString(Arrays.copyOf(buffer.getData(), buffer.getLength()));
cfg.addOption(MERGES_OPTION, encoded);
}
use of org.apache.accumulo.core.dataImpl.KeyExtent in project accumulo by apache.
the class DefaultLoadBalancer method move.
/**
* Select a tablet based on differences between table loads; if the loads are even, use the
* busiest table
*/
List<TabletMigration> move(ServerCounts tooMuch, ServerCounts tooLittle, int count, Map<TableId, Map<KeyExtent, TabletStats>> donerTabletStats) {
if (count == 0) {
return Collections.emptyList();
}
List<TabletMigration> result = new ArrayList<>();
// Copy counts so we can update them as we propose migrations
Map<TableId, Integer> tooMuchMap = tabletCountsPerTable(tooMuch.status);
Map<TableId, Integer> tooLittleMap = tabletCountsPerTable(tooLittle.status);
for (int i = 0; i < count; i++) {
TableId table;
Integer tooLittleCount;
if (tableToBalance == null) {
// find a table to migrate
// look for an uneven table count
int biggestDifference = 0;
TableId biggestDifferenceTable = null;
for (var tableEntry : tooMuchMap.entrySet()) {
TableId tableID = tableEntry.getKey();
tooLittleMap.putIfAbsent(tableID, 0);
int diff = tableEntry.getValue() - tooLittleMap.get(tableID);
if (diff > biggestDifference) {
biggestDifference = diff;
biggestDifferenceTable = tableID;
}
}
if (biggestDifference < 2) {
table = busiest(tooMuch.status.tableMap);
} else {
table = biggestDifferenceTable;
}
} else {
// just balance the given table
table = tableToBalance;
}
Map<KeyExtent, TabletStats> onlineTabletsForTable = donerTabletStats.get(table);
try {
if (onlineTabletsForTable == null) {
onlineTabletsForTable = new HashMap<>();
List<TabletStats> stats = getOnlineTabletsForTable(tooMuch.server, table);
if (stats == null) {
log.warn("Unable to find tablets to move");
return result;
}
for (TabletStats stat : stats) onlineTabletsForTable.put(KeyExtent.fromThrift(stat.extent), stat);
donerTabletStats.put(table, onlineTabletsForTable);
}
} catch (Exception ex) {
log.error("Unable to select a tablet to move", ex);
return result;
}
KeyExtent extent = selectTablet(onlineTabletsForTable);
onlineTabletsForTable.remove(extent);
if (extent == null)
return result;
tooMuchMap.put(table, tooMuchMap.get(table) - 1);
/**
* If a table grows from 1 tablet then tooLittleMap.get(table) can return a null, since there
* is only one tabletserver that holds all of the tablets. Here we check to see if in fact
* that is the case and if so set the value to 0.
*/
tooLittleCount = tooLittleMap.get(table);
if (tooLittleCount == null) {
tooLittleCount = 0;
}
tooLittleMap.put(table, tooLittleCount + 1);
tooMuch.count--;
tooLittle.count++;
result.add(new TabletMigration(extent, tooMuch.server, tooLittle.server));
}
return result;
}
use of org.apache.accumulo.core.dataImpl.KeyExtent in project accumulo by apache.
the class DefaultLoadBalancer method selectTablet.
static KeyExtent selectTablet(Map<KeyExtent, TabletStats> extents) {
if (extents.isEmpty())
return null;
KeyExtent mostRecentlySplit = null;
long splitTime = 0;
for (Entry<KeyExtent, TabletStats> entry : extents.entrySet()) if (entry.getValue().splitCreationTime >= splitTime) {
splitTime = entry.getValue().splitCreationTime;
mostRecentlySplit = entry.getKey();
}
return mostRecentlySplit;
}
use of org.apache.accumulo.core.dataImpl.KeyExtent in project accumulo by apache.
the class TabletGroupWatcher method getHighTablet.
private KeyExtent getHighTablet(KeyExtent range) throws AccumuloException {
try {
AccumuloClient client = manager.getContext();
Scanner scanner = client.createScanner(range.isMeta() ? RootTable.NAME : MetadataTable.NAME, Authorizations.EMPTY);
TabletColumnFamily.PREV_ROW_COLUMN.fetch(scanner);
KeyExtent start = new KeyExtent(range.tableId(), range.endRow(), null);
scanner.setRange(new Range(start.toMetaRow(), null));
Iterator<Entry<Key, Value>> iterator = scanner.iterator();
if (!iterator.hasNext()) {
throw new AccumuloException("No last tablet for a merge " + range);
}
Entry<Key, Value> entry = iterator.next();
KeyExtent highTablet = KeyExtent.fromMetaPrevRow(entry);
if (!highTablet.tableId().equals(range.tableId())) {
throw new AccumuloException("No last tablet for merge " + range + " " + highTablet);
}
return highTablet;
} catch (Exception ex) {
throw new AccumuloException("Unexpected failure finding the last tablet for a merge " + range, ex);
}
}
use of org.apache.accumulo.core.dataImpl.KeyExtent in project accumulo by apache.
the class TabletGroupWatcher method sendSplitRequest.
private void sendSplitRequest(MergeInfo info, TabletState state, TabletLocationState tls) {
// Already split?
if (!info.getState().equals(MergeState.SPLITTING))
return;
// Merges don't split
if (!info.isDelete())
return;
// Online and ready to split?
if (!state.equals(TabletState.HOSTED))
return;
// Does this extent cover the end points of the delete?
KeyExtent range = info.getExtent();
if (tls.extent.overlaps(range)) {
for (Text splitPoint : new Text[] { range.prevEndRow(), range.endRow() }) {
if (splitPoint == null)
continue;
if (!tls.extent.contains(splitPoint))
continue;
if (splitPoint.equals(tls.extent.endRow()))
continue;
if (splitPoint.equals(tls.extent.prevEndRow()))
continue;
try {
TServerConnection conn;
conn = manager.tserverSet.getConnection(tls.current);
if (conn != null) {
Manager.log.info("Asking {} to split {} at {}", tls.current, tls.extent, splitPoint);
conn.splitTablet(tls.extent, splitPoint);
} else {
Manager.log.warn("Not connected to server {}", tls.current);
}
} catch (NotServingTabletException e) {
Manager.log.debug("Error asking tablet server to split a tablet: ", e);
} catch (Exception e) {
Manager.log.warn("Error asking tablet server to split a tablet: ", e);
}
}
}
}
Aggregations