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

org.apache.flink.runtime.state.gemini.engine.snapshot.SnapshotManager Maven / Gradle / Ivy

There is a newer version: 1.5.1
Show 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.gemini.engine.snapshot;

import org.apache.flink.annotation.VisibleForTesting;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.core.fs.Path;
import org.apache.flink.runtime.state.gemini.engine.GRegionContext;
import org.apache.flink.runtime.state.gemini.engine.GRegionID;
import org.apache.flink.runtime.state.gemini.engine.filecache.PageBatchFlusher;
import org.apache.flink.runtime.state.gemini.engine.page.PageIndex;

import javax.annotation.Nullable;

import java.io.Closeable;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;

/**
 * SnapshotManager.
 */
public interface SnapshotManager extends Closeable {

	/**
	 * Whether we need to break the lineage. If we need to break the lineage,
	 * e.g. rescaling case, we would not remember any parental lineage information
	 * and ensure all data must go into newer snapshot to not depend any older snapshots.
	 * In a nutshell, when need to break the lineage, that snapshot cannot be a incremental one.
	 */
	boolean isNeedToBreakLineage();

	void setNeedToBreakLineage(boolean needToBreakLineage);

	/**
	 * synchronously method, start a snapshot, will submit a SnapshotHandler to asynchronously run.
	 */
	Future startSnapshot(BackendSnapshotMeta backendSnapshotMeta);

	/**
	 * complete snapshot successfully or exceptionally.
	 * @param throwable The throwable for exceptionally complete, and null for successfully.
	 */
	void endSnapshot(long checkpointId, Throwable throwable);

	/**
	 * finally result of snapshot.
	 */
	@Nullable
	PendingSnapshot getPendingSnapshot(long checkpointId);

