Search in sources :

Example 1 with AbstractReadExecutor

use of org.apache.cassandra.service.reads.AbstractReadExecutor in project cassandra by apache.

the class StorageProxy method fetchRows.

/**
 * This function executes local and remote reads, and blocks for the results:
 *
 * 1. Get the replica locations, sorted by response time according to the snitch
 * 2. Send a data request to the closest replica, and digest requests to either
 *    a) all the replicas, if read repair is enabled
 *    b) the closest R-1 replicas, where R is the number required to satisfy the ConsistencyLevel
 * 3. Wait for a response from R replicas
 * 4. If the digests (if any) match the data return the data
 * 5. else carry out read repair by getting data from all the nodes.
 */
private static PartitionIterator fetchRows(List<SinglePartitionReadCommand> commands, ConsistencyLevel consistencyLevel, long queryStartNanoTime) throws UnavailableException, ReadFailureException, ReadTimeoutException {
    int cmdCount = commands.size();
    AbstractReadExecutor[] reads = new AbstractReadExecutor[cmdCount];
    // for type of speculation we'll use in this read
    for (int i = 0; i < cmdCount; i++) {
        reads[i] = AbstractReadExecutor.getReadExecutor(commands.get(i), consistencyLevel, queryStartNanoTime);
        if (canDoLocalRequest(reads[i].getContactedReplicas())) {
            readMetrics.localRequests.mark();
        } else {
            readMetrics.remoteRequests.mark();
        }
    }
    // read executoe, we'll only send read requests to enough replicas to satisfy the consistency level
    for (int i = 0; i < cmdCount; i++) {
        reads[i].executeAsync();
    }
    // set of replicas we sent messages to, speculatively send an additional messages to an un-contacted replica
    for (int i = 0; i < cmdCount; i++) {
        reads[i].maybeTryAdditionalReplicas();
    }
    // repair process by sending full data reads to all replicas we received responses from.
    for (int i = 0; i < cmdCount; i++) {
        reads[i].awaitResponses();
    }
    // an additional request to any remaining replicas we haven't contacted (if there are any)
    for (int i = 0; i < cmdCount; i++) {
        reads[i].maybeSendAdditionalDataRequests();
    }
    // read repair - block on full data responses
    for (int i = 0; i < cmdCount; i++) {
        reads[i].awaitReadRepair();
    }
    // if we didn't do a read repair, return the contents of the data response, if we did do a read
    // repair, merge the full data reads
    List<PartitionIterator> results = new ArrayList<>(cmdCount);
    List<ReadRepair<?, ?>> repairs = new ArrayList<>(cmdCount);
    for (int i = 0; i < cmdCount; i++) {
        results.add(reads[i].getResult());
        repairs.add(reads[i].getReadRepair());
    }
    // if we did a read repair, assemble repair mutation and block on them
    return concatAndBlockOnRepair(results, repairs);
}
Also used : AbstractReadExecutor(org.apache.cassandra.service.reads.AbstractReadExecutor) UnfilteredPartitionIterator(org.apache.cassandra.db.partitions.UnfilteredPartitionIterator) PartitionIterator(org.apache.cassandra.db.partitions.PartitionIterator) ArrayList(java.util.ArrayList) ReadRepair(org.apache.cassandra.service.reads.repair.ReadRepair) Hint(org.apache.cassandra.hints.Hint)

Aggregations

ArrayList (java.util.ArrayList)1 PartitionIterator (org.apache.cassandra.db.partitions.PartitionIterator)1 UnfilteredPartitionIterator (org.apache.cassandra.db.partitions.UnfilteredPartitionIterator)1 Hint (org.apache.cassandra.hints.Hint)1 AbstractReadExecutor (org.apache.cassandra.service.reads.AbstractReadExecutor)1 ReadRepair (org.apache.cassandra.service.reads.repair.ReadRepair)1