Search in sources :

Example 1 with RangesAtEndpoint

use of org.apache.cassandra.locator.RangesAtEndpoint in project cassandra by apache.

the class StreamSession method addTransferRanges.

/**
 * Set up transfer for specific keyspace/ranges/CFs
 *
 * @param keyspace Transfer keyspace
 * @param replicas Transfer ranges
 * @param columnFamilies Transfer ColumnFamilies
 * @param flushTables flush tables?
 */
synchronized void addTransferRanges(String keyspace, RangesAtEndpoint replicas, Collection<String> columnFamilies, boolean flushTables) {
    failIfFinished();
    Collection<ColumnFamilyStore> stores = getColumnFamilyStores(keyspace, columnFamilies);
    if (flushTables)
        flushSSTables(stores);
    // Was it safe to remove this normalize, sorting seems not to matter, merging? Maybe we should have?
    // Do we need to unwrap here also or is that just making it worse?
    // Range and if it's transient
    RangesAtEndpoint unwrappedRanges = replicas.unwrap();
    List<OutgoingStream> streams = getOutgoingStreamsForRanges(unwrappedRanges, stores, pendingRepair, previewKind);
    addTransferStreams(streams);
    Set<Range<Token>> toBeUpdated = transferredRangesPerKeyspace.get(keyspace);
    if (toBeUpdated == null) {
        toBeUpdated = new HashSet<>();
    }
    toBeUpdated.addAll(replicas.ranges());
    transferredRangesPerKeyspace.put(keyspace, toBeUpdated);
}
Also used : RangesAtEndpoint(org.apache.cassandra.locator.RangesAtEndpoint) ColumnFamilyStore(org.apache.cassandra.db.ColumnFamilyStore) Range(org.apache.cassandra.dht.Range)

Example 2 with RangesAtEndpoint

use of org.apache.cassandra.locator.RangesAtEndpoint in project cassandra by apache.

the class CancelCompactionsTest method testAnticompaction.

@Test
public void testAnticompaction() throws InterruptedException, ExecutionException {
    ColumnFamilyStore cfs = MockSchema.newCFS();
    List<SSTableReader> sstables = createSSTables(cfs, 10, 0);
    List<SSTableReader> alreadyRepairedSSTables = createSSTables(cfs, 10, 10);
    for (SSTableReader sstable : alreadyRepairedSSTables) AbstractPendingRepairTest.mutateRepaired(sstable, System.currentTimeMillis());
    assertEquals(20, cfs.getLiveSSTables().size());
    List<TestCompactionTask> tcts = new ArrayList<>();
    tcts.add(new TestCompactionTask(cfs, new HashSet<>(sstables.subList(0, 2))));
    tcts.add(new TestCompactionTask(cfs, new HashSet<>(sstables.subList(3, 4))));
    tcts.add(new TestCompactionTask(cfs, new HashSet<>(sstables.subList(5, 7))));
    tcts.add(new TestCompactionTask(cfs, new HashSet<>(sstables.subList(8, 9))));
    List<TestCompactionTask> nonAffectedTcts = new ArrayList<>();
    nonAffectedTcts.add(new TestCompactionTask(cfs, new HashSet<>(alreadyRepairedSSTables)));
    try {
        tcts.forEach(TestCompactionTask::start);
        nonAffectedTcts.forEach(TestCompactionTask::start);
        List<CompactionInfo.Holder> activeCompactions = getActiveCompactionsForTable(cfs);
        assertEquals(5, activeCompactions.size());
        // make sure that sstables are fully contained so that the metadata gets mutated
        Range<Token> range = new Range<>(token(-1), token(49));
        UUID prsid = UUID.randomUUID();
        ActiveRepairService.instance.registerParentRepairSession(prsid, InetAddressAndPort.getLocalHost(), Collections.singletonList(cfs), Collections.singleton(range), true, 1, true, PreviewKind.NONE);
        InetAddressAndPort local = FBUtilities.getBroadcastAddressAndPort();
        RangesAtEndpoint rae = RangesAtEndpoint.builder(local).add(new Replica(local, range, true)).build();
        PendingAntiCompaction pac = new PendingAntiCompaction(prsid, Collections.singleton(cfs), rae, Executors.newSingleThreadExecutor(), () -> false);
        Future<?> fut = pac.run();
        Thread.sleep(600);
        List<TestCompactionTask> toAbort = new ArrayList<>();
        for (CompactionInfo.Holder holder : getActiveCompactionsForTable(cfs)) {
            if (holder.getCompactionInfo().getSSTables().stream().anyMatch(sstable -> sstable.intersects(Collections.singleton(range)) && !sstable.isRepaired() && !sstable.isPendingRepair())) {
                assertTrue(holder.isStopRequested());
                for (TestCompactionTask tct : tcts) if (tct.sstables.equals(holder.getCompactionInfo().getSSTables()))
                    toAbort.add(tct);
            } else
                assertFalse(holder.isStopRequested());
        }
        assertEquals(2, toAbort.size());
        toAbort.forEach(TestCompactionTask::abort);
        fut.get();
        for (SSTableReader sstable : sstables) assertTrue(!sstable.intersects(Collections.singleton(range)) || sstable.isPendingRepair());
    } finally {
        tcts.forEach(TestCompactionTask::abort);
        nonAffectedTcts.forEach(TestCompactionTask::abort);
    }
}
Also used : InetAddressAndPort(org.apache.cassandra.locator.InetAddressAndPort) RangesAtEndpoint(org.apache.cassandra.locator.RangesAtEndpoint) ArrayList(java.util.ArrayList) Token(org.apache.cassandra.dht.Token) Range(org.apache.cassandra.dht.Range) Replica(org.apache.cassandra.locator.Replica) PendingAntiCompaction(org.apache.cassandra.db.repair.PendingAntiCompaction) SSTableReader(org.apache.cassandra.io.sstable.format.SSTableReader) ColumnFamilyStore(org.apache.cassandra.db.ColumnFamilyStore) UUID(java.util.UUID) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 3 with RangesAtEndpoint

