AWS Neptune 数据库中的多租户
Multi-tenancy in AWS Neptune database
我是海王星的新手。
在 Neptune 数据库中支持多租户的最佳方式是什么?
要求:
1.支持数据库千租户(一个集群)
2. 租户过滤避免查询变得过于复杂
3. 良好的性能(如果有一种方法可以使用数据分区来加快查询时间)
4. 安全 - 很难犯会导致跨租户访问的错误。
在非生产环境中,Gremlin partition strategy 证明对我来说已经足够了。顶点和边共存于同一个 Gremlin 集群中,它们有一个 属性 来区分它们,在我的例子中我使用了 _env
属性。
然后在我的 Java 代码中,每次我请求工厂遍历时,它都使用分区策略。
private GraphTraversalSource buildReadOnlyTraversal() {
log.debug("building read-only traversal");
return AnonymousTraversalSource.traversal()
.withRemote(DriverRemoteConnection.using(getReadOnlyCluster()))
.withStrategies(buildPartitionStrategy(), buildReadOnlyStrategy());
}
private PartitionStrategy buildPartitionStrategy() {
var env = this.properties.getEnvironmentPartition();
log.info("building partition strategy for environment={}", env);
return PartitionStrategy.build()
.partitionKey(ENVIRONMENT_PARTITION_KEY)
.writePartition(env)
.readPartitions(env)
.create();
}
使用这些遍历将自动限定在您的分区范围内。然而,最大的问题是你需要记住在从控制台查询时手动添加对分区的引用(实际上任何不使用分区策略机制的东西)例如
g.V().hasLabel('user').has('_env', 'dev')
我认为这符合您的前 2 个标准,性能我无法真正评论。第 4 点,是的,这不是应用程序代码的问题,手动修改图形时更容易出错。
我已经想出了解决这个问题的方法。我像这样更改了 GraphTraversal 的一些现有功能。
setEnvironment = (g: GraphTraversalSource<GraphTraversal>, ENV: string) => {
const bindGraphTraversal = (t: GraphTraversal): GraphTraversal => {
const V = t.V.bind(t);
const addV = t.addV.bind(t);
const addE = t.addE.bind(t);
t.V = (...args: any[]) => V(...args).has('_env', ENV);
t.addV = (...args: any[]) => addV(...args).property('_env', ENV);
t.addE = (...args: any[]) => addE(...args).property('_env', ENV);
return t;
}
const addV = g.addV.bind(g);
const addE = g.addE.bind(g);
const V = g.V.bind(g);
const E = g.E.bind(g);
g.addV = (...args: any[]) => bindGraphTraversal(addV(...args).property('_env', ENV));
g.addE = (...args: any[]) => bindGraphTraversal(addE(...args).property('_env', ENV));
g.V = (...args: any[]) => bindGraphTraversal(V(...args).has('_env', ENV));
g.E = (...args: any[]) => bindGraphTraversal(E(...args).has('_env', ENV));
return g;
}
然后像这样重新赋值图遍历对象
g = setEnvironment(g, 'my-environment');
这将在创建顶点或边时自动添加 属性 _env
。它从查询中过滤 _env
。
虽然这不是一个合适的解决方案,但我们可以通过这个创建多个图形环境。
来自提及将多租户 Blazegraph 数据库迁移到 Neptune 的 AWS Neptune 文档:
"多租户 – Blazegraph 支持单个数据库内的多租户。在 Neptune 中,通过将数据存储在命名图中并使用 USING NAMED 子句来支持多租户
SPARQL 查询,或通过为每个租户创建单独的数据库集群。"
https://docs.amazonaws.cn/en_us/neptune/latest/userguide/neptune-ug.pdf
这可能会解决 1、2 和 3。第 4 点将是弱点,因为即使在默认情况下(当查询中不包含命名图时)它也会使用所有图的并集。重要的是要强调此解决方案仅适用于 RDF,而不适用于将 Neptune 用作 属性 图形存储时。
我是海王星的新手。
在 Neptune 数据库中支持多租户的最佳方式是什么?
要求:
1.支持数据库千租户(一个集群)
2. 租户过滤避免查询变得过于复杂
3. 良好的性能(如果有一种方法可以使用数据分区来加快查询时间)
4. 安全 - 很难犯会导致跨租户访问的错误。
在非生产环境中,Gremlin partition strategy 证明对我来说已经足够了。顶点和边共存于同一个 Gremlin 集群中,它们有一个 属性 来区分它们,在我的例子中我使用了 _env
属性。
然后在我的 Java 代码中,每次我请求工厂遍历时,它都使用分区策略。
private GraphTraversalSource buildReadOnlyTraversal() {
log.debug("building read-only traversal");
return AnonymousTraversalSource.traversal()
.withRemote(DriverRemoteConnection.using(getReadOnlyCluster()))
.withStrategies(buildPartitionStrategy(), buildReadOnlyStrategy());
}
private PartitionStrategy buildPartitionStrategy() {
var env = this.properties.getEnvironmentPartition();
log.info("building partition strategy for environment={}", env);
return PartitionStrategy.build()
.partitionKey(ENVIRONMENT_PARTITION_KEY)
.writePartition(env)
.readPartitions(env)
.create();
}
使用这些遍历将自动限定在您的分区范围内。然而,最大的问题是你需要记住在从控制台查询时手动添加对分区的引用(实际上任何不使用分区策略机制的东西)例如
g.V().hasLabel('user').has('_env', 'dev')
我认为这符合您的前 2 个标准,性能我无法真正评论。第 4 点,是的,这不是应用程序代码的问题,手动修改图形时更容易出错。
我已经想出了解决这个问题的方法。我像这样更改了 GraphTraversal 的一些现有功能。
setEnvironment = (g: GraphTraversalSource<GraphTraversal>, ENV: string) => {
const bindGraphTraversal = (t: GraphTraversal): GraphTraversal => {
const V = t.V.bind(t);
const addV = t.addV.bind(t);
const addE = t.addE.bind(t);
t.V = (...args: any[]) => V(...args).has('_env', ENV);
t.addV = (...args: any[]) => addV(...args).property('_env', ENV);
t.addE = (...args: any[]) => addE(...args).property('_env', ENV);
return t;
}
const addV = g.addV.bind(g);
const addE = g.addE.bind(g);
const V = g.V.bind(g);
const E = g.E.bind(g);
g.addV = (...args: any[]) => bindGraphTraversal(addV(...args).property('_env', ENV));
g.addE = (...args: any[]) => bindGraphTraversal(addE(...args).property('_env', ENV));
g.V = (...args: any[]) => bindGraphTraversal(V(...args).has('_env', ENV));
g.E = (...args: any[]) => bindGraphTraversal(E(...args).has('_env', ENV));
return g;
}
然后像这样重新赋值图遍历对象
g = setEnvironment(g, 'my-environment');
这将在创建顶点或边时自动添加 属性 _env
。它从查询中过滤 _env
。
虽然这不是一个合适的解决方案,但我们可以通过这个创建多个图形环境。
来自提及将多租户 Blazegraph 数据库迁移到 Neptune 的 AWS Neptune 文档:
"多租户 – Blazegraph 支持单个数据库内的多租户。在 Neptune 中,通过将数据存储在命名图中并使用 USING NAMED 子句来支持多租户 SPARQL 查询,或通过为每个租户创建单独的数据库集群。"
https://docs.amazonaws.cn/en_us/neptune/latest/userguide/neptune-ug.pdf
这可能会解决 1、2 和 3。第 4 点将是弱点,因为即使在默认情况下(当查询中不包含命名图时)它也会使用所有图的并集。重要的是要强调此解决方案仅适用于 RDF,而不适用于将 Neptune 用作 属性 图形存储时。