use of org.apache.cassandra.repair.RepairParallelism in project cassandra by apache.
the class RepairOption method parse.
/**
* Construct RepairOptions object from given map of Strings.
* <p>
* Available options are:
*
* <table>
* <caption>Repair Options</caption>
* <thead>
* <tr>
* <th>key</th>
* <th>value</th>
* <th>default (when key not given)</th>
* </tr>
* </thead>
* <tbody>
* <tr>
* <td>parallelism</td>
* <td>"sequential", "parallel" or "dc_parallel"</td>
* <td>"sequential"</td>
* </tr>
* <tr>
* <td>primaryRange</td>
* <td>"true" if perform repair only on primary range.</td>
* <td>false</td>
* </tr>
* <tr>
* <td>incremental</td>
* <td>"true" if perform incremental repair.</td>
* <td>false</td>
* </tr>
* <tr>
* <td>trace</td>
* <td>"true" if repair is traced.</td>
* <td>false</td>
* </tr>
* <tr>
* <td>jobThreads</td>
* <td>Number of threads to use to run repair job.</td>
* <td>1</td>
* </tr>
* <tr>
* <td>ranges</td>
* <td>Ranges to repair. A range is expressed as <start token>:<end token>
* and multiple ranges can be given as comma separated ranges(e.g. aaa:bbb,ccc:ddd).</td>
* <td></td>
* </tr>
* <tr>
* <td>columnFamilies</td>
* <td>Specify names of ColumnFamilies to repair.
* Multiple ColumnFamilies can be given as comma separated values(e.g. cf1,cf2,cf3).</td>
* <td></td>
* </tr>
* <tr>
* <td>dataCenters</td>
* <td>Specify names of data centers who participate in this repair.
* Multiple data centers can be given as comma separated values(e.g. dc1,dc2,dc3).</td>
* <td></td>
* </tr>
* <tr>
* <td>hosts</td>
* <td>Specify names of hosts who participate in this repair.
* Multiple hosts can be given as comma separated values(e.g. cass1,cass2).</td>
* <td></td>
* </tr>
* <tr>
* <td>pullRepair</td>
* <td>"true" if the repair should only stream data one way from a remote host to this host.
* This is only allowed if exactly 2 hosts are specified along with a token range that they share.</td>
* <td>false</td>
* </tr>
* <tr>
* <td>forceRepair</td>
* <td>"true" if the repair should continue, even if one of the replicas involved is down.
* <td>false</td>
* </tr>
* <tr>
* <td>optimiseStreams</td>
* <td>"true" if we should try to optimise the syncing to avoid transfering identical
* ranges to the same host multiple times</td>
* <td>false</td>
* </tr>
* </tbody>
* </table>
*
* @param options options to parse
* @param partitioner partitioner is used to construct token ranges
* @return RepairOptions object
*/
public static RepairOption parse(Map<String, String> options, IPartitioner partitioner) {
// if no parallel option is given, then this will be "sequential" by default.
RepairParallelism parallelism = RepairParallelism.fromName(options.get(PARALLELISM_KEY));
boolean primaryRange = Boolean.parseBoolean(options.get(PRIMARY_RANGE_KEY));
boolean incremental = Boolean.parseBoolean(options.get(INCREMENTAL_KEY));
PreviewKind previewKind = PreviewKind.valueOf(options.getOrDefault(PREVIEW, PreviewKind.NONE.toString()));
boolean trace = Boolean.parseBoolean(options.get(TRACE_KEY));
boolean force = Boolean.parseBoolean(options.get(FORCE_REPAIR_KEY));
boolean pullRepair = Boolean.parseBoolean(options.get(PULL_REPAIR_KEY));
boolean ignoreUnreplicatedKeyspaces = Boolean.parseBoolean(options.get(IGNORE_UNREPLICATED_KS));
int jobThreads = 1;
if (options.containsKey(JOB_THREADS_KEY)) {
try {
jobThreads = Integer.parseInt(options.get(JOB_THREADS_KEY));
} catch (NumberFormatException ignore) {
}
}
// ranges
Set<Range<Token>> ranges = parseRanges(options.get(RANGES_KEY), partitioner);
boolean asymmetricSyncing = Boolean.parseBoolean(options.get(OPTIMISE_STREAMS_KEY));
RepairOption option = new RepairOption(parallelism, primaryRange, incremental, trace, jobThreads, ranges, !ranges.isEmpty(), pullRepair, force, previewKind, asymmetricSyncing, ignoreUnreplicatedKeyspaces);
// data centers
String dataCentersStr = options.get(DATACENTERS_KEY);
Collection<String> dataCenters = new HashSet<>();
if (dataCentersStr != null) {
StringTokenizer tokenizer = new StringTokenizer(dataCentersStr, ",");
while (tokenizer.hasMoreTokens()) {
dataCenters.add(tokenizer.nextToken().trim());
}
option.getDataCenters().addAll(dataCenters);
}
// hosts
String hostsStr = options.get(HOSTS_KEY);
Collection<String> hosts = new HashSet<>();
if (hostsStr != null) {
StringTokenizer tokenizer = new StringTokenizer(hostsStr, ",");
while (tokenizer.hasMoreTokens()) {
hosts.add(tokenizer.nextToken().trim());
}
option.getHosts().addAll(hosts);
}
// columnfamilies
String cfStr = options.get(COLUMNFAMILIES_KEY);
if (cfStr != null) {
Collection<String> columnFamilies = new HashSet<>();
StringTokenizer tokenizer = new StringTokenizer(cfStr, ",");
while (tokenizer.hasMoreTokens()) {
columnFamilies.add(tokenizer.nextToken().trim());
}
option.getColumnFamilies().addAll(columnFamilies);
}
// validate options
if (jobThreads > MAX_JOB_THREADS) {
throw new IllegalArgumentException("Too many job threads. Max is " + MAX_JOB_THREADS);
}
if (!dataCenters.isEmpty() && !hosts.isEmpty()) {
throw new IllegalArgumentException("Cannot combine -dc and -hosts options.");
}
if (primaryRange && ((!dataCenters.isEmpty() && !option.isInLocalDCOnly()) || !hosts.isEmpty())) {
throw new IllegalArgumentException("You need to run primary range repair on all nodes in the cluster.");
}
if (pullRepair) {
if (hosts.size() != 2) {
throw new IllegalArgumentException("Pull repair can only be performed between two hosts. Please specify two hosts, one of which must be this host.");
} else if (ranges.isEmpty()) {
throw new IllegalArgumentException("Token ranges must be specified when performing pull repair. Please specify at least one token range which both hosts have in common.");
}
}
return option;
}
use of org.apache.cassandra.repair.RepairParallelism in project cassandra by apache.
the class Repair method execute.
@Override
public void execute(NodeProbe probe) {
List<String> keyspaces = parseOptionalKeyspace(args, probe, KeyspaceSet.NON_LOCAL_STRATEGY);
String[] cfnames = parseOptionalTables(args);
if (primaryRange && (!specificDataCenters.isEmpty() || !specificHosts.isEmpty()))
throw new RuntimeException("Primary range repair should be performed on all nodes in the cluster.");
for (String keyspace : keyspaces) {
// avoid repairing system_distributed by default (CASSANDRA-9621)
if ((args == null || args.isEmpty()) && ONLY_EXPLICITLY_REPAIRED.contains(keyspace))
continue;
Map<String, String> options = new HashMap<>();
RepairParallelism parallelismDegree = RepairParallelism.PARALLEL;
if (sequential)
parallelismDegree = RepairParallelism.SEQUENTIAL;
else if (dcParallel)
parallelismDegree = RepairParallelism.DATACENTER_AWARE;
options.put(RepairOption.PARALLELISM_KEY, parallelismDegree.getName());
options.put(RepairOption.PRIMARY_RANGE_KEY, Boolean.toString(primaryRange));
options.put(RepairOption.INCREMENTAL_KEY, Boolean.toString(!fullRepair));
options.put(RepairOption.JOB_THREADS_KEY, Integer.toString(numJobThreads));
options.put(RepairOption.TRACE_KEY, Boolean.toString(trace));
options.put(RepairOption.COLUMNFAMILIES_KEY, StringUtils.join(cfnames, ","));
options.put(RepairOption.PULL_REPAIR_KEY, Boolean.toString(pullRepair));
options.put(RepairOption.FORCE_REPAIR_KEY, Boolean.toString(force));
options.put(RepairOption.PREVIEW, getPreviewKind().toString());
options.put(RepairOption.OPTIMISE_STREAMS_KEY, Boolean.toString(optimiseStreams));
options.put(RepairOption.IGNORE_UNREPLICATED_KS, Boolean.toString(ignoreUnreplicatedKeyspaces));
if (!startToken.isEmpty() || !endToken.isEmpty()) {
options.put(RepairOption.RANGES_KEY, startToken + ":" + endToken);
}
if (localDC) {
options.put(RepairOption.DATACENTERS_KEY, StringUtils.join(newArrayList(probe.getDataCenter()), ","));
} else {
options.put(RepairOption.DATACENTERS_KEY, StringUtils.join(specificDataCenters, ","));
}
options.put(RepairOption.HOSTS_KEY, StringUtils.join(specificHosts, ","));
try {
probe.repairAsync(probe.output().out, keyspace, options);
} catch (Exception e) {
throw new RuntimeException("Error occurred during repair", e);
}
}
}
Aggregations