Search in sources :

Example 1 with Future

use of org.apache.cassandra.utils.concurrent.Future in project cassandra by apache.

the class HintsService method excise.

/**
 * Cleans up hints-related state after a node with id = hostId left.
 *
 * Dispatcher can not stop itself (isHostAlive() can not start returning false for the leaving host because this
 * method is called by the same thread as gossip, which blocks gossip), so we can't simply wait for
 * completion.
 *
 * We should also flush the buffer if there are any hints for the node there, and close the writer (if any),
 * so that we don't leave any hint files lying around.
 *
 * Once that is done, we can simply delete all hint files and remove the host id from the catalog.
 *
 * The worst that can happen if we don't get everything right is a hints file (or two) remaining undeleted.
 *
 * @param hostId id of the node being excised
 */
public void excise(UUID hostId) {
    HintsStore store = catalog.getNullable(hostId);
    if (store == null)
        return;
    // flush the buffer and then close the writer for the excised host id, to make sure that no new files will appear
    // for this host id after we are done
    Future flushFuture = writeExecutor.flushBufferPool(bufferPool, Collections.singleton(store));
    Future closeFuture = writeExecutor.closeWriter(store);
    try {
        flushFuture.get();
        closeFuture.get();
    } catch (InterruptedException e) {
        throw new UncheckedInterruptedException(e);
    } catch (ExecutionException e) {
        throw new RuntimeException(e);
    }
    // interrupt the current dispatch session to end (if any), so that the currently dispatched file gets removed
    dispatchExecutor.interruptDispatch(store.hostId);
    // delete all the hints files and remove the HintsStore instance from the map in the catalog
    catalog.exciseStore(hostId);
}
Also used : ScheduledFuture(java.util.concurrent.ScheduledFuture) Future(org.apache.cassandra.utils.concurrent.Future) UncheckedInterruptedException(org.apache.cassandra.utils.concurrent.UncheckedInterruptedException) ExecutionException(java.util.concurrent.ExecutionException) UncheckedInterruptedException(org.apache.cassandra.utils.concurrent.UncheckedInterruptedException)

Example 2 with Future

use of org.apache.cassandra.utils.concurrent.Future in project cassandra by apache.

the class CommitLogReplayer method blockForWrites.

/**
 * Flushes all keyspaces associated with this replayer in parallel, blocking until their flushes are complete.
 * @return the number of mutations replayed
 */
public int blockForWrites() {
    for (Map.Entry<TableId, AtomicInteger> entry : commitLogReader.getInvalidMutations()) logger.warn("Skipped {} mutations from unknown (probably removed) CF with id {}", entry.getValue(), entry.getKey());
    // wait for all the writes to finish on the mutation stage
    FBUtilities.waitOnFutures(futures);
    logger.trace("Finished waiting on mutations from recovery");
    // flush replayed keyspaces
    futures.clear();
    boolean flushingSystem = false;
    List<Future<?>> futures = new ArrayList<Future<?>>();
    for (Keyspace keyspace : keyspacesReplayed) {
        if (keyspace.getName().equals(SchemaConstants.SYSTEM_KEYSPACE_NAME))
            flushingSystem = true;
        futures.addAll(keyspace.flush());
    }
    // also flush batchlog incase of any MV updates
    if (!flushingSystem)
        futures.add(Keyspace.open(SchemaConstants.SYSTEM_KEYSPACE_NAME).getColumnFamilyStore(SystemKeyspace.BATCHES).forceFlush());
    FBUtilities.waitOnFutures(futures);
    return replayedCount.get();
}
Also used : TableId(org.apache.cassandra.schema.TableId) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) SystemKeyspace(org.apache.cassandra.db.SystemKeyspace) Keyspace(org.apache.cassandra.db.Keyspace) Future(org.apache.cassandra.utils.concurrent.Future)

Example 3 with Future

use of org.apache.cassandra.utils.concurrent.Future in project cassandra by apache.

