-
Notifications
You must be signed in to change notification settings - Fork 460
Increase majc priority for tablets over file size threshold #5026
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f29c322
04d1130
30644f1
dd1d80a
0cb0470
ff4b3d1
74d66b2
4c24262
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,42 +19,136 @@ | |
package org.apache.accumulo.core.util.compaction; | ||
|
||
import java.util.Comparator; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.Objects; | ||
import java.util.function.Function; | ||
|
||
import org.apache.accumulo.core.clientImpl.Namespace; | ||
import org.apache.accumulo.core.data.NamespaceId; | ||
import org.apache.accumulo.core.data.TableId; | ||
import org.apache.accumulo.core.metadata.MetadataTable; | ||
import org.apache.accumulo.core.metadata.RootTable; | ||
import org.apache.accumulo.core.spi.compaction.CompactionJob; | ||
import org.apache.accumulo.core.spi.compaction.CompactionKind; | ||
import org.apache.accumulo.core.util.Pair; | ||
import org.apache.commons.lang3.Range; | ||
|
||
import com.google.common.base.Preconditions; | ||
|
||
public class CompactionJobPrioritizer { | ||
|
||
public static final Comparator<CompactionJob> JOB_COMPARATOR = | ||
Comparator.comparingInt(CompactionJob::getPriority) | ||
.thenComparingInt(job -> job.getFiles().size()).reversed(); | ||
|
||
public static short createPriority(CompactionKind kind, int totalFiles, int compactingFiles) { | ||
|
||
int prio = totalFiles + compactingFiles; | ||
|
||
switch (kind) { | ||
case USER: | ||
case CHOP: | ||
// user-initiated compactions will have a positive priority | ||
// based on number of files | ||
if (prio > Short.MAX_VALUE) { | ||
return Short.MAX_VALUE; | ||
} | ||
return (short) prio; | ||
case SELECTOR: | ||
case SYSTEM: | ||
// system-initiated compactions will have a negative priority | ||
// starting at -32768 and increasing based on number of files | ||
// maxing out at -1 | ||
if (prio > Short.MAX_VALUE) { | ||
return -1; | ||
} else { | ||
return (short) (Short.MIN_VALUE + prio); | ||
} | ||
default: | ||
throw new AssertionError("Unknown kind " + kind); | ||
private static final Map<Pair<TableId,CompactionKind>,Range<Short>> SYSTEM_TABLE_RANGES = | ||
new HashMap<>(); | ||
private static final Map<Pair<NamespaceId,CompactionKind>, | ||
Range<Short>> ACCUMULO_NAMESPACE_RANGES = new HashMap<>(); | ||
|
||
// Create ranges of possible priority values where each range has | ||
// 2000 possible values. Priority order is: | ||
// root table user initiated | ||
// root table system initiated | ||
// metadata table user initiated | ||
// metadata table system initiated | ||
// other tables in accumulo namespace user initiated | ||
// other tables in accumulo namespace system initiated | ||
// user tables that have more files that configured system initiated | ||
// user tables user initiated | ||
// user tables system initiated | ||
static final Range<Short> ROOT_TABLE_USER = Range.of((short) 30768, (short) 32767); | ||
dlmarion marked this conversation as resolved.
Show resolved
Hide resolved
|
||
static final Range<Short> ROOT_TABLE_SYSTEM = Range.of((short) 28768, (short) 30767); | ||
|
||
static final Range<Short> METADATA_TABLE_USER = Range.of((short) 26768, (short) 28767); | ||
static final Range<Short> METADATA_TABLE_SYSTEM = Range.of((short) 24768, (short) 26767); | ||
|
||
static final Range<Short> SYSTEM_NS_USER = Range.of((short) 22768, (short) 24767); | ||
static final Range<Short> SYSTEM_NS_SYSTEM = Range.of((short) 20768, (short) 22767); | ||
|
||
static final Range<Short> TABLE_OVER_SIZE = Range.of((short) 18768, (short) 20767); | ||
|
||
static final Range<Short> USER_TABLE_USER = Range.of((short) 1, (short) 18767); | ||
static final Range<Short> USER_TABLE_SYSTEM = Range.of((short) -32768, (short) 0); | ||
|
||
static { | ||
// root table | ||
SYSTEM_TABLE_RANGES.put(new Pair<>(RootTable.ID, CompactionKind.USER), ROOT_TABLE_USER); | ||
SYSTEM_TABLE_RANGES.put(new Pair<>(RootTable.ID, CompactionKind.SYSTEM), ROOT_TABLE_SYSTEM); | ||
|
||
// metadata table | ||
SYSTEM_TABLE_RANGES.put(new Pair<>(MetadataTable.ID, CompactionKind.USER), METADATA_TABLE_USER); | ||
SYSTEM_TABLE_RANGES.put(new Pair<>(MetadataTable.ID, CompactionKind.SYSTEM), | ||
METADATA_TABLE_SYSTEM); | ||
|
||
// metadata table | ||
ACCUMULO_NAMESPACE_RANGES.put(new Pair<>(Namespace.ACCUMULO.id(), CompactionKind.USER), | ||
SYSTEM_NS_USER); | ||
ACCUMULO_NAMESPACE_RANGES.put(new Pair<>(Namespace.ACCUMULO.id(), CompactionKind.SYSTEM), | ||
SYSTEM_NS_SYSTEM); | ||
} | ||
|
||
public static short createPriority(final NamespaceId nsId, final TableId tableId, | ||
final CompactionKind kind, final int totalFiles, final int compactingFiles, | ||
final int maxFilesPerTablet) { | ||
|
||
Objects.requireNonNull(nsId, "nsId cannot be null"); | ||
Objects.requireNonNull(tableId, "tableId cannot be null"); | ||
Preconditions.checkArgument(totalFiles >= 0, "totalFiles is negative %s", totalFiles); | ||
Preconditions.checkArgument(compactingFiles >= 0, "compactingFiles is negative %s", | ||
compactingFiles); | ||
|
||
final Function<Range<Short>,Short> normalPriorityFunction = new Function<>() { | ||
@Override | ||
public Short apply(Range<Short> f) { | ||
return (short) Math.min(f.getMaximum(), f.getMinimum() + totalFiles + compactingFiles); | ||
} | ||
}; | ||
|
||
final Function<Range<Short>,Short> tabletOverSizeFunction = new Function<>() { | ||
@Override | ||
public Short apply(Range<Short> f) { | ||
return (short) Math.min(f.getMaximum(), | ||
f.getMinimum() + compactingFiles + (totalFiles - maxFilesPerTablet)); | ||
} | ||
}; | ||
|
||
// Handle the case of a CHOP compaction. For the purposes of determining | ||
// a priority, treat them as a USER compaction. | ||
CompactionKind calculationKind = kind; | ||
if (kind == CompactionKind.CHOP) { | ||
dlmarion marked this conversation as resolved.
Show resolved
Hide resolved
|
||
calculationKind = CompactionKind.USER; | ||
} else if (kind == CompactionKind.SELECTOR) { | ||
calculationKind = CompactionKind.SYSTEM; | ||
} | ||
|
||
Range<Short> range = null; | ||
Function<Range<Short>,Short> func = normalPriorityFunction; | ||
if (Namespace.ACCUMULO.id() == nsId) { | ||
// Handle system tables | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There could be chop compactions when merging the metadata table and these may end w/ a null range causing an exception. Need to add handling for kind of chop. Will have to drop this in the 3.1 code. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In 74d66b2 I added code to treat CHOP as USER compaction kind. |
||
range = SYSTEM_TABLE_RANGES.get(new Pair<>(tableId, calculationKind)); | ||
if (range == null) { | ||
range = ACCUMULO_NAMESPACE_RANGES.get(new Pair<>(nsId, calculationKind)); | ||
} | ||
} else { | ||
// Handle user tables | ||
if (totalFiles > maxFilesPerTablet && calculationKind == CompactionKind.SYSTEM) { | ||
range = TABLE_OVER_SIZE; | ||
func = tabletOverSizeFunction; | ||
} else if (calculationKind == CompactionKind.SYSTEM) { | ||
range = USER_TABLE_SYSTEM; | ||
} else { | ||
range = USER_TABLE_USER; | ||
} | ||
} | ||
|
||
if (range == null) { | ||
throw new IllegalStateException( | ||
"Error calculating compaction priority for table: " + tableId); | ||
} | ||
return func.apply(range); | ||
|
||
} | ||
|
||
} |
Uh oh!
There was an error while loading. Please reload this page.