Skip to content
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

catches exceptions and logs when planning compactions #4435

Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public class CompactionJobGenerator {
private final PluginEnvironment env;
private final Map<FateId,Map<String,String>> allExecutionHints;
private final Cache<Pair<TableId,CompactionServiceId>,Long> unknownCompactionServiceErrorCache;
private final Cache<String,Long> generateJobsErrorCache;

public CompactionJobGenerator(PluginEnvironment env,
Map<FateId,Map<String,String>> executionHints) {
Expand All @@ -87,42 +88,60 @@ public CompactionJobGenerator(PluginEnvironment env,
unknownCompactionServiceErrorCache =
Caches.getInstance().createNewBuilder(CacheName.COMPACTION_SERVICE_UNKNOWN, false)
.expireAfterWrite(5, TimeUnit.MINUTES).build();

generateJobsErrorCache =
Caches.getInstance().createNewBuilder(CacheName.COMPACTION_SERVICE_UNKNOWN, false)
.expireAfterWrite(5, TimeUnit.MINUTES).build();

}

public Collection<CompactionJob> generateJobs(TabletMetadata tablet, Set<CompactionKind> kinds) {
try {
Collection<CompactionJob> systemJobs = Set.of();

// ELASTICITY_TODO do not want user configured plugins to cause exceptions that prevents tablets
// from being
// assigned. So probably want to catch exceptions and log, but not too spammily OR some how
// report something
// back to the manager so it can log.

Collection<CompactionJob> systemJobs = Set.of();
if (kinds.contains(CompactionKind.SYSTEM)) {
CompactionServiceId serviceId = dispatch(CompactionKind.SYSTEM, tablet, Map.of());
systemJobs = planCompactions(serviceId, CompactionKind.SYSTEM, tablet, Map.of());
}

if (kinds.contains(CompactionKind.SYSTEM)) {
CompactionServiceId serviceId = dispatch(CompactionKind.SYSTEM, tablet, Map.of());
systemJobs = planCompactions(serviceId, CompactionKind.SYSTEM, tablet, Map.of());
}
Collection<CompactionJob> userJobs = Set.of();

Collection<CompactionJob> userJobs = Set.of();
if (kinds.contains(CompactionKind.USER) && tablet.getSelectedFiles() != null) {
var hints = allExecutionHints.get(tablet.getSelectedFiles().getFateId());
if (hints != null) {
CompactionServiceId serviceId = dispatch(CompactionKind.USER, tablet, hints);
userJobs = planCompactions(serviceId, CompactionKind.USER, tablet, hints);
}
}

if (kinds.contains(CompactionKind.USER) && tablet.getSelectedFiles() != null) {
var hints = allExecutionHints.get(tablet.getSelectedFiles().getFateId());
if (hints != null) {
CompactionServiceId serviceId = dispatch(CompactionKind.USER, tablet, hints);
userJobs = planCompactions(serviceId, CompactionKind.USER, tablet, hints);
if (userJobs.isEmpty()) {
return systemJobs;
} else if (systemJobs.isEmpty()) {
return userJobs;
} else {
var all = new ArrayList<CompactionJob>(systemJobs.size() + userJobs.size());
all.addAll(systemJobs);
all.addAll(userJobs);
return all;
}
} catch (Exception e) {
// The same code that plans compactions also assigns tablets. The intent of this catch is
// mainly to defend against user plugins called here that throw an exception from negatively
// impacting tablet assignment.
String cacheKey = tablet.getTableId() + " " + e.getClass().getName();
// This check defends against every tablet in a table having the same problem and therefore
// generating an enormous amount of spam for the logs.
if (generateJobsErrorCache.asMap().putIfAbsent(cacheKey, System.currentTimeMillis())
== null) {
log.error(
"Failed to generate compaction jobs for {}. Other tablets may be experiencing the"
+ " same error, this log message is temporarily suppressed for the entire table.",
tablet.getExtent(), e);
}
}

if (userJobs.isEmpty()) {
return systemJobs;
} else if (systemJobs.isEmpty()) {
return userJobs;
} else {
var all = new ArrayList<CompactionJob>(systemJobs.size() + userJobs.size());
all.addAll(systemJobs);
all.addAll(userJobs);
return all;
log.trace("Failed to generate compaction jobs for {}", tablet.getExtent(), e);

return Set.of();
}
}

Expand Down