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

org.apache.flink.runtime.checkpoint.metadata.MetadataV3Serializer Maven / Gradle / Ivy

/*
 * 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.checkpoint.metadata;

import org.apache.flink.annotation.Internal;
import org.apache.flink.annotation.VisibleForTesting;
import org.apache.flink.runtime.checkpoint.FinishedOperatorSubtaskState;
import org.apache.flink.runtime.checkpoint.FullyFinishedOperatorState;
import org.apache.flink.runtime.checkpoint.OperatorState;
import org.apache.flink.runtime.checkpoint.OperatorSubtaskState;
import org.apache.flink.runtime.checkpoint.StateObjectCollection;
import org.apache.flink.runtime.jobgraph.OperatorID;
import org.apache.flink.runtime.state.InputChannelStateHandle;
import org.apache.flink.runtime.state.KeyedStateHandle;
import org.apache.flink.runtime.state.OperatorStateHandle;
import org.apache.flink.runtime.state.ResultSubpartitionStateHandle;
import org.apache.flink.runtime.state.StateObject;
import org.apache.flink.runtime.state.StreamStateHandle;
import org.apache.flink.runtime.state.memory.ByteStreamStateHandle;
import org.apache.flink.util.function.BiConsumerWithException;

import javax.annotation.Nullable;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Map;

import static org.apache.flink.util.Preconditions.checkState;

/**
 * (De)serializer for checkpoint metadata format version 3. This format was introduced with Apache
 * Flink 1.11.0.
 *
 * 

Compared to format version 2, this drops some unused fields and introduces operator * coordinator state. * *

See {@link MetadataV2V3SerializerBase} for a description of the format layout. */ @Internal public class MetadataV3Serializer extends MetadataV2V3SerializerBase implements MetadataSerializer { /** The metadata format version. */ public static final int VERSION = 3; /** The singleton instance of the serializer. */ public static final MetadataV3Serializer INSTANCE = new MetadataV3Serializer(); private final ChannelStateHandleSerializer channelStateHandleSerializer = new ChannelStateHandleSerializer(); /** Singleton, not meant to be instantiated. */ private MetadataV3Serializer() {} @Override public int getVersion() { return VERSION; } // ------------------------------------------------------------------------ // (De)serialization entry points // ------------------------------------------------------------------------ public static void serialize(CheckpointMetadata checkpointMetadata, DataOutputStream dos) throws IOException { INSTANCE.serializeMetadata(checkpointMetadata, dos); } @Override public CheckpointMetadata deserialize( DataInputStream dis, ClassLoader classLoader, String externalPointer) throws IOException { return deserializeMetadata(dis, externalPointer); } // ------------------------------------------------------------------------ // version-specific serialization formats // ------------------------------------------------------------------------ @Override protected void serializeOperatorState(OperatorState operatorState, DataOutputStream dos) throws IOException { // Operator ID dos.writeLong(operatorState.getOperatorID().getLowerPart()); dos.writeLong(operatorState.getOperatorID().getUpperPart()); // Parallelism dos.writeInt(operatorState.getParallelism()); dos.writeInt(operatorState.getMaxParallelism()); // Coordinator state serializeStreamStateHandle(operatorState.getCoordinatorState(), dos); // Sub task states if (operatorState.isFullyFinished()) { dos.writeInt(-1); } else { final Map subtaskStateMap = operatorState.getSubtaskStates(); dos.writeInt(subtaskStateMap.size()); for (Map.Entry entry : subtaskStateMap.entrySet()) { boolean isFinished = entry.getValue().isFinished(); serializeSubtaskIndexAndFinishedState(entry.getKey(), isFinished, dos); if (!isFinished) { serializeSubtaskState(entry.getValue(), dos); } } } } private void serializeSubtaskIndexAndFinishedState( int subtaskIndex, boolean isFinished, DataOutputStream dos) throws IOException { if (isFinished) { // We store a negative index for the finished subtask. In consideration // of the index 0, the negative index would start from -1. dos.writeInt(-(subtaskIndex + 1)); } else { dos.writeInt(subtaskIndex); } } @Override protected void serializeSubtaskState(OperatorSubtaskState subtaskState, DataOutputStream dos) throws IOException { super.serializeSubtaskState(subtaskState, dos); serializeCollection( subtaskState.getInputChannelState(), dos, this::serializeInputChannelStateHandle); serializeCollection( subtaskState.getResultSubpartitionState(), dos, this::serializeResultSubpartitionStateHandle); } @Override protected OperatorState deserializeOperatorState( DataInputStream dis, @Nullable DeserializationContext context) throws IOException { final OperatorID jobVertexId = new OperatorID(dis.readLong(), dis.readLong()); final int parallelism = dis.readInt(); final int maxParallelism = dis.readInt(); ByteStreamStateHandle coordinateState = deserializeAndCheckByteStreamStateHandle(dis, context); final int numSubTaskStates = dis.readInt(); if (numSubTaskStates < 0) { checkState( coordinateState == null, "Coordinator State should be null for fully finished operator state"); return new FullyFinishedOperatorState(jobVertexId, parallelism, maxParallelism); } final OperatorState operatorState = new OperatorState(jobVertexId, parallelism, maxParallelism); // Coordinator state operatorState.setCoordinatorState(coordinateState); // Sub task states for (int j = 0; j < numSubTaskStates; j++) { SubtaskAndFinishedState subtaskAndFinishedState = deserializeSubtaskIndexAndFinishedState(dis); if (subtaskAndFinishedState.isFinished) { operatorState.putState( subtaskAndFinishedState.subtaskIndex, FinishedOperatorSubtaskState.INSTANCE); } else { final OperatorSubtaskState subtaskState = deserializeSubtaskState(dis, context); operatorState.putState(subtaskAndFinishedState.subtaskIndex, subtaskState); } } return operatorState; } private SubtaskAndFinishedState deserializeSubtaskIndexAndFinishedState(DataInputStream dis) throws IOException { int storedSubtaskIndex = dis.readInt(); if (storedSubtaskIndex < 0) { return new SubtaskAndFinishedState(-storedSubtaskIndex - 1, true); } else { return new SubtaskAndFinishedState(storedSubtaskIndex, false); } } @VisibleForTesting @Override public void serializeResultSubpartitionStateHandle( ResultSubpartitionStateHandle handle, DataOutputStream dos) throws IOException { channelStateHandleSerializer.serialize(handle, dos); } @VisibleForTesting @Override public StateObjectCollection deserializeResultSubpartitionStateHandle( DataInputStream dis, @Nullable DeserializationContext context) throws IOException { return deserializeCollection( dis, context, channelStateHandleSerializer::deserializeResultSubpartitionStateHandle); } @VisibleForTesting @Override public void serializeInputChannelStateHandle( InputChannelStateHandle handle, DataOutputStream dos) throws IOException { channelStateHandleSerializer.serialize(handle, dos); } @VisibleForTesting @Override public StateObjectCollection deserializeInputChannelStateHandle( DataInputStream dis, @Nullable DeserializationContext context) throws IOException { return deserializeCollection( dis, context, channelStateHandleSerializer::deserializeInputChannelStateHandle); } private void serializeCollection( StateObjectCollection stateObjectCollection, DataOutputStream dos, BiConsumerWithException cons) throws IOException { if (stateObjectCollection == null) { dos.writeInt(0); } else { dos.writeInt(stateObjectCollection.size()); for (T stateObject : stateObjectCollection) { cons.accept(stateObject, dos); } } } // ------------------------------------------------------------------------ // exposed static methods for test cases // // NOTE: The fact that certain tests directly call these lower level // serialization methods is a problem, because that way the tests // bypass the versioning scheme. Especially tests that test for // cross-version compatibility need to version themselves if we // ever break the format of these low level state types. // ------------------------------------------------------------------------ @VisibleForTesting public static void serializeStreamStateHandle( StreamStateHandle stateHandle, DataOutputStream dos) throws IOException { MetadataV2V3SerializerBase.serializeStreamStateHandle(stateHandle, dos); } @VisibleForTesting public static StreamStateHandle deserializeStreamStateHandle(DataInputStream dis) throws IOException { return MetadataV2V3SerializerBase.deserializeStreamStateHandle(dis, null); } @VisibleForTesting public static void serializeOperatorStateHandleUtil( OperatorStateHandle stateHandle, DataOutputStream dos) throws IOException { INSTANCE.serializeOperatorStateHandle(stateHandle, dos); } @VisibleForTesting public static OperatorStateHandle deserializeOperatorStateHandleUtil(DataInputStream dis) throws IOException { return INSTANCE.deserializeOperatorStateHandle(dis, null); } @VisibleForTesting public static void serializeKeyedStateHandleUtil( KeyedStateHandle stateHandle, DataOutputStream dos) throws IOException { INSTANCE.serializeKeyedStateHandle(stateHandle, dos); } @VisibleForTesting public static KeyedStateHandle deserializeKeyedStateHandleUtil(DataInputStream dis) throws IOException { return INSTANCE.deserializeKeyedStateHandle(dis, null); } @VisibleForTesting public static StateObjectCollection deserializeInputChannelStateHandle( DataInputStream dis) throws IOException { return INSTANCE.deserializeInputChannelStateHandle(dis, null); } @VisibleForTesting public StateObjectCollection deserializeResultSubpartitionStateHandle(DataInputStream dis) throws IOException { return INSTANCE.deserializeResultSubpartitionStateHandle(dis, null); } private static class SubtaskAndFinishedState { final int subtaskIndex; final boolean isFinished; public SubtaskAndFinishedState(int subtaskIndex, boolean isFinished) { this.subtaskIndex = subtaskIndex; this.isFinished = isFinished; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy