【问题标题】:Multi-tenancy in AWS Neptune databaseAWS Neptune 数据库中的多租户
【发布时间】:2019-12-06 22:40:07
【问题描述】:

我是海王星的新手。 在 Neptune 数据库中支持多租户的最佳方式是什么?
要求:
1.支持数据库上千租户(一个集群)
2. 租户过滤避免查询过于复杂
3. 性能好(如果有办法使用数据分区来加快查询时间)
4. 安全 - 防止出错导致跨租户访问。

【问题讨论】:

    标签: gremlin amazon-neptune


    【解决方案1】:

    在非生产环境中,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 点,是的,它不是应用程序代码的问题,手动修改图形时更容易出错。

    【讨论】:

    • AWS Neptune 是否支持 PartitionStrategy?
    • 这个带有 PartitionStrategy 的解决方案是否适用于 AWS Neptune?
    • 是的,我在一个 neptune 实例上有两个分区(dev 和 qa)。将其视为使用 Java 代码时自动添加的额外属性。
    【解决方案2】:

    我想出了解决此问题的方法。我像这样更改了 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

    虽然这不是一个合适的解决方案,但我们可以通过这个创建多个图形环境。

    【讨论】:

      【解决方案3】:

      来自有关将多租户 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 作为属性图存储时。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-23
        • 2014-12-01
        • 1970-01-01
        • 2021-07-10
        • 1970-01-01
        • 2012-03-19
        相关资源
        最近更新 更多