use of org.apache.cassandra.locator.RangesAtEndpoint in project cassandra by apache.

the class RangeRelocator method computeRanges.

private static void computeRanges(RangesAtEndpoint srcRanges, RangesAtEndpoint dstRanges, RangesAtEndpoint.Builder ranges) {
    for (Replica src : srcRanges) {
        boolean intersect = false;
        RangesAtEndpoint remainder = null;
        for (Replica dst : dstRanges) {
            logger.debug("Comparing {} and {}", src, dst);
            // Stream the full range if there's no intersection
            if (!src.intersectsOnRange(dst))
                continue;
            // If we're transitioning from full to transient
            if (src.isFull() && dst.isTransient())
                continue;
            if (remainder == null) {
                remainder = src.subtractIgnoreTransientStatus(dst.range());
            } else {
                // Re-subtract ranges to avoid overstreaming in cases when the single range is split or merged
                RangesAtEndpoint.Builder newRemainder = new RangesAtEndpoint.Builder(remainder.endpoint());
                for (Replica replica : remainder) newRemainder.addAll(replica.subtractIgnoreTransientStatus(dst.range()));
                remainder = newRemainder.build();
            }
            intersect = true;
        }
        if (!intersect) {
            assert remainder == null;
            logger.debug("    Doesn't intersect adding {}", src);
            // should stream whole old range
            ranges.add(src);
        } else {
            ranges.addAll(remainder);
            logger.debug("    Intersects adding {}", remainder);
        }
    }
}
Also used : RangesAtEndpoint(org.apache.cassandra.locator.RangesAtEndpoint) Replica(org.apache.cassandra.locator.Replica) EndpointsByReplica(org.apache.cassandra.locator.EndpointsByReplica)

Example 4 with RangesAtEndpoint

use of org.apache.cassandra.locator.RangesAtEndpoint in project cassandra by apache.

the class RangeRelocator method calculateToFromStreams.

public void calculateToFromStreams() {
    logger.debug("Current tmd: {}, Updated tmd: {}", tokenMetaClone, tokenMetaCloneAllSettled);
    for (String keyspace : keyspaceNames) {
        // replication strategy of the current keyspace
        AbstractReplicationStrategy strategy = Keyspace.open(keyspace).getReplicationStrategy();
        logger.info("Calculating ranges to stream and request for keyspace {}", keyspace);
        // From what I have seen we only ever call this with a single token from StorageService.move(Token)
        for (Token newToken : tokens) {
            Collection<Token> currentTokens = tokenMetaClone.getTokens(localAddress);
            if (currentTokens.size() > 1 || currentTokens.isEmpty()) {
                throw new AssertionError("Unexpected current tokens: " + currentTokens);
            }
            // calculated parts of the ranges to request/stream from/to nodes in the ring
            Pair<RangesAtEndpoint, RangesAtEndpoint> streamAndFetchOwnRanges;
            // so it's easier to just identify this case up front.
            if (tokenMetaClone.getTopology().getDatacenterEndpoints().get(DatabaseDescriptor.getEndpointSnitch().getLocalDatacenter()).size() > 1) {
                // getting collection of the currently used ranges by this keyspace
                RangesAtEndpoint currentReplicas = strategy.getAddressReplicas(localAddress);
                // collection of ranges which this node will serve after move to the new token
                RangesAtEndpoint updatedReplicas = strategy.getPendingAddressRanges(tokenMetaClone, newToken, localAddress);
                streamAndFetchOwnRanges = calculateStreamAndFetchRanges(currentReplicas, updatedReplicas);
            } else {
                streamAndFetchOwnRanges = Pair.create(RangesAtEndpoint.empty(localAddress), RangesAtEndpoint.empty(localAddress));
            }
            RangesByEndpoint rangesToStream = calculateRangesToStreamWithEndpoints(streamAndFetchOwnRanges.left, strategy, tokenMetaClone, tokenMetaCloneAllSettled);
            logger.info("Endpoint ranges to stream to " + rangesToStream);
            // stream ranges
            for (InetAddressAndPort address : rangesToStream.keySet()) {
                logger.debug("Will stream range {} of keyspace {} to endpoint {}", rangesToStream.get(address), keyspace, address);
                RangesAtEndpoint ranges = rangesToStream.get(address);
                streamPlan.transferRanges(address, keyspace, ranges);
            }
            Multimap<InetAddressAndPort, RangeStreamer.FetchReplica> rangesToFetch = calculateRangesToFetchWithPreferredEndpoints(streamAndFetchOwnRanges.right, strategy, keyspace, tokenMetaClone, tokenMetaCloneAllSettled);
            // stream requests
            rangesToFetch.asMap().forEach((address, sourceAndOurReplicas) -> {
                RangesAtEndpoint full = sourceAndOurReplicas.stream().filter(pair -> pair.remote.isFull()).map(pair -> pair.local).collect(RangesAtEndpoint.collector(localAddress));
                RangesAtEndpoint trans = sourceAndOurReplicas.stream().filter(pair -> pair.remote.isTransient()).map(pair -> pair.local).collect(RangesAtEndpoint.collector(localAddress));
                logger.debug("Will request range {} of keyspace {} from endpoint {}", rangesToFetch.get(address), keyspace, address);
                streamPlan.requestRanges(address, keyspace, full, trans);
            });
            logger.debug("Keyspace {}: work map {}.", keyspace, rangesToFetch);
        }
    }
}
Also used : InetAddressAndPort(org.apache.cassandra.locator.InetAddressAndPort) Arrays(java.util.Arrays) LoggerFactory(org.slf4j.LoggerFactory) Range(org.apache.cassandra.dht.Range) Multimap(com.google.common.collect.Multimap) Future(java.util.concurrent.Future) Token(org.apache.cassandra.dht.Token) TokenMetadata(org.apache.cassandra.locator.TokenMetadata) Pair(org.apache.cassandra.utils.Pair) RangeStreamer(org.apache.cassandra.dht.RangeStreamer) DatabaseDescriptor(org.apache.cassandra.config.DatabaseDescriptor) StreamOperation(org.apache.cassandra.streaming.StreamOperation) Keyspace(org.apache.cassandra.db.Keyspace) EndpointsForRange(org.apache.cassandra.locator.EndpointsForRange) Logger(org.slf4j.Logger) FBUtilities(org.apache.cassandra.utils.FBUtilities) Collection(java.util.Collection) Set(java.util.Set) RangesByEndpoint(org.apache.cassandra.locator.RangesByEndpoint) RangesAtEndpoint(org.apache.cassandra.locator.RangesAtEndpoint) Replica(org.apache.cassandra.locator.Replica) StreamState(org.apache.cassandra.streaming.StreamState) List(java.util.List) AbstractReplicationStrategy(org.apache.cassandra.locator.AbstractReplicationStrategy) StreamPlan(org.apache.cassandra.streaming.StreamPlan) EndpointsByReplica(org.apache.cassandra.locator.EndpointsByReplica) VisibleForTesting(com.google.common.annotations.VisibleForTesting) FailureDetector(org.apache.cassandra.gms.FailureDetector) Collections(java.util.Collections) RangesAtEndpoint(org.apache.cassandra.locator.RangesAtEndpoint) InetAddressAndPort(org.apache.cassandra.locator.InetAddressAndPort) AbstractReplicationStrategy(org.apache.cassandra.locator.AbstractReplicationStrategy) Token(org.apache.cassandra.dht.Token) RangesByEndpoint(org.apache.cassandra.locator.RangesByEndpoint)