	/**
	 * Returns the namespace of this snapshot manager.
	 *
	 * 

Namespace acts as an unique id of this snapshot manager. * All snapshots generated by this snapshot manager should have the same namespace. * When restoring, Gemini would use namespace to judge whether this should flush all pages when executing first checkpoint. * * @return The namespace of this snapshot manager. */ String getNameSpace(); /** * Min access number of running snapshot. */ long getMinRunningSnapshotAccessNumber(); /** * Get the executorService for snapshot. */ ExecutorService getSnapshotExecutor(); /** * This method is called as a notification once a distributed checkpoint has been completed. */ void notifySnapshotComplete(long snapshotID); /** * This method is called as a notification once a distributed checkpoint has been aborted. */ void notifySnapshotAbort(long snapshotID); /** * This method is called as a notification once a distributed checkpoint has been subsumed. */ void notifySnapshotSubsume(long snapshotID); /** * Restore all snapshots according to the snapshot which DB is restored. * * @param snapshotId snapshot which db is restored from. * @param fileMapping file mapping db is restored from. * @param restoredBasePath db base path the snapshot used. * @return all snapshots restored. */ Map restore(long snapshotId, Map fileMapping, String restoredBasePath); /** * snapshot result. */ class PendingSnapshot { long checkpointId; long timestamp; SnapshotCompletableFuture resultFuture; // table name -> region id -> region meta private final Map> regionSnapshotMetas; Path snapshotBasePath; Path snapshotMetaPath; @Nullable Path localSnapshotBasePath; @Nullable Path localSnapshotMetaPath; // mapping table for dfs snapshot. Map>> fileMapping; // mapping table for local snapshot. @Nullable Map>> localFileMapping; long accessNumber; SnapshotOperation snapshotOperation; SnapshotCompaction snapshotCompaction; private final SnapshotStat snapshotStat; private boolean isCanceled; private DBSnapshotResult dbSnapshotResult; private CompletableFuture dbSnapshotResultFuture; /** * This flusher can only be used in {@link SnapshotManagerImpl#snapshotExecutor} * so that it's guaranteed to thread safety. */ private PageBatchFlusher dfsPageBatchFlusher ; public PendingSnapshot( long checkpointId, long timestamp, SnapshotCompletableFuture resultFuture, Path snapshotBasePath, Path snapshotMetaPath, Path localSnapshotBasePath, Path localSnapshotMetaPath, long accessNumber, SnapshotOperation snapshotOperation, PageBatchFlusher dfsPageBatchFlusher) { this.checkpointId = checkpointId; this.timestamp = timestamp; this.resultFuture = resultFuture; this.snapshotBasePath = snapshotBasePath; this.snapshotMetaPath = snapshotMetaPath; this.localSnapshotBasePath = localSnapshotBasePath; this.localSnapshotMetaPath = localSnapshotMetaPath; this.accessNumber = accessNumber; this.snapshotOperation = snapshotOperation; this.regionSnapshotMetas = new ConcurrentHashMap<>(); this.snapshotStat = new SnapshotStat(); this.isCanceled = false; this.snapshotCompaction = NoSnapshotCompaction.INSTANCE; this.dfsPageBatchFlusher = dfsPageBatchFlusher; this.dbSnapshotResultFuture = new CompletableFuture<>(); } public long getCheckpointId() { return checkpointId; } public long getTimestamp() { return timestamp; } public SnapshotCompletableFuture getResultFuture() { return resultFuture; } public Path getSnapshotBasePath() { return snapshotBasePath; } public Path getSnapshotMetaPath() { return snapshotMetaPath; } public Path getLocalSnapshotBasePath() { return localSnapshotBasePath; } public Path getLocalSnapshotMetaPath() { return localSnapshotMetaPath; } public long getAccessNumber() { return accessNumber; } public SnapshotOperation getSnapshotOperation() { return snapshotOperation; } public SnapshotCompaction getSnapshotCompaction() { return snapshotCompaction; } public void setSnapshotCompaction(SnapshotCompaction snapshotCompaction) { this.snapshotCompaction = snapshotCompaction; } public void addGRegionSnapshotMeta( GRegionContext gRegionContext, PageIndex pageIndex) { regionSnapshotMetas.computeIfAbsent(gRegionContext.getTableName(), (nothing) -> new ConcurrentHashMap<>()) .put(gRegionContext.getRegionId(), new GRegionSnapshotMeta( gRegionContext, pageIndex, gRegionContext.getLastSeqId(), gRegionContext.getRemoveAllSeqId())); } public Map> getGRegionSnapshotMeta() { return regionSnapshotMetas; } public void setFileMapping(Map>> fileMapping) { this.fileMapping = fileMapping; } public Map>> getFileMapping() { return fileMapping; } public void setLocalFileMapping(Map>> localFileMapping) { this.localFileMapping = localFileMapping; } public Map>> getLocalFileMapping() { return localFileMapping; } public SnapshotStat getSnapshotStat() { return snapshotStat; } public PageBatchFlusher getDfsPageBatchFlusher() { return dfsPageBatchFlusher; } public void releaseResource() { regionSnapshotMetas.clear(); if (fileMapping != null) { fileMapping.clear(); } if (localFileMapping != null) { localFileMapping.clear(); } } public DBSnapshotResult getDbSnapshotResult() { return dbSnapshotResult; } public void setDbSnapshotResult(DBSnapshotResult dbSnapshotResult) { this.dbSnapshotResult = dbSnapshotResult; } public CompletableFuture getDbSnapshotResultFuture() { return dbSnapshotResultFuture; } public boolean isCanceled() { return isCanceled; } /** * Should only be called when cancelling this pending snapshot. */ @VisibleForTesting void setCanceled(boolean canceled) { isCanceled = canceled; } } /** * Snapshot meta for region. */ class GRegionSnapshotMeta { private GRegionContext gRegionContext; private PageIndex pageIndex; private long lastSeqID; private long removeAllSeqID; GRegionSnapshotMeta( GRegionContext gRegionContext, PageIndex pageIndex, long lastSeqID, long removeAllSeqID) { this.gRegionContext = gRegionContext; this.pageIndex = pageIndex; this.lastSeqID = lastSeqID; this.removeAllSeqID = removeAllSeqID; } public GRegionContext getGRegionContext() { return gRegionContext; } public PageIndex getPageIndex() { return pageIndex; } public long getLastSeqID() { return lastSeqID; } public long getRemoveAllSeqID() { return removeAllSeqID; } } /** * Completed snapshot information. */ class CompletedSnapshot { private final long checkpointID; private final String metaFilePath; private final Set dataFileIDs; public CompletedSnapshot( long checkpointID, String metaFilePath, Set dataFileIDs) { this.checkpointID = checkpointID; this.metaFilePath = metaFilePath; this.dataFileIDs = dataFileIDs; } public long getCheckpointID() { return checkpointID; } public String getMetaFilePath() { return metaFilePath; } public Set getDataFileIDs() { return dataFileIDs; } @Override public int hashCode() { return Objects.hash(checkpointID, metaFilePath, dataFileIDs); } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } CompletedSnapshot that = (CompletedSnapshot) o; return checkpointID == that.checkpointID && metaFilePath.equals(that.metaFilePath) && dataFileIDs.equals(that.dataFileIDs); } } /** * Meta for a restored snapshot. */ class RestoredSnapshot { private final long checkpointID; private final String metaFilePath; private final Map fileMapping; public RestoredSnapshot( long checkpointID, String metaFilePath, Map fileMapping) { this.checkpointID = checkpointID; this.metaFilePath = metaFilePath; this.fileMapping = fileMapping; } public long getCheckpointID() { return checkpointID; } public String getMetaFilePath() { return metaFilePath; } public Map getFileMapping() { return fileMapping; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy