use of org.apache.cassandra.service.reads.DataResolver in project cassandra by apache.
the class AbstractReadRepair method startRepair.
// digestResolver isn't used here because we resend read requests to all participants
public void startRepair(DigestResolver<E, P> digestResolver, Consumer<PartitionIterator> resultConsumer) {
getRepairMeter().mark();
/*
* When repaired data tracking is enabled, a digest will be created from data reads from repaired SSTables.
* The digests from each replica can then be compared on the coordinator to detect any divergence in their
* repaired datasets. In this context, an SSTable is considered repaired if it is marked repaired or has a
* pending repair session which has been committed. In addition to the digest, a set of ids for any pending but
* as yet uncommitted repair sessions is recorded and returned to the coordinator. This is to help reduce false
* positives caused by compaction lagging which can leave sstables from committed sessions in the pending state
* for a time.
*/
boolean trackRepairedStatus = DatabaseDescriptor.getRepairedDataTrackingForPartitionReadsEnabled();
// Do a full data read to resolve the correct response (and repair node that need be)
DataResolver<E, P> resolver = new DataResolver<>(command, replicaPlan, this, queryStartNanoTime, trackRepairedStatus);
ReadCallback<E, P> readCallback = new ReadCallback<>(resolver, command, replicaPlan, queryStartNanoTime);
digestRepair = new DigestRepair<>(resolver, readCallback, resultConsumer);
// if enabled, request additional info about repaired data from any full replicas
for (Replica replica : replicaPlan().contacts()) {
sendReadCommand(replica, readCallback, false, trackRepairedStatus);
}
ReadRepairDiagnostics.startRepair(this, replicaPlan(), digestResolver);
}
use of org.apache.cassandra.service.reads.DataResolver in project cassandra by apache.
the class RangeCommandIterator method query.
/**
* Queries the provided sub-range.
*
* @param replicaPlan the subRange to query.
* @param isFirst in the case where multiple queries are sent in parallel, whether that's the first query on
* that batch or not. The reason it matters is that whe paging queries, the command (more specifically the
* {@code DataLimits}) may have "state" information and that state may only be valid for the first query (in
* that it's the query that "continues" whatever we're previously queried).
*/
private SingleRangeResponse query(ReplicaPlan.ForRangeRead replicaPlan, boolean isFirst) {
PartitionRangeReadCommand rangeCommand = command.forSubRange(replicaPlan.range(), isFirst);
// If enabled, request repaired data tracking info from full replicas, but
// only if there are multiple full replicas to compare results from.
boolean trackRepairedStatus = DatabaseDescriptor.getRepairedDataTrackingForRangeReadsEnabled() && replicaPlan.contacts().filter(Replica::isFull).size() > 1;
ReplicaPlan.SharedForRangeRead sharedReplicaPlan = ReplicaPlan.shared(replicaPlan);
ReadRepair<EndpointsForRange, ReplicaPlan.ForRangeRead> readRepair = ReadRepair.create(command, sharedReplicaPlan, queryStartNanoTime);
DataResolver<EndpointsForRange, ReplicaPlan.ForRangeRead> resolver = new DataResolver<>(rangeCommand, sharedReplicaPlan, readRepair, queryStartNanoTime, trackRepairedStatus);
ReadCallback<EndpointsForRange, ReplicaPlan.ForRangeRead> handler = new ReadCallback<>(resolver, rangeCommand, sharedReplicaPlan, queryStartNanoTime);
if (replicaPlan.contacts().size() == 1 && replicaPlan.contacts().get(0).isSelf()) {
Stage.READ.execute(new StorageProxy.LocalReadRunnable(rangeCommand, handler, trackRepairedStatus));
} else {
for (Replica replica : replicaPlan.contacts()) {
Tracing.trace("Enqueuing request to {}", replica);
ReadCommand command = replica.isFull() ? rangeCommand : rangeCommand.copyAsTransientQuery(replica);
Message<ReadCommand> message = command.createMessage(trackRepairedStatus && replica.isFull());
MessagingService.instance().sendWithCallback(message, replica.endpoint(), handler);
}
}
return new SingleRangeResponse(resolver, handler, readRepair);
}
Aggregations