use of org.apache.accumulo.core.conf.AccumuloConfiguration in project accumulo by apache.
the class Tablet method _majorCompact.
private CompactionStats _majorCompact(MajorCompactionReason reason) throws IOException, CompactionCanceledException {
long t1, t2, t3;
Pair<Long, UserCompactionConfig> compactionId = null;
CompactionStrategy strategy = null;
Map<FileRef, Pair<Key, Key>> firstAndLastKeys = null;
if (reason == MajorCompactionReason.USER) {
try {
compactionId = getCompactionID();
strategy = createCompactionStrategy(compactionId.getSecond().getCompactionStrategy());
} catch (NoNodeException e) {
throw new RuntimeException(e);
}
} else if (reason == MajorCompactionReason.NORMAL || reason == MajorCompactionReason.IDLE) {
strategy = Property.createTableInstanceFromPropertyName(tableConfiguration, Property.TABLE_COMPACTION_STRATEGY, CompactionStrategy.class, new DefaultCompactionStrategy());
strategy.init(Property.getCompactionStrategyOptions(tableConfiguration));
} else if (reason == MajorCompactionReason.CHOP) {
firstAndLastKeys = getFirstAndLastKeys(getDatafileManager().getDatafileSizes());
} else {
throw new IllegalArgumentException("Unknown compaction reason " + reason);
}
if (strategy != null) {
BlockCache sc = tabletResources.getTabletServerResourceManager().getSummaryCache();
BlockCache ic = tabletResources.getTabletServerResourceManager().getIndexCache();
MajorCompactionRequest request = new MajorCompactionRequest(extent, reason, getTabletServer().getFileSystem(), tableConfiguration, sc, ic);
request.setFiles(getDatafileManager().getDatafileSizes());
strategy.gatherInformation(request);
}
Map<FileRef, DataFileValue> filesToCompact = null;
int maxFilesToCompact = tableConfiguration.getCount(Property.TSERV_MAJC_THREAD_MAXOPEN);
CompactionStats majCStats = new CompactionStats();
CompactionPlan plan = null;
boolean propogateDeletes = false;
boolean updateCompactionID = false;
synchronized (this) {
// plan all that work that needs to be done in the sync block... then do the actual work
// outside the sync block
t1 = System.currentTimeMillis();
majorCompactionState = CompactionState.WAITING_TO_START;
getTabletMemory().waitForMinC();
t2 = System.currentTimeMillis();
majorCompactionState = CompactionState.IN_PROGRESS;
notifyAll();
VolumeManager fs = getTabletServer().getFileSystem();
if (extent.isRootTablet()) {
// very important that we call this before doing major compaction,
// otherwise deleted compacted files could possible be brought back
// at some point if the file they were compacted to was legitimately
// removed by a major compaction
RootFiles.cleanupReplacement(fs, fs.listStatus(this.location), false);
}
SortedMap<FileRef, DataFileValue> allFiles = getDatafileManager().getDatafileSizes();
List<FileRef> inputFiles = new ArrayList<>();
if (reason == MajorCompactionReason.CHOP) {
// enforce rules: files with keys outside our range need to be compacted
inputFiles.addAll(findChopFiles(extent, firstAndLastKeys, allFiles.keySet()));
} else {
MajorCompactionRequest request = new MajorCompactionRequest(extent, reason, tableConfiguration);
request.setFiles(allFiles);
plan = strategy.getCompactionPlan(request);
if (plan != null) {
plan.validate(allFiles.keySet());
inputFiles.addAll(plan.inputFiles);
}
}
if (inputFiles.isEmpty()) {
if (reason == MajorCompactionReason.USER) {
if (compactionId.getSecond().getIterators().isEmpty()) {
log.debug("No-op major compaction by USER on 0 input files because no iterators present.");
lastCompactID = compactionId.getFirst();
updateCompactionID = true;
} else {
log.debug("Major compaction by USER on 0 input files with iterators.");
filesToCompact = new HashMap<>();
}
} else {
return majCStats;
}
} else {
// If no original files will exist at the end of the compaction, we do not have to propogate deletes
Set<FileRef> droppedFiles = new HashSet<>();
droppedFiles.addAll(inputFiles);
if (plan != null)
droppedFiles.addAll(plan.deleteFiles);
propogateDeletes = !(droppedFiles.equals(allFiles.keySet()));
log.debug("Major compaction plan: {} propogate deletes : {}", plan, propogateDeletes);
filesToCompact = new HashMap<>(allFiles);
filesToCompact.keySet().retainAll(inputFiles);
getDatafileManager().reserveMajorCompactingFiles(filesToCompact.keySet());
}
t3 = System.currentTimeMillis();
}
try {
log.debug(String.format("MajC initiate lock %.2f secs, wait %.2f secs", (t3 - t2) / 1000.0, (t2 - t1) / 1000.0));
if (updateCompactionID) {
MetadataTableUtil.updateTabletCompactID(extent, compactionId.getFirst(), tabletServer, getTabletServer().getLock());
return majCStats;
}
if (!propogateDeletes && compactionId == null) {
// compacting everything, so update the compaction id in metadata
try {
compactionId = getCompactionID();
if (compactionId.getSecond().getCompactionStrategy() != null) {
compactionId = null;
// TODO maybe return unless chop?
}
} catch (NoNodeException e) {
throw new RuntimeException(e);
}
}
List<IteratorSetting> compactionIterators = new ArrayList<>();
if (compactionId != null) {
if (reason == MajorCompactionReason.USER) {
if (getCompactionCancelID() >= compactionId.getFirst()) {
// compaction was canceled
return majCStats;
}
compactionIterators = compactionId.getSecond().getIterators();
synchronized (this) {
if (lastCompactID >= compactionId.getFirst())
// already compacted
return majCStats;
}
}
}
// ACCUMULO-3645 run loop at least once, even if filesToCompact.isEmpty()
do {
int numToCompact = maxFilesToCompact;
if (filesToCompact.size() > maxFilesToCompact && filesToCompact.size() < 2 * maxFilesToCompact) {
// on the second to last compaction pass, compact the minimum amount of files possible
numToCompact = filesToCompact.size() - maxFilesToCompact + 1;
}
Set<FileRef> smallestFiles = removeSmallest(filesToCompact, numToCompact);
FileRef fileName = getNextMapFilename((filesToCompact.size() == 0 && !propogateDeletes) ? "A" : "C");
FileRef compactTmpName = new FileRef(fileName.path().toString() + "_tmp");
AccumuloConfiguration tableConf = createTableConfiguration(tableConfiguration, plan);
Span span = Trace.start("compactFiles");
try {
CompactionEnv cenv = new CompactionEnv() {
@Override
public boolean isCompactionEnabled() {
return Tablet.this.isCompactionEnabled();
}
@Override
public IteratorScope getIteratorScope() {
return IteratorScope.majc;
}
@Override
public RateLimiter getReadLimiter() {
return getTabletServer().getMajorCompactionReadLimiter();
}
@Override
public RateLimiter getWriteLimiter() {
return getTabletServer().getMajorCompactionWriteLimiter();
}
};
HashMap<FileRef, DataFileValue> copy = new HashMap<>(getDatafileManager().getDatafileSizes());
if (!copy.keySet().containsAll(smallestFiles))
throw new IllegalStateException("Cannot find data file values for " + smallestFiles);
copy.keySet().retainAll(smallestFiles);
log.debug("Starting MajC {} ({}) {} --> {} {}", extent, reason, copy.keySet(), compactTmpName, compactionIterators);
// always propagate deletes, unless last batch
boolean lastBatch = filesToCompact.isEmpty();
Compactor compactor = new Compactor(tabletServer, this, copy, null, compactTmpName, lastBatch ? propogateDeletes : true, cenv, compactionIterators, reason.ordinal(), tableConf);
CompactionStats mcs = compactor.call();
span.data("files", "" + smallestFiles.size());
span.data("read", "" + mcs.getEntriesRead());
span.data("written", "" + mcs.getEntriesWritten());
majCStats.add(mcs);
if (lastBatch && plan != null && plan.deleteFiles != null) {
smallestFiles.addAll(plan.deleteFiles);
}
getDatafileManager().bringMajorCompactionOnline(smallestFiles, compactTmpName, fileName, filesToCompact.size() == 0 && compactionId != null ? compactionId.getFirst() : null, new DataFileValue(mcs.getFileSize(), mcs.getEntriesWritten()));
// to add the deleted file
if (filesToCompact.size() > 0 && mcs.getEntriesWritten() > 0) {
filesToCompact.put(fileName, new DataFileValue(mcs.getFileSize(), mcs.getEntriesWritten()));
}
} finally {
span.stop();
}
} while (filesToCompact.size() > 0);
return majCStats;
} finally {
synchronized (Tablet.this) {
getDatafileManager().clearMajorCompactingFile();
}
}
}
use of org.apache.accumulo.core.conf.AccumuloConfiguration in project accumulo by apache.
the class LargestFirstMemoryManagerTest method testDeletedTable.
@Test
public void testDeletedTable() throws Exception {
final String deletedTableId = "1";
Function<Table.ID, Boolean> existenceCheck = tableId -> !deletedTableId.contentEquals(tableId.canonicalID());
LargestFirstMemoryManagerWithExistenceCheck mgr = new LargestFirstMemoryManagerWithExistenceCheck(existenceCheck);
ServerConfiguration config = new ServerConfiguration() {
ServerConfigurationFactory delegate = new ServerConfigurationFactory(inst);
@Override
public AccumuloConfiguration getSystemConfiguration() {
return DefaultConfiguration.getInstance();
}
@Override
public TableConfiguration getTableConfiguration(Table.ID tableId) {
return delegate.getTableConfiguration(tableId);
}
@Override
public NamespaceConfiguration getNamespaceConfiguration(Namespace.ID namespaceId) {
return delegate.getNamespaceConfiguration(namespaceId);
}
};
mgr.init(config);
MemoryManagementActions result;
// one tablet is really big and the other is for a nonexistent table
KeyExtent extent = new KeyExtent(Table.ID.of("2"), new Text("j"), null);
result = mgr.getMemoryManagementActions(tablets(t(extent, ZERO, ONE_GIG, 0), t(k("j"), ZERO, ONE_GIG, 0)));
assertEquals(1, result.tabletsToMinorCompact.size());
assertEquals(extent, result.tabletsToMinorCompact.get(0));
}
use of org.apache.accumulo.core.conf.AccumuloConfiguration in project accumulo by apache.
the class ShellServerIT method importDirectory.
@Test
public void importDirectory() throws Exception {
final String table = name.getMethodName();
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(conf);
File importDir = new File(rootPath, "import");
assertTrue(importDir.mkdir());
String even = new File(importDir, "even.rf").toString();
String odd = new File(importDir, "odd.rf").toString();
File errorsDir = new File(rootPath, "errors");
assertTrue(errorsDir.mkdir());
fs.mkdirs(new Path(errorsDir.toString()));
AccumuloConfiguration aconf = DefaultConfiguration.getInstance();
FileSKVWriter evenWriter = FileOperations.getInstance().newWriterBuilder().forFile(even, fs, conf).withTableConfiguration(aconf).build();
evenWriter.startDefaultLocalityGroup();
FileSKVWriter oddWriter = FileOperations.getInstance().newWriterBuilder().forFile(odd, fs, conf).withTableConfiguration(aconf).build();
oddWriter.startDefaultLocalityGroup();
long timestamp = System.currentTimeMillis();
Text cf = new Text("cf");
Text cq = new Text("cq");
Value value = new Value("value".getBytes());
for (int i = 0; i < 100; i += 2) {
Key key = new Key(new Text(String.format("%8d", i)), cf, cq, timestamp);
evenWriter.append(key, value);
key = new Key(new Text(String.format("%8d", i + 1)), cf, cq, timestamp);
oddWriter.append(key, value);
}
evenWriter.close();
oddWriter.close();
assertEquals(0, ts.shell.getExitCode());
ts.exec("createtable " + table, true);
ts.exec("importdirectory " + importDir + " " + errorsDir + " true", true);
ts.exec("scan -r 00000000", true, "00000000", true);
ts.exec("scan -r 00000099", true, "00000099", true);
ts.exec("deletetable -f " + table);
}
use of org.apache.accumulo.core.conf.AccumuloConfiguration in project accumulo by apache.
the class BulkFileIT method testBulkFile.
@Test
public void testBulkFile() throws Exception {
Connector c = getConnector();
String tableName = getUniqueNames(1)[0];
c.tableOperations().create(tableName);
SortedSet<Text> splits = new TreeSet<>();
for (String split : "0333 0666 0999 1333 1666".split(" ")) splits.add(new Text(split));
c.tableOperations().addSplits(tableName, splits);
Configuration conf = new Configuration();
AccumuloConfiguration aconf = new ServerConfigurationFactory(c.getInstance()).getSystemConfiguration();
FileSystem fs = getCluster().getFileSystem();
String rootPath = cluster.getTemporaryPath().toString();
String dir = rootPath + "/bulk_test_diff_files_89723987592_" + getUniqueNames(1)[0];
fs.delete(new Path(dir), true);
FileSKVWriter writer1 = FileOperations.getInstance().newWriterBuilder().forFile(dir + "/f1." + RFile.EXTENSION, fs, conf).withTableConfiguration(aconf).build();
writer1.startDefaultLocalityGroup();
writeData(writer1, 0, 333);
writer1.close();
FileSKVWriter writer2 = FileOperations.getInstance().newWriterBuilder().forFile(dir + "/f2." + RFile.EXTENSION, fs, conf).withTableConfiguration(aconf).build();
writer2.startDefaultLocalityGroup();
writeData(writer2, 334, 999);
writer2.close();
FileSKVWriter writer3 = FileOperations.getInstance().newWriterBuilder().forFile(dir + "/f3." + RFile.EXTENSION, fs, conf).withTableConfiguration(aconf).build();
writer3.startDefaultLocalityGroup();
writeData(writer3, 1000, 1999);
writer3.close();
FunctionalTestUtils.bulkImport(c, fs, tableName, dir);
FunctionalTestUtils.checkRFiles(c, tableName, 6, 6, 1, 1);
verifyData(tableName, 0, 1999);
}
use of org.apache.accumulo.core.conf.AccumuloConfiguration in project accumulo by apache.
the class IteratorUtilTest method onlyReadsRelevantIteratorScopeConfigurations.
@Test
public void onlyReadsRelevantIteratorScopeConfigurations() throws Exception {
Map<String, String> data = new HashMap<>();
// Make some configuration items, one with a bogus scope
data.put(Property.TABLE_ITERATOR_SCAN_PREFIX + "foo", "50," + SummingCombiner.class.getName());
data.put(Property.TABLE_ITERATOR_SCAN_PREFIX + "foo.opt." + SummingCombiner.ALL_OPTION, "true");
data.put(Property.TABLE_ITERATOR_PREFIX + ".fakescope.bar", "50," + SummingCombiner.class.getName());
data.put(Property.TABLE_ITERATOR_SCAN_PREFIX + "foo.opt.fakeopt", "fakevalue");
AccumuloConfiguration conf = new ConfigurationCopy(data);
List<IterInfo> iterators = new ArrayList<>();
Map<String, Map<String, String>> options = new HashMap<>();
IteratorUtil.parseIterConf(IteratorScope.scan, iterators, options, conf);
Assert.assertEquals(1, iterators.size());
IterInfo ii = iterators.get(0);
Assert.assertEquals(new IterInfo(50, SummingCombiner.class.getName(), "foo"), ii);
}
Aggregations