Search in sources :

Example 1 with RepairParallelism

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 &lt;start token&gt;:&lt;end token&gt;
 *             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;
}
Also used : Range(org.apache.cassandra.dht.Range) RepairParallelism(org.apache.cassandra.repair.RepairParallelism) PreviewKind(org.apache.cassandra.streaming.PreviewKind)

Example 2 with RepairParallelism

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);
        }
    }
}
Also used : RepairParallelism(org.apache.cassandra.repair.RepairParallelism) HashMap(java.util.HashMap)

Aggregations

RepairParallelism (org.apache.cassandra.repair.RepairParallelism)2 HashMap (java.util.HashMap)1 Range (org.apache.cassandra.dht.Range)1 PreviewKind (org.apache.cassandra.streaming.PreviewKind)1