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 用作 属性 图形存储时。