Skip to content

Commit

Permalink
Let snapshot saved disk same as rocksdb data path (#1392)
Browse files Browse the repository at this point in the history
* The goal is to ensure that snapshots can be generated in hard link
* Add create and resume snapshot API
* Use checkpoint when resume snapshot
* Refactor some code in RocksDBStdSessions

Change-Id: I88b39003107652f6ff8eae071e88dc888dd21959
  • Loading branch information
Linary authored Apr 1, 2021
1 parent c0dff5b commit 39b9474
Show file tree
Hide file tree
Showing 23 changed files with 565 additions and 295 deletions.
2 changes: 1 addition & 1 deletion hugegraph-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@
</addDefaultSpecificationEntries>
</manifest>
<manifestEntries>
<Implementation-Version>0.59.0.0</Implementation-Version>
<Implementation-Version>0.60.0.0</Implementation-Version>
</manifestEntries>
</archive>
</configuration>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,34 @@ public void clear(@Context GraphManager manager,
g.truncateBackend();
}

@PUT
@Timed
@Path("{name}/snapshot_create")
@Produces(APPLICATION_JSON_WITH_CHARSET)
@RolesAllowed({"admin", "$owner=$name"})
public Object createSnapshot(@Context GraphManager manager,
@PathParam("name") String name) {
LOG.debug("Create snapshot for graph '{}'", name);

HugeGraph g = graph(manager, name);
g.createSnapshot();
return ImmutableMap.of(name, "snapshot_created");
}

@PUT
@Timed
@Path("{name}/snapshot_resume")
@Produces(APPLICATION_JSON_WITH_CHARSET)
@RolesAllowed({"admin", "$owner=$name"})
public Object resumeSnapshot(@Context GraphManager manager,
@PathParam("name") String name) {
LOG.debug("Resume snapshot for graph '{}'", name);

HugeGraph g = graph(manager, name);
g.resumeSnapshot();
return ImmutableMap.of(name, "snapshot_resumed");
}

@PUT
@Timed
@Path("{name}/mode")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,18 @@ public void truncateBackend() {
}
}

@Override
public void createSnapshot() {
this.verifyPermission(HugePermission.WRITE, ResourceType.STATUS);
this.hugegraph.createSnapshot();
}

@Override
public void resumeSnapshot() {
this.verifyPermission(HugePermission.WRITE, ResourceType.STATUS);
this.hugegraph.resumeSnapshot();
}