Example 5 with RangesAtEndpoint

use of org.apache.cassandra.locator.RangesAtEndpoint in project cassandra by apache.

the class RangeStreamer method fetchAsync.

public StreamResultFuture fetchAsync() {
    toFetch.forEach((keyspace, sources) -> {
        logger.debug("Keyspace {} Sources {}", keyspace, sources);
        sources.asMap().forEach((source, fetchReplicas) -> {
            // filter out already streamed ranges
            SystemKeyspace.AvailableRanges available = stateStore.getAvailableRanges(keyspace, metadata.partitioner);
            Predicate<FetchReplica> isAvailable = fetch -> {
                boolean isInFull = available.full.contains(fetch.local.range());
                boolean isInTrans = available.trans.contains(fetch.local.range());
                if (!isInFull && !isInTrans)
                    // Range is unavailable
                    return false;
                if (fetch.local.isFull())
                    // For full, pick only replicas with matching transientness
                    return isInFull == fetch.remote.isFull();
                // Any transient or full will do
                return true;
            };
            List<FetchReplica> remaining = fetchReplicas.stream().filter(not(isAvailable)).collect(Collectors.toList());
            if (remaining.size() < available.full.size() + available.trans.size()) {
                List<FetchReplica> skipped = fetchReplicas.stream().filter(isAvailable).collect(Collectors.toList());
                logger.info("Some ranges of {} are already available. Skipping streaming those ranges. Skipping {}. Fully available {} Transiently available {}", fetchReplicas, skipped, available.full, available.trans);
            }
            if (logger.isTraceEnabled())
                logger.trace("{}ing from {} ranges {}", description, source, StringUtils.join(remaining, ", "));
            InetAddressAndPort self = FBUtilities.getBroadcastAddressAndPort();
            RangesAtEndpoint full = remaining.stream().filter(pair -> pair.remote.isFull()).map(pair -> pair.local).collect(RangesAtEndpoint.collector(self));
            RangesAtEndpoint transientReplicas = remaining.stream().filter(pair -> pair.remote.isTransient()).map(pair -> pair.local).collect(RangesAtEndpoint.collector(self));
            logger.debug("Source and our replicas {}", fetchReplicas);
            logger.debug("Source {} Keyspace {}  streaming full {} transient {}", source, keyspace, full, transientReplicas);
            /* Send messages to respective folks to stream data over to me */
            streamPlan.requestRanges(source, keyspace, full, transientReplicas);
        });
    });
    return streamPlan.execute();
}
Also used : BiFunction(java.util.function.BiFunction) LoggerFactory(org.slf4j.LoggerFactory) Iterables.all(com.google.common.collect.Iterables.all) StringUtils(org.apache.commons.lang3.StringUtils) Gossiper(org.apache.cassandra.gms.Gossiper) NetworkTopologyStrategy(org.apache.cassandra.locator.NetworkTopologyStrategy) Predicates.and(com.google.common.base.Predicates.and) StreamResultFuture(org.apache.cassandra.streaming.StreamResultFuture) Replica.fullReplica(org.apache.cassandra.locator.Replica.fullReplica) HashMultimap(com.google.common.collect.HashMultimap) Replicas(org.apache.cassandra.locator.Replicas) Endpoints(org.apache.cassandra.locator.Endpoints) Predicates.not(com.google.common.base.Predicates.not) ReplicaCollection(org.apache.cassandra.locator.ReplicaCollection) Map(java.util.Map) EndpointsByRange(org.apache.cassandra.locator.EndpointsByRange) Keyspace(org.apache.cassandra.db.Keyspace) EndpointsForRange(org.apache.cassandra.locator.EndpointsForRange) FBUtilities(org.apache.cassandra.utils.FBUtilities) Collection(java.util.Collection) Set(java.util.Set) Collectors(java.util.stream.Collectors) RangesAtEndpoint(org.apache.cassandra.locator.RangesAtEndpoint) List(java.util.List) Predicate(com.google.common.base.Predicate) Conflict(org.apache.cassandra.locator.ReplicaCollection.Builder.Conflict) Optional(java.util.Optional) FailureDetector(org.apache.cassandra.gms.FailureDetector) Iterables.any(com.google.common.collect.Iterables.any) InetAddressAndPort(org.apache.cassandra.locator.InetAddressAndPort) Iterables(com.google.common.collect.Iterables) HashMap(java.util.HashMap) Multimap(com.google.common.collect.Multimap) Function(java.util.function.Function) SystemKeyspace(org.apache.cassandra.db.SystemKeyspace) ArrayList(java.util.ArrayList) IEndpointSnitch(org.apache.cassandra.locator.IEndpointSnitch) TokenMetadata(org.apache.cassandra.locator.TokenMetadata) ImmutableMultimap(com.google.common.collect.ImmutableMultimap) StreamOperation(org.apache.cassandra.streaming.StreamOperation) Logger(org.slf4j.Logger) Replica(org.apache.cassandra.locator.Replica) IFailureDetector(org.apache.cassandra.gms.IFailureDetector) PreviewKind(org.apache.cassandra.streaming.PreviewKind) AbstractReplicationStrategy(org.apache.cassandra.locator.AbstractReplicationStrategy) StreamPlan(org.apache.cassandra.streaming.StreamPlan) EndpointsByReplica(org.apache.cassandra.locator.EndpointsByReplica) Preconditions(com.google.common.base.Preconditions) VisibleForTesting(com.google.common.annotations.VisibleForTesting) LocalStrategy(org.apache.cassandra.locator.LocalStrategy) InetAddressAndPort(org.apache.cassandra.locator.InetAddressAndPort) RangesAtEndpoint(org.apache.cassandra.locator.RangesAtEndpoint) SystemKeyspace(org.apache.cassandra.db.SystemKeyspace)

Aggregations

RangesAtEndpoint (org.apache.cassandra.locator.RangesAtEndpoint)32 Token (org.apache.cassandra.dht.Token)22 Range (org.apache.cassandra.dht.Range)20 Replica (org.apache.cassandra.locator.Replica)17 SSTableReader (org.apache.cassandra.io.sstable.format.SSTableReader)10 EndpointsByReplica (org.apache.cassandra.locator.EndpointsByReplica)10 ArrayList (java.util.ArrayList)9 List (java.util.List)9 Test (org.junit.Test)9 Logger (org.slf4j.Logger)9 LoggerFactory (org.slf4j.LoggerFactory)9 Collection (java.util.Collection)8 DatabaseDescriptor (org.apache.cassandra.config.DatabaseDescriptor)8 InetAddressAndPort (org.apache.cassandra.locator.InetAddressAndPort)8 VisibleForTesting (com.google.common.annotations.VisibleForTesting)7 Set (java.util.Set)7 UUID (java.util.UUID)7 Replica.fullReplica (org.apache.cassandra.locator.Replica.fullReplica)7 IOException (java.io.IOException)6 Replica.transientReplica (org.apache.cassandra.locator.Replica.transientReplica)6