the class StorageService method restoreReplicaCount.

/**
 * Called when an endpoint is removed from the ring. This function checks
 * whether this node becomes responsible for new ranges as a
 * consequence and streams data if needed.
 *
 * This is rather ineffective, but it does not matter so much
 * since this is called very seldom
 *
 * @param endpoint the node that left
 */
private void restoreReplicaCount(InetAddressAndPort endpoint, final InetAddressAndPort notifyEndpoint) {
    Map<String, Multimap<InetAddressAndPort, FetchReplica>> replicasToFetch = new HashMap<>();
    InetAddressAndPort myAddress = FBUtilities.getBroadcastAddressAndPort();
    for (String keyspaceName : Schema.instance.getNonLocalStrategyKeyspaces()) {
        logger.debug("Restoring replica count for keyspace {}", keyspaceName);
        EndpointsByReplica changedReplicas = getChangedReplicasForLeaving(keyspaceName, endpoint, tokenMetadata, Keyspace.open(keyspaceName).getReplicationStrategy());
        Set<LeavingReplica> myNewReplicas = new HashSet<>();
        for (Map.Entry<Replica, Replica> entry : changedReplicas.flattenEntries()) {
            Replica replica = entry.getValue();
            if (replica.endpoint().equals(myAddress)) {
                // Maybe we don't technically need to fetch transient data from somewhere
                // but it's probably not a lot and it probably makes things a hair more resilient to people
                // not running repair when they should.
                myNewReplicas.add(new LeavingReplica(entry.getKey(), entry.getValue()));
            }
        }
        logger.debug("Changed replicas for leaving {}, myNewReplicas {}", changedReplicas, myNewReplicas);
        replicasToFetch.put(keyspaceName, getNewSourceReplicas(keyspaceName, myNewReplicas));
    }
    StreamPlan stream = new StreamPlan(StreamOperation.RESTORE_REPLICA_COUNT);
    replicasToFetch.forEach((keyspaceName, sources) -> {
        logger.debug("Requesting keyspace {} sources", keyspaceName);
        sources.asMap().forEach((sourceAddress, fetchReplicas) -> {
            logger.debug("Source and our replicas are {}", fetchReplicas);
            // Remember whether this node is providing the full or transient replicas for this range. We are going
            // to pass streaming the local instance of Replica for the range which doesn't tell us anything about the source
            // By encoding it as two separate sets we retain this information about the source.
            RangesAtEndpoint full = fetchReplicas.stream().filter(f -> f.remote.isFull()).map(f -> f.local).collect(RangesAtEndpoint.collector(myAddress));
            RangesAtEndpoint transientReplicas = fetchReplicas.stream().filter(f -> f.remote.isTransient()).map(f -> f.local).collect(RangesAtEndpoint.collector(myAddress));
            if (logger.isDebugEnabled())
                logger.debug("Requesting from {} full replicas {} transient replicas {}", sourceAddress, StringUtils.join(full, ", "), StringUtils.join(transientReplicas, ", "));
            stream.requestRanges(sourceAddress, keyspaceName, full, transientReplicas);
        });
    });
    StreamResultFuture future = stream.execute();
    future.addCallback(new FutureCallback<StreamState>() {

        public void onSuccess(StreamState finalState) {
            sendReplicationNotification(notifyEndpoint);
        }

        public void onFailure(Throwable t) {
            logger.warn("Streaming to restore replica count failed", t);
            // We still want to send the notification
            sendReplicationNotification(notifyEndpoint);
        }
    });
}
Also used : TraceKeyspace(org.apache.cassandra.tracing.TraceKeyspace) StorageMetrics(org.apache.cassandra.metrics.StorageMetrics) File(org.apache.cassandra.io.util.File) CommitLog(org.apache.cassandra.db.commitlog.CommitLog) AuthKeyspace(org.apache.cassandra.auth.AuthKeyspace) org.apache.cassandra.utils(org.apache.cassandra.utils) Global.nanoTime(org.apache.cassandra.utils.Clock.Global.nanoTime) StringUtils(org.apache.commons.lang3.StringUtils) TokenFactory(org.apache.cassandra.dht.Token.TokenFactory) VersionAndType(org.apache.cassandra.io.sstable.format.VersionAndType) InetAddress(java.net.InetAddress) SystemDistributedKeyspace(org.apache.cassandra.schema.SystemDistributedKeyspace) SecondaryIndexManager.isIndexColumnFamily(org.apache.cassandra.index.SecondaryIndexManager.isIndexColumnFamily) SecondaryIndexManager.getIndexName(org.apache.cassandra.index.SecondaryIndexManager.getIndexName) Arrays.asList(java.util.Arrays.asList) HintsService(org.apache.cassandra.hints.HintsService) JMXBroadcastExecutor(org.apache.cassandra.utils.progress.jmx.JMXBroadcastExecutor) MILLISECONDS(java.util.concurrent.TimeUnit.MILLISECONDS) FullQueryLoggerOptions(org.apache.cassandra.fql.FullQueryLoggerOptions) ViewMetadata(org.apache.cassandra.schema.ViewMetadata) Stream(java.util.stream.Stream) Predicate(com.google.common.base.Predicate) CassandraRelevantProperties(org.apache.cassandra.config.CassandraRelevantProperties) FullQueryLogger(org.apache.cassandra.fql.FullQueryLogger) Conflict(org.apache.cassandra.locator.ReplicaCollection.Builder.Conflict) KeyspaceMetadata(org.apache.cassandra.schema.KeyspaceMetadata) LoggingSupportFactory(org.apache.cassandra.utils.logging.LoggingSupportFactory) NoPayload.noPayload(org.apache.cassandra.net.NoPayload.noPayload) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ProgressEvent(org.apache.cassandra.utils.progress.ProgressEvent) java.util(java.util) OpenDataException(javax.management.openmbean.OpenDataException) CompactionManager(org.apache.cassandra.db.compaction.CompactionManager) SSTableLoader(org.apache.cassandra.io.sstable.SSTableLoader) ClientResourceLimits(org.apache.cassandra.transport.ClientResourceLimits) Global.currentTimeMillis(org.apache.cassandra.utils.Clock.Global.currentTimeMillis) Range(org.apache.cassandra.dht.Range) MINUTES(java.util.concurrent.TimeUnit.MINUTES) QueryProcessor(org.apache.cassandra.cql3.QueryProcessor) Supplier(java.util.function.Supplier) REPLICATION_DONE_REQ(org.apache.cassandra.net.Verb.REPLICATION_DONE_REQ) Schema(org.apache.cassandra.schema.Schema) ActiveRepairService(org.apache.cassandra.service.ActiveRepairService) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) FullQueryLoggerOptionsCompositeData(org.apache.cassandra.fql.FullQueryLoggerOptionsCompositeData) Predicates(com.google.common.base.Predicates) BatchlogManager(org.apache.cassandra.batchlog.BatchlogManager) StreamSupport(java.util.stream.StreamSupport) ProgressEventType(org.apache.cassandra.utils.progress.ProgressEventType) Nullable(javax.annotation.Nullable) CompositeData(javax.management.openmbean.CompositeData) IOException(java.io.IOException) UnknownHostException(java.net.UnknownHostException) IOError(java.io.IOError) ExecutionException(java.util.concurrent.ExecutionException) Paths(java.nio.file.Paths) ImmediateFuture(org.apache.cassandra.utils.concurrent.ImmediateFuture) org.apache.cassandra.net(org.apache.cassandra.net) SnapshotManager(org.apache.cassandra.service.snapshot.SnapshotManager) Preconditions(com.google.common.base.Preconditions) org.apache.cassandra.locator(org.apache.cassandra.locator) AuditLogManager(org.apache.cassandra.audit.AuditLogManager) Verifier(org.apache.cassandra.db.compaction.Verifier) org.apache.cassandra.repair(org.apache.cassandra.repair) org.apache.cassandra.streaming(org.apache.cassandra.streaming) Iterables.transform(com.google.common.collect.Iterables.transform) Iterables.tryFind(com.google.common.collect.Iterables.tryFind) MatchResult(java.util.regex.MatchResult) LoggerFactory(org.slf4j.LoggerFactory) org.apache.cassandra.db(org.apache.cassandra.db) ReplicationParams(org.apache.cassandra.schema.ReplicationParams) TimeoutException(java.util.concurrent.TimeoutException) org.apache.cassandra.gms(org.apache.cassandra.gms) com.google.common.util.concurrent(com.google.common.util.concurrent) TabularData(javax.management.openmbean.TabularData) ByteBuffer(java.nio.ByteBuffer) MigrationManager(org.apache.cassandra.schema.MigrationManager) ByteArrayInputStream(java.io.ByteArrayInputStream) Collectors.toMap(java.util.stream.Collectors.toMap) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) SSTableFormat(org.apache.cassandra.io.sstable.format.SSTableFormat) AuthSchemaChangeListener(org.apache.cassandra.auth.AuthSchemaChangeListener) PathUtils(org.apache.cassandra.io.util.PathUtils) com.google.common.collect(com.google.common.collect) DatabaseDescriptor(org.apache.cassandra.config.DatabaseDescriptor) AuditLogOptions(org.apache.cassandra.audit.AuditLogOptions) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) TombstoneOption(org.apache.cassandra.schema.CompactionParams.TombstoneOption) JMXProgressSupport(org.apache.cassandra.utils.progress.jmx.JMXProgressSupport) Instant(java.time.Instant) org.apache.cassandra.dht(org.apache.cassandra.dht) InetSocketAddress(java.net.InetSocketAddress) Collectors(java.util.stream.Collectors) UncheckedInterruptedException(org.apache.cassandra.utils.concurrent.UncheckedInterruptedException) ProgressListener(org.apache.cassandra.utils.progress.ProgressListener) AuthCacheService(org.apache.cassandra.auth.AuthCacheService) DurationSpec(org.apache.cassandra.config.DurationSpec) MigrationManager.evolveSystemKeyspace(org.apache.cassandra.schema.MigrationManager.evolveSystemKeyspace) ParameterizedClass(org.apache.cassandra.config.ParameterizedClass) LifecycleTransaction(org.apache.cassandra.db.lifecycle.LifecycleTransaction) Future(org.apache.cassandra.utils.concurrent.Future) org.apache.cassandra.exceptions(org.apache.cassandra.exceptions) FileUtils(org.apache.cassandra.io.util.FileUtils) TableMetadataRef(org.apache.cassandra.schema.TableMetadataRef) TabularDataSupport(javax.management.openmbean.TabularDataSupport) Entry(java.util.Map.Entry) org.apache.cassandra.concurrent(org.apache.cassandra.concurrent) TableMetadata(org.apache.cassandra.schema.TableMetadata) VirtualKeyspaceRegistry(org.apache.cassandra.db.virtual.VirtualKeyspaceRegistry) Pattern(java.util.regex.Pattern) MigrationCoordinator(org.apache.cassandra.schema.MigrationCoordinator) SchemaConstants(org.apache.cassandra.schema.SchemaConstants) Arrays.stream(java.util.Arrays.stream) DataInputStream(java.io.DataInputStream) RepairOption(org.apache.cassandra.repair.messages.RepairOption) NANOSECONDS(java.util.concurrent.TimeUnit.NANOSECONDS) Config(org.apache.cassandra.config.Config) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) QueryHandler(org.apache.cassandra.cql3.QueryHandler) BOOTSTRAP_SKIP_SCHEMA_CHECK(org.apache.cassandra.config.CassandraRelevantProperties.BOOTSTRAP_SKIP_SCHEMA_CHECK) FetchReplica(org.apache.cassandra.dht.RangeStreamer.FetchReplica) ProtocolVersion(org.apache.cassandra.transport.ProtocolVersion) ExecutorService(java.util.concurrent.ExecutorService) Logger(org.slf4j.Logger) javax.management(javax.management) REPLACEMENT_ALLOW_EMPTY(org.apache.cassandra.config.CassandraRelevantProperties.REPLACEMENT_ALLOW_EMPTY) TimeUnit(java.util.concurrent.TimeUnit) Collectors.toList(java.util.stream.Collectors.toList) VisibleForTesting(com.google.common.annotations.VisibleForTesting) BOOTSTRAP_SCHEMA_DELAY_MS(org.apache.cassandra.config.CassandraRelevantProperties.BOOTSTRAP_SCHEMA_DELAY_MS) TableSnapshot(org.apache.cassandra.service.snapshot.TableSnapshot) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) FetchReplica(org.apache.cassandra.dht.RangeStreamer.FetchReplica) Collectors.toMap(java.util.stream.Collectors.toMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Example 4 with Future

use of org.apache.cassandra.utils.concurrent.Future in project cassandra by apache.

the class StorageService method unbootstrap.

private void unbootstrap(Runnable onFinish) throws ExecutionException, InterruptedException {
    Supplier<Future<StreamState>> startStreaming = prepareUnbootstrapStreaming();
    setMode(Mode.LEAVING, "replaying batch log and streaming data to other nodes", true);
    // Start with BatchLog replay, which may create hints but no writes since this is no longer a valid endpoint.
    Future<?> batchlogReplay = BatchlogManager.instance.startBatchlogReplay();
    Future<StreamState> streamSuccess = startStreaming.get();
    // Wait for batch log to complete before streaming hints.
    logger.debug("waiting for batch log processing.");
    batchlogReplay.get();
    setMode(Mode.LEAVING, "streaming hints to other nodes", true);
    Future hintsSuccess = streamHints();
    // wait for the transfer runnables to signal the latch.
    logger.debug("waiting for stream acks.");
    streamSuccess.get();
    hintsSuccess.get();
    logger.debug("stream acks all received.");
    leaveRing();
    onFinish.run();
}
Also used : ImmediateFuture(org.apache.cassandra.utils.concurrent.ImmediateFuture) Future(org.apache.cassandra.utils.concurrent.Future)

Example 5 with Future

use of org.apache.cassandra.utils.concurrent.Future in project cassandra by apache.

the class AutoSavingCache method loadSaved.

public int loadSaved() {
    int count = 0;
    long start = nanoTime();
    // modern format, allows both key and value (so key cache load can be purely sequential)
    File dataPath = getCacheDataPath(CURRENT_VERSION);
    File crcPath = getCacheCrcPath(CURRENT_VERSION);
    if (dataPath.exists() && crcPath.exists()) {
        DataInputStreamPlus in = null;
        try {
            logger.info("reading saved cache {}", dataPath);
            in = new DataInputStreamPlus(new LengthAvailableInputStream(new BufferedInputStream(streamFactory.getInputStream(dataPath, crcPath)), dataPath.length()));
            // Check the schema has not changed since CFs are looked up by name which is ambiguous
            UUID schemaVersion = new UUID(in.readLong(), in.readLong());
            if (!schemaVersion.equals(Schema.instance.getVersion()))
                throw new RuntimeException("Cache schema version " + schemaVersion + " does not match current schema version " + Schema.instance.getVersion());
            ArrayDeque<Future<Pair<K, V>>> futures = new ArrayDeque<>();
            long loadByNanos = start + TimeUnit.SECONDS.toNanos(DatabaseDescriptor.getCacheLoadTimeout());
            while (nanoTime() < loadByNanos && in.available() > 0) {
                // tableId and indexName are serialized by the serializers in CacheService
                // That is delegated there because there are serializer specific conditions
                // where a cache key is skipped and not written
                TableId tableId = TableId.deserialize(in);
                String indexName = in.readUTF();
                if (indexName.isEmpty())
                    indexName = null;
                ColumnFamilyStore cfs = Schema.instance.getColumnFamilyStoreInstance(tableId);
                if (indexName != null && cfs != null)
                    cfs = cfs.indexManager.getIndexByName(indexName).getBackingTable().orElse(null);
                Future<Pair<K, V>> entryFuture = cacheLoader.deserialize(in, cfs);
                // Key cache entry can return null, if the SSTable doesn't exist.
                if (entryFuture == null)
                    continue;
                futures.offer(entryFuture);
                count++;
                /*
                     * Kind of unwise to accrue an unbounded number of pending futures
                     * So now there is this loop to keep a bounded number pending.
                     */
                do {
                    while (futures.peek() != null && futures.peek().isDone()) {
                        Future<Pair<K, V>> future = futures.poll();
                        Pair<K, V> entry = future.get();
                        if (entry != null && entry.right != null)
                            put(entry.left, entry.right);
                    }
                    if (futures.size() > 1000)
                        Thread.yield();
                } while (futures.size() > 1000);
            }
            Future<Pair<K, V>> future = null;
            while ((future = futures.poll()) != null) {
                Pair<K, V> entry = future.get();
                if (entry != null && entry.right != null)
                    put(entry.left, entry.right);
            }
        } catch (CorruptFileException e) {
            JVMStabilityInspector.inspectThrowable(e);
            logger.warn(String.format("Non-fatal checksum error reading saved cache %s", dataPath.absolutePath()), e);
        } catch (Throwable t) {
            JVMStabilityInspector.inspectThrowable(t);
            logger.info(String.format("Harmless error reading saved cache %s", dataPath.absolutePath()), t);
        } finally {
            FileUtils.closeQuietly(in);
            cacheLoader.cleanupAfterDeserialize();
        }
    }
    if (logger.isTraceEnabled())
        logger.trace("completed reading ({} ms; {} keys) saved cache {}", TimeUnit.NANOSECONDS.toMillis(nanoTime() - start), count, dataPath);
    return count;
}
Also used : TableId(org.apache.cassandra.schema.TableId) BufferedInputStream(java.io.BufferedInputStream) DataInputStreamPlus(org.apache.cassandra.io.util.DataInputPlus.DataInputStreamPlus) ColumnFamilyStore(org.apache.cassandra.db.ColumnFamilyStore) ScheduledFuture(java.util.concurrent.ScheduledFuture) Future(org.apache.cassandra.utils.concurrent.Future) Pair(org.apache.cassandra.utils.Pair)

Aggregations

Future (org.apache.cassandra.utils.concurrent.Future)29 ImmediateFuture (org.apache.cassandra.utils.concurrent.ImmediateFuture)12 InetAddressAndPort (org.apache.cassandra.locator.InetAddressAndPort)11 Test (org.junit.Test)8 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)7 DatabaseDescriptor (org.apache.cassandra.config.DatabaseDescriptor)7 ExecutionException (java.util.concurrent.ExecutionException)6 Collectors (java.util.stream.Collectors)6 ColumnFamilyStore (org.apache.cassandra.db.ColumnFamilyStore)6 CoordinatedRepairResult (org.apache.cassandra.repair.CoordinatedRepairResult)6 Logger (org.slf4j.Logger)6 LoggerFactory (org.slf4j.LoggerFactory)6 VisibleForTesting (com.google.common.annotations.VisibleForTesting)5 UUID (java.util.UUID)5 TimeUnit (java.util.concurrent.TimeUnit)5 AbstractRepairTest (org.apache.cassandra.repair.AbstractRepairTest)5 AsyncFuture (org.apache.cassandra.utils.concurrent.AsyncFuture)5 ByteBuffer (java.nio.ByteBuffer)4 java.util (java.util)4 Range (org.apache.cassandra.dht.Range)4