private void verifyAdminPermission() {
verifyPermission(HugePermission.ANY, ResourceType.ROOT);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,11 @@ public final class ApiVersion {
* [0.58] Issue-1173: Supports customized kout/kneighbor,
* multi-node-shortest-path, jaccard-similar and template-paths
* [0.59] Issue-1333: Support graph read mode for olap property
* [0.60] Issue-1392: Support create and resume snapshot
*/

// The second parameter of Version.of() is for IDE running without JAR
public static final Version VERSION = Version.of(ApiVersion.class, "0.59");
public static final Version VERSION = Version.of(ApiVersion.class, "0.60");

public static final void check() {
// Check version of hugegraph-core. Firstly do check from version 0.3
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,9 @@ public interface HugeGraph extends Graph {
public void clearBackend();
public void truncateBackend();

public void createSnapshot();
public void resumeSnapshot();

@Override
public HugeFeatures features();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -360,14 +360,36 @@ public void truncateBackend() {
* When restarting, load the snapshot first and then read backend,
* will not encounter such an intermediate state.
*/
this.storeProvider.writeSnapshot();
this.storeProvider.createSnapshot();
} finally {
LockUtil.unlock(this.name, LockUtil.GRAPH_LOCK);
}

LOG.info("Graph '{}' has been truncated", this.name);
}

@Override
public void createSnapshot() {
LockUtil.lock(this.name, LockUtil.GRAPH_LOCK);
try {
this.storeProvider.createSnapshot();
} finally {
LockUtil.unlock(this.name, LockUtil.GRAPH_LOCK);
}
LOG.info("Graph '{}' has created snapshot", this.name);
}

@Override
public void resumeSnapshot() {
LockUtil.lock(this.name, LockUtil.GRAPH_LOCK);
try {
this.storeProvider.resumeSnapshot();
} finally {
LockUtil.unlock(this.name, LockUtil.GRAPH_LOCK);
}
LOG.info("Graph '{}' has resumed from snapshot", this.name);
}

private SchemaTransaction openSchemaTransaction() throws HugeException {
this.checkGraphNotClosed();
try {
Expand Down Expand Up @@ -1424,7 +1446,7 @@ public void invalid2(HugeType type, Object[] ids) {

@Override
public void clear(HugeType type) {
this.hub.notify(Events.CACHE, Cache.ACTION_CLEAR, type, null);
this.hub.notify(Events.CACHE, Cache.ACTION_CLEAR, type);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

import com.baidu.hugegraph.HugeGraph;
import com.baidu.hugegraph.backend.BackendException;
import com.baidu.hugegraph.backend.store.raft.StoreSnapshotFile;
import com.baidu.hugegraph.event.EventHub;
import com.baidu.hugegraph.event.EventListener;
import com.baidu.hugegraph.util.E;
Expand Down Expand Up @@ -151,13 +152,19 @@ public void initSystemInfo(HugeGraph graph) {
}

@Override
public void writeSnapshot() {
// TODO: to be implemented
public void createSnapshot() {
String snapshotPrefix = StoreSnapshotFile.SNAPSHOT_DIR;
for (BackendStore store : this.stores.values()) {
store.createSnapshot(snapshotPrefix);
}
}

@Override
public void readSnapshot() {
// TODO: to be implemented
public void resumeSnapshot() {
String snapshotPrefix = StoreSnapshotFile.SNAPSHOT_DIR;
for (BackendStore store : this.stores.values()) {
store.resumeSnapshot(snapshotPrefix, true);
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ public default boolean supportsSharedStorage() {
return true;
}

public default boolean supportsSnapshot() {
return false;
}

public boolean supportsScanToken();

public boolean supportsScanKeyPrefix();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package com.baidu.hugegraph.backend.store;

import java.util.Iterator;
import java.util.Set;

import com.baidu.hugegraph.backend.id.Id;
import com.baidu.hugegraph.backend.id.IdGenerator;
Expand Down Expand Up @@ -116,12 +117,13 @@ public default void setCounterLowest(HugeType type, long lowest) {
// Get current counter for a specific type
public long getCounter(HugeType type);

public default void writeSnapshot(String snapshotPath) {
throw new UnsupportedOperationException("writeSnapshot");
public default Set<String> createSnapshot(String snapshotDir) {
throw new UnsupportedOperationException("createSnapshot");
}

public default void readSnapshot(String snapshotPath) {
throw new UnsupportedOperationException("readSnapshot");
public default void resumeSnapshot(String snapshotDir,
boolean deleteSnapshot) {
throw new UnsupportedOperationException("resumeSnapshot");
}

static enum TxState {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ public interface BackendStoreProvider {

public void initSystemInfo(HugeGraph graph);

public void writeSnapshot();
public void createSnapshot();

public void readSnapshot();
public void resumeSnapshot();

public void listen(EventListener listener);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ public void initSystemInfo(HugeGraph graph) {
}

@Override
public void writeSnapshot() {
public void createSnapshot() {
StoreCommand command = new StoreCommand(StoreType.ALL,
StoreAction.SNAPSHOT, null);
StoreClosure closure = new StoreClosure(command);
Expand All @@ -208,8 +208,9 @@ public void writeSnapshot() {
}

@Override
public void readSnapshot() {
// How to read snapshot by jraft explicity?
public void resumeSnapshot() {
// Jraft doesn't expose API to load snapshot
throw new UnsupportedOperationException("resumeSnapshot");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
Expand All @@ -43,6 +44,7 @@
import com.baidu.hugegraph.HugeException;
import com.baidu.hugegraph.HugeGraphParams;
import com.baidu.hugegraph.backend.cache.Cache;
import com.baidu.hugegraph.backend.id.Id;
import com.baidu.hugegraph.backend.store.BackendStore;
import com.baidu.hugegraph.backend.store.raft.rpc.ListPeersProcessor;
import com.baidu.hugegraph.backend.store.raft.rpc.RaftRequests.StoreType;
Expand Down Expand Up @@ -259,7 +261,7 @@ public void clearCache() {
this.notifyCache(Cache.ACTION_CLEAR, HugeType.VERTEX, null);
}

protected void notifyCache(String action, HugeType type, Object id) {
protected void notifyCache(String action, HugeType type, List<Id> ids) {
EventHub eventHub;
if (type.isGraph()) {
eventHub = this.params.graphEventHub();
Expand All @@ -270,7 +272,15 @@ protected void notifyCache(String action, HugeType type, Object id) {
}
try {
// How to avoid update cache from server info
eventHub.notify(Events.CACHE, action, type, id);
if (ids == null) {
eventHub.call(Events.CACHE, action, type);
} else {
if (ids.size() == 1) {
eventHub.call(Events.CACHE, action, type, ids.get(0));
} else {
eventHub.call(Events.CACHE, action, type, ids.toArray());
}
}
} catch (RejectedExecutionException e) {
LOG.warn("Can't update cache due to EventHub is too busy");
}
Expand Down
Loading

0 comments on commit 39b9474

Please sign in to comment.