Skip to content

Commit d3ac669

Browse files
authored
fix(interactive): invalidate query cache after schema update (#4486)
<!-- Thanks for your contribution! please review https://github.com/alibaba/GraphScope/blob/main/CONTRIBUTING.md before opening an issue. --> ## What do these changes do? as titled. <!-- Please give a short brief about these changes. --> ## Related issue number <!-- Are there any issues opened that will be resolved by merging this change? --> Fixes #4483
1 parent ab137ac commit d3ac669

File tree

28 files changed

+234
-127
lines changed

28 files changed

+234
-127
lines changed

interactive_engine/compiler/src/main/java/com/alibaba/graphscope/GraphServer.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import com.alibaba.graphscope.gremlin.integration.result.GraphProperties;
4242
import com.alibaba.graphscope.gremlin.integration.result.TestGraphFactory;
4343
import com.alibaba.graphscope.gremlin.service.IrGremlinServer;
44+
import com.google.common.collect.ImmutableList;
4445
import com.google.common.collect.ImmutableMap;
4546
import com.google.common.io.Resources;
4647

@@ -56,6 +57,7 @@
5657
import java.nio.file.Files;
5758
import java.nio.file.Path;
5859
import java.nio.file.Paths;
60+
import java.util.List;
5961

6062
public class GraphServer {
6163
private static final Logger logger = LoggerFactory.getLogger(GraphServer.class);
@@ -65,6 +67,7 @@ public class GraphServer {
6567
private final GraphProperties testGraph;
6668
private final GraphRelOptimizer optimizer;
6769
private final MetricsTool metricsTool;
70+
private final QueryCache queryCache;
6871

6972
private IrGremlinServer gremlinServer;
7073
private CypherBootstrapper cypherBootstrapper;
@@ -74,21 +77,22 @@ public GraphServer(
7477
ChannelFetcher channelFetcher,
7578
IrMetaQueryCallback metaQueryCallback,
7679
GraphProperties testGraph,
77-
GraphRelOptimizer optimizer) {
80+
GraphRelOptimizer optimizer,
81+
QueryCache queryCache) {
7882
this.configs = configs;
7983
this.channelFetcher = channelFetcher;
8084
this.metaQueryCallback = metaQueryCallback;
8185
this.testGraph = testGraph;
8286
this.optimizer = optimizer;
8387
this.metricsTool = new MetricsTool(configs);
8488
this.metricsTool.registerMetric(new MemoryMetric());
89+
this.queryCache = queryCache;
8590
}
8691

8792
public void start() throws Exception {
8893
ExecutionClient executionClient =
8994
ExecutionClient.Factory.create(configs, channelFetcher, metricsTool);
9095
QueryIdGenerator idGenerator = new QueryIdGenerator(configs);
91-
QueryCache queryCache = new QueryCache(configs);
9296
if (!FrontendConfig.GREMLIN_SERVER_DISABLED.get(configs)) {
9397
GraphPlanner graphPlanner =
9498
new GraphPlanner(configs, new LogicalPlanFactory.Gremlin(), optimizer);
@@ -177,19 +181,22 @@ public static void main(String[] args) throws Exception {
177181
}
178182
Configs configs = Configs.Factory.create(args[0]);
179183
GraphRelOptimizer optimizer = new GraphRelOptimizer(configs);
184+
QueryCache queryCache = new QueryCache(configs);
180185
IrMetaQueryCallback queryCallback =
181-
new IrMetaQueryCallback(createIrMetaFetcher(configs, optimizer.getGlogueHolder()));
186+
new IrMetaQueryCallback(
187+
createIrMetaFetcher(configs, ImmutableList.of(optimizer, queryCache)));
182188
GraphServer server =
183189
new GraphServer(
184190
configs,
185191
getChannelFetcher(configs),
186192
queryCallback,
187193
getTestGraph(configs),
188-
optimizer);
194+
optimizer,
195+
queryCache);
189196
server.start();
190197
}
191198

192-
private static IrMetaFetcher createIrMetaFetcher(Configs configs, IrMetaTracker tracker)
199+
private static IrMetaFetcher createIrMetaFetcher(Configs configs, List<IrMetaTracker> tracker)
193200
throws IOException {
194201
URI schemaUri = URI.create(GraphConfig.GRAPH_META_SCHEMA_URI.get(configs));
195202
if (schemaUri.getScheme() == null || schemaUri.getScheme().equals("file")) {

interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/meta/IrMetaTracker.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,7 @@
2020

2121
// This interface defines the callback to be invoked when IrMeta changes.
2222
public interface IrMetaTracker {
23-
void onChanged(IrMeta meta);
23+
void onSchemaChanged(IrMeta meta);
24+
25+
void onStatsChanged(IrMetaStats stats);
2426
}

interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/meta/fetcher/DynamicIrMetaFetcher.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,13 @@
2626
import com.alibaba.graphscope.common.ir.meta.IrMetaStats;
2727
import com.alibaba.graphscope.common.ir.meta.IrMetaTracker;
2828
import com.alibaba.graphscope.common.ir.meta.reader.IrMetaReader;
29+
import com.alibaba.graphscope.common.ir.meta.schema.SchemaSpec;
2930
import com.alibaba.graphscope.groot.common.schema.api.GraphStatistics;
3031

3132
import org.slf4j.Logger;
3233
import org.slf4j.LoggerFactory;
3334

35+
import java.util.List;
3436
import java.util.Optional;
3537
import java.util.concurrent.ScheduledExecutorService;
3638
import java.util.concurrent.ScheduledThreadPoolExecutor;
@@ -48,7 +50,8 @@ public class DynamicIrMetaFetcher extends IrMetaFetcher implements AutoCloseable
4850
private volatile StatsState statsState;
4951
private volatile Boolean statsEnabled = null;
5052

51-
public DynamicIrMetaFetcher(Configs configs, IrMetaReader dataReader, IrMetaTracker tracker) {
53+
public DynamicIrMetaFetcher(
54+
Configs configs, IrMetaReader dataReader, List<IrMetaTracker> tracker) {
5255
super(dataReader, tracker);
5356
this.scheduler = new ScheduledThreadPoolExecutor(1);
5457
long schemaIntervalMS = GraphConfig.GRAPH_META_SCHEMA_FETCH_INTERVAL_MS.get(configs);
@@ -93,6 +96,12 @@ private synchronized void syncMeta() {
9396
meta.getSchema(),
9497
meta.getStoredProcedures(),
9598
null);
99+
if (logger.isDebugEnabled()) {
100+
logger.debug(
101+
"sync schema with {}",
102+
meta.getSchema().getSchemaSpec(SchemaSpec.Type.FLEX_IN_YAML));
103+
}
104+
tracker.forEach(t -> t.onSchemaChanged(this.currentState));
96105
}
97106
boolean statsEnabled = getStatsEnabled(this.currentState.getGraphId());
98107
if (statsEnabled && this.statsState != StatsState.SYNCED
@@ -135,7 +144,7 @@ private synchronized void syncStats() {
135144
stats);
136145
if (tracker != null) {
137146
logger.info("start to update the glogue");
138-
tracker.onChanged(this.currentState);
147+
tracker.forEach(t -> t.onStatsChanged(this.currentState));
139148
}
140149
this.statsState = StatsState.SYNCED;
141150
}
@@ -149,7 +158,7 @@ private synchronized void syncStats() {
149158
&& tracker != null
150159
&& this.statsState == StatsState.INITIALIZED) {
151160
logger.info("start to mock the glogue");
152-
tracker.onChanged(this.currentState);
161+
tracker.forEach(t -> t.onStatsChanged(this.currentState));
153162
this.statsState = StatsState.MOCKED;
154163
}
155164
} catch (Throwable t) {

interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/meta/fetcher/IrMetaFetcher.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.alibaba.graphscope.common.ir.meta.IrMetaTracker;
2323
import com.alibaba.graphscope.common.ir.meta.reader.IrMetaReader;
2424

25+
import java.util.List;
2526
import java.util.Optional;
2627

2728
/**
@@ -31,9 +32,9 @@
3132
*/
3233
public abstract class IrMetaFetcher {
3334
protected final IrMetaReader reader;
34-
protected final IrMetaTracker tracker;
35+
protected final List<IrMetaTracker> tracker;
3536

36-
protected IrMetaFetcher(IrMetaReader reader, IrMetaTracker tracker) {
37+
protected IrMetaFetcher(IrMetaReader reader, List<IrMetaTracker> tracker) {
3738
this.reader = reader;
3839
this.tracker = tracker;
3940
}

interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/meta/fetcher/StaticIrMetaFetcher.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,31 @@
2929
import org.slf4j.LoggerFactory;
3030

3131
import java.io.IOException;
32+
import java.util.List;
3233
import java.util.Optional;
3334

3435
public class StaticIrMetaFetcher extends IrMetaFetcher {
3536
private static final Logger logger = LoggerFactory.getLogger(StaticIrMetaFetcher.class);
3637
private final IrMetaStats metaStats;
3738

38-
public StaticIrMetaFetcher(IrMetaReader dataReader, IrMetaTracker tracker) throws IOException {
39+
public StaticIrMetaFetcher(IrMetaReader dataReader, List<IrMetaTracker> tracker)
40+
throws IOException {
3941
super(dataReader, tracker);
4042
IrMeta meta = this.reader.readMeta();
41-
GraphStatistics stats = (meta == null) ? null : fetchStats(meta);
43+
tracker.forEach(t -> t.onSchemaChanged(meta));
44+
GraphStatistics stats = null;
45+
if (meta != null) {
46+
try {
47+
stats = fetchStats(meta);
48+
} catch (Exception e) {
49+
logger.error("failed to fetch graph statistics, error is {}", e);
50+
}
51+
}
4252
this.metaStats =
4353
new IrMetaStats(
4454
meta.getSnapshotId(), meta.getSchema(), meta.getStoredProcedures(), stats);
4555
if (tracker != null && stats != null) {
46-
tracker.onChanged(this.metaStats);
56+
tracker.forEach(t -> t.onStatsChanged(this.metaStats));
4757
}
4858
}
4959

interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/planner/GlogueHolder.java

Lines changed: 0 additions & 58 deletions
This file was deleted.

interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/planner/GraphHepPlanner.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@
55
import com.alibaba.graphscope.common.ir.rel.graph.*;
66
import com.alibaba.graphscope.common.ir.rel.graph.match.GraphLogicalMultiMatch;
77
import com.alibaba.graphscope.common.ir.rel.graph.match.GraphLogicalSingleMatch;
8+
import com.alibaba.graphscope.gremlin.Utils;
89

10+
import org.apache.calcite.plan.RelDigest;
911
import org.apache.calcite.plan.RelOptTable;
1012
import org.apache.calcite.plan.hep.HepPlanner;
1113
import org.apache.calcite.plan.hep.HepProgram;
14+
import org.apache.calcite.plan.hep.HepRelVertex;
1215
import org.apache.calcite.rel.RelNode;
1316
import org.apache.calcite.rel.logical.LogicalFilter;
1417
import org.apache.calcite.rel.logical.LogicalJoin;
@@ -20,6 +23,7 @@
2023
import org.checkerframework.checker.nullness.qual.Nullable;
2124

2225
import java.util.IdentityHashMap;
26+
import java.util.Map;
2327

2428
/**
2529
* Original {@code HepPlanner} skip optimizations to the nested structures, i.e. {@code RelNode} nested in the {@code CommonTableScan} or {@code RexSubQuery},
@@ -173,4 +177,12 @@ private RelNode findBestIfRoot(RelNode oldRel, RelNode newRel) {
173177
return oldRel == root ? findBestExpOfRoot(newRel) : newRel;
174178
}
175179
}
180+
181+
@Override
182+
public void clear() {
183+
super.clear();
184+
Map<RelDigest, HepRelVertex> mapDigestToVertex =
185+
Utils.getFieldValue(HepPlanner.class, this, "mapDigestToVertex");
186+
mapDigestToVertex.clear();
187+
}
176188
}

interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/planner/GraphRelOptimizer.java

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,18 @@
1919
import com.alibaba.graphscope.common.config.Configs;
2020
import com.alibaba.graphscope.common.config.PlannerConfig;
2121
import com.alibaba.graphscope.common.ir.meta.IrMeta;
22+
import com.alibaba.graphscope.common.ir.meta.IrMetaStats;
23+
import com.alibaba.graphscope.common.ir.meta.IrMetaTracker;
2224
import com.alibaba.graphscope.common.ir.meta.glogue.calcite.GraphRelMetadataQuery;
2325
import com.alibaba.graphscope.common.ir.meta.glogue.calcite.handler.GraphMetadataHandlerProvider;
2426
import com.alibaba.graphscope.common.ir.rel.GraphShuttle;
2527
import com.alibaba.graphscope.common.ir.rel.graph.GraphLogicalSource;
2628
import com.alibaba.graphscope.common.ir.rel.graph.match.AbstractLogicalMatch;
2729
import com.alibaba.graphscope.common.ir.rel.graph.match.GraphLogicalMultiMatch;
2830
import com.alibaba.graphscope.common.ir.rel.graph.match.GraphLogicalSingleMatch;
31+
import com.alibaba.graphscope.common.ir.rel.metadata.glogue.Glogue;
2932
import com.alibaba.graphscope.common.ir.rel.metadata.glogue.GlogueQuery;
33+
import com.alibaba.graphscope.common.ir.rel.metadata.schema.GlogueSchema;
3034
import com.alibaba.graphscope.common.ir.tools.GraphBuilderFactory;
3135
import com.alibaba.graphscope.common.ir.tools.config.GraphOpt;
3236
import com.google.common.base.Preconditions;
@@ -43,28 +47,33 @@
4347
import org.apache.calcite.rel.metadata.RelMetadataQuery;
4448
import org.apache.calcite.tools.RelBuilderFactory;
4549
import org.checkerframework.checker.nullness.qual.Nullable;
50+
import org.slf4j.Logger;
51+
import org.slf4j.LoggerFactory;
4652

4753
import java.io.Closeable;
4854
import java.util.List;
4955
import java.util.concurrent.atomic.AtomicBoolean;
56+
import java.util.concurrent.atomic.AtomicReference;
5057

5158
/**
5259
* Optimize graph relational tree which consists of match and other relational operators
5360
*/
54-
public class GraphRelOptimizer implements Closeable {
61+
public class GraphRelOptimizer implements Closeable, IrMetaTracker {
62+
private static final Logger logger = LoggerFactory.getLogger(GraphRelOptimizer.class);
5563
private final PlannerConfig config;
5664
private final RelBuilderFactory relBuilderFactory;
57-
private final GlogueHolder glogueHolder;
5865
private final PlannerGroupManager plannerGroupManager;
5966

67+
private final AtomicReference<GlogueQuery> glogueRef;
68+
6069
public GraphRelOptimizer(Configs graphConfig, Class<? extends PlannerGroupManager> instance) {
6170
try {
6271
this.config = new PlannerConfig(graphConfig);
6372
this.relBuilderFactory = new GraphBuilderFactory(graphConfig);
64-
this.glogueHolder = new GlogueHolder(graphConfig);
6573
this.plannerGroupManager =
6674
instance.getDeclaredConstructor(PlannerConfig.class, RelBuilderFactory.class)
6775
.newInstance(this.config, this.relBuilderFactory);
76+
this.glogueRef = new AtomicReference<>();
6877
} catch (Exception e) {
6978
throw new RuntimeException(e);
7079
}
@@ -74,10 +83,6 @@ public GraphRelOptimizer(Configs graphConfig) {
7483
this(graphConfig, PlannerGroupManager.Dynamic.class);
7584
}
7685

77-
public GlogueHolder getGlogueHolder() {
78-
return glogueHolder;
79-
}
80-
8186
public RelOptPlanner getMatchPlanner() {
8287
PlannerGroup currentGroup = this.plannerGroupManager.getCurrentGroup();
8388
return currentGroup.getMatchPlanner();
@@ -90,7 +95,7 @@ public RelNode optimize(RelNode before, GraphIOProcessor ioProcessor) {
9095

9196
public @Nullable RelMetadataQuery createMetaDataQuery(IrMeta irMeta) {
9297
if (config.isOn() && config.getOpt() == PlannerConfig.Opt.CBO) {
93-
GlogueQuery gq = this.glogueHolder.getGlogue();
98+
GlogueQuery gq = this.glogueRef.get();
9499
Preconditions.checkArgument(gq != null, "glogue is not ready");
95100
return new GraphRelMetadataQuery(
96101
new GraphMetadataHandlerProvider(getMatchPlanner(), gq, this.config));
@@ -105,6 +110,21 @@ public void close() {
105110
}
106111
}
107112

113+
@Override
114+
public void onSchemaChanged(IrMeta meta) {
115+
if (this.plannerGroupManager != null) {
116+
this.plannerGroupManager.clean();
117+
}
118+
}
119+
120+
@Override
121+
public void onStatsChanged(IrMetaStats stats) {
122+
GlogueSchema g = GlogueSchema.fromMeta(stats);
123+
Glogue gl = new Glogue(g, config.getGlogueSize());
124+
GlogueQuery gq = new GlogueQuery(gl);
125+
this.glogueRef.compareAndSet(glogueRef.get(), gq);
126+
}
127+
108128
public static class MatchOptimizer extends GraphShuttle {
109129
private final GraphIOProcessor ioProcessor;
110130
private final RelOptPlanner matchPlanner;

interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/planner/PlannerGroup.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ public synchronized void clear() {
188188
this.matchPlanner.addRule(rule);
189189
}
190190
List<RelOptRule> physicalRBORules = this.physicalPlanner.getRules();
191-
this.physicalPlanner.clear();
191+
physicalPlanner.clear();
192192
for (RelOptRule rule : physicalRBORules) {
193193
this.physicalPlanner.addRule(rule);
194194
}

0 commit comments

Comments
 (0)