All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.flink.runtime.state.IncrementalRemoteKeyedStateHandle Maven / Gradle / Ivy

The newest version!
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.flink.runtime.state;

import org.apache.flink.annotation.VisibleForTesting;
import org.apache.flink.util.Preconditions;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Nonnull;

import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * The handle to states of an incremental snapshot.
 *
 * 

The states contained in an incremental snapshot include: * *

    *
  • Created shared state which includes shared files produced since the last completed * checkpoint. These files can be referenced by succeeding checkpoints if the checkpoint * succeeds to complete. *
  • Referenced shared state which includes the shared files materialized in previous * checkpoints. Until we this is registered to a {@link SharedStateRegistry}, all referenced * shared state handles are only placeholders, so that we do not send state handles twice from * which we know that they already exist on the checkpoint coordinator. *
  • Private state which includes all other files, typically mutable, that cannot be shared by * other checkpoints. *
  • Backend meta state which includes the information of existing states. *
* * When this should become a completed checkpoint on the checkpoint coordinator, it must first be * registered with a {@link SharedStateRegistry}, so that all placeholder state handles to * previously existing state are replaced with the originals. * *

IMPORTANT: This class currently overrides equals and hash code only for testing purposes. They * should not be called from production code. This means this class is also not suited to serve as a * key, e.g. in hash maps. */ public class IncrementalRemoteKeyedStateHandle extends AbstractIncrementalStateHandle { public static final long UNKNOWN_CHECKPOINTED_SIZE = -1L; private static final Logger LOG = LoggerFactory.getLogger(IncrementalRemoteKeyedStateHandle.class); private static final long serialVersionUID = -8328808513197388231L; /** Private state in the incremental checkpoint. */ private final List privateState; private final long persistedSizeOfThisCheckpoint; /** * Once the shared states are registered, it is the {@link SharedStateRegistry}'s responsibility * to cleanup those shared states. But in the cases where the state handle is discarded before * performing the registration, the handle should delete all the shared states created by it. * *

This variable is not null iff the handles was registered. */ private transient SharedStateRegistry sharedStateRegistry; @VisibleForTesting public IncrementalRemoteKeyedStateHandle( UUID backendIdentifier, KeyGroupRange keyGroupRange, long checkpointId, List sharedState, List privateState, StreamStateHandle metaStateHandle) { this( backendIdentifier, keyGroupRange, checkpointId, sharedState, privateState, metaStateHandle, UNKNOWN_CHECKPOINTED_SIZE, new StateHandleID(UUID.randomUUID().toString())); } public IncrementalRemoteKeyedStateHandle( UUID backendIdentifier, KeyGroupRange keyGroupRange, long checkpointId, List sharedState, List privateState, StreamStateHandle metaStateHandle, long persistedSizeOfThisCheckpoint) { this( backendIdentifier, keyGroupRange, checkpointId, sharedState, privateState, metaStateHandle, persistedSizeOfThisCheckpoint, new StateHandleID(UUID.randomUUID().toString())); } protected IncrementalRemoteKeyedStateHandle( UUID backendIdentifier, KeyGroupRange keyGroupRange, long checkpointId, List sharedState, List privateState, StreamStateHandle metaStateHandle, long persistedSizeOfThisCheckpoint, StateHandleID stateHandleId) { super( Preconditions.checkNotNull(backendIdentifier), Preconditions.checkNotNull(keyGroupRange), checkpointId, sharedState, metaStateHandle, stateHandleId); this.privateState = Preconditions.checkNotNull(privateState); this.sharedStateRegistry = null; this.persistedSizeOfThisCheckpoint = persistedSizeOfThisCheckpoint == UNKNOWN_CHECKPOINTED_SIZE ? getStateSize() : persistedSizeOfThisCheckpoint; } public static IncrementalRemoteKeyedStateHandle restore( UUID backendIdentifier, KeyGroupRange keyGroupRange, long checkpointId, List sharedState, List privateState, StreamStateHandle metaStateHandle, long persistedSizeOfThisCheckpoint, StateHandleID stateHandleId) { return new IncrementalRemoteKeyedStateHandle( backendIdentifier, keyGroupRange, checkpointId, sharedState, privateState, metaStateHandle, persistedSizeOfThisCheckpoint, stateHandleId); } @Override public CheckpointBoundKeyedStateHandle rebound(long checkpointId) { return new IncrementalRemoteKeyedStateHandle( backendIdentifier, keyGroupRange, checkpointId, sharedState, privateState, metaStateHandle, persistedSizeOfThisCheckpoint, stateHandleId); } public List getSharedState() { return sharedState; } public List getPrivateState() { return privateState; } @Nonnull @Override public List getSharedStateHandles() { return getSharedState(); } public SharedStateRegistry getSharedStateRegistry() { return sharedStateRegistry; } @Override public void discardState() throws Exception { SharedStateRegistry registry = this.sharedStateRegistry; final boolean isRegistered = (registry != null); LOG.trace( "Discarding IncrementalRemoteKeyedStateHandle (registered = {}) for checkpoint {} from backend with id {}.", isRegistered, checkpointId, backendIdentifier); try { metaStateHandle.discardState(); } catch (Exception e) { LOG.warn("Could not properly discard meta data.", e); } try { StateUtil.bestEffortDiscardAllStateObjects( privateState.stream() .map(HandleAndLocalPath::getHandle) .collect(Collectors.toList())); } catch (Exception e) { LOG.warn("Could not properly discard misc file states.", e); } // discard only on TM; on JM, shared state is removed on subsumption if (!isRegistered) { try { StateUtil.bestEffortDiscardAllStateObjects( sharedState.stream() .map(HandleAndLocalPath::getHandle) .collect(Collectors.toList())); } catch (Exception e) { LOG.warn("Could not properly discard new sst file states.", e); } } } @Override public long getStateSize() { return streamSubHandles().mapToLong(StateObject::getStateSize).sum(); } @Override public void collectSizeStats(StateObjectSizeStatsCollector collector) { streamSubHandles().forEach(handle -> handle.collectSizeStats(collector)); } public Stream streamSubHandles() { return Stream.of( Stream.of(metaStateHandle), sharedState.stream().map(HandleAndLocalPath::getHandle), privateState.stream().map(HandleAndLocalPath::getHandle)) .flatMap(Function.identity()) .filter(Objects::nonNull); } @Override public long getCheckpointedSize() { return persistedSizeOfThisCheckpoint; } @Override public void registerSharedStates(SharedStateRegistry stateRegistry, long checkpointID) { // This is a quick check to avoid that we register twice with the same registry. However, // the code allows to // register again with a different registry. The implication is that ownership is // transferred to this new // registry. This should only happen in case of a restart, when the CheckpointCoordinator // creates a new // SharedStateRegistry for the current attempt and the old registry becomes meaningless. We // also assume that // an old registry object from a previous run is due to be GCed and will never be used for // registration again. Preconditions.checkState( sharedStateRegistry != stateRegistry, "The state handle has already registered its shared states to the given registry."); sharedStateRegistry = Preconditions.checkNotNull(stateRegistry); LOG.trace( "Registering IncrementalRemoteKeyedStateHandle for checkpoint {} from backend with id {}.", checkpointId, backendIdentifier); for (HandleAndLocalPath handleAndLocalPath : sharedState) { StreamStateHandle reference = stateRegistry.registerReference( SharedStateRegistryKey.forStreamStateHandle( handleAndLocalPath.getHandle()), handleAndLocalPath.getHandle(), checkpointID); // This step consolidates our shared handles with the registry, which will replace // placeholder state handle with already registered, actual state handles. // Because of SharedStateRegistryKey is based on the physical id of the stream handle, // no de-duplication will be performed. see FLINK-29913. handleAndLocalPath.replaceHandle(reference); } } @VisibleForTesting IncrementalRemoteKeyedStateHandle copy() { return new IncrementalRemoteKeyedStateHandle( backendIdentifier, keyGroupRange, checkpointId, sharedState, privateState, metaStateHandle, persistedSizeOfThisCheckpoint, stateHandleId); } @Override public String toString() { return "IncrementalRemoteKeyedStateHandle{" + "privateState=" + privateState + ", persistedSizeOfThisCheckpoint=" + persistedSizeOfThisCheckpoint + ", registered=" + (sharedStateRegistry != null) + "} " + super.toString(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy