【问题标题】:Which solution is preferred when populating two Cassandra tables?填充两个 Cassandra 表时首选哪种解决方案?
【发布时间】:2021-07-20 13:52:03
【问题描述】:

我有一个性能问题。我在 Cassandra 中有两张桌子,它们的结构完全相同。我需要在他们两个中保存传入的数据。我遇到的问题是什么是更好的解决方案:

  1. 创建两个存储库,它们都打开 Cassandra 会话,将数据分别保存到两个表中(全部在代码中)。
  2. 将数据保存到一个表中,在该表上设置一个触发器并将传入的数据复制到另一个表中
  3. 还有其他解决方案吗?

我认为前两个还可以,但我不确定第一个是否足够好。谁能给我解释一下?

【问题讨论】:

    标签: database performance cassandra nosql


    【解决方案1】:

    这听起来像是BATCH 的一个很好的用例。本质上,您可以组装两个写语句并在BATCH 中执行它们以确保原子性。这应该使两个表保持同步。以下示例来自 DataStax 文档 (URL)。

    cqlsh> BEGIN LOGGED BATCH
        INSERT INTO cycling.cyclist_names (cyclist_name, race_id) VALUES ('Vera ADRIAN', 100);
        INSERT INTO cycling.cyclist_by_id (race_id, cyclist_name) VALUES (100, 'Vera ADRIAN');
    APPLY BATCH;
    

    【讨论】:

      【解决方案2】:

      +1 对 Aaron 关于使用 BATCH 语句的回复,但引用的示例特定于 CQL。在您的应用中实现它时会更加细致入微。

      如果您使用的是 Java 驱动程序,典型的 INSERT 语句如下所示:

      SimpleStatement simpleInsertUser = SimpleStatement.newInstance(
        "INSERT INTO users (...) VALUES (?), "..." );
      

      这是一个准备好的声明:

      PreparedStatement psInsertUserByMobile = session.prepare(
        "INSERT INTO users_by_mobile (...) VALUES (...)" );
      

      如果您要批处理这两个语句:

      BatchStatement batch = BatchStatement.newInstance(
        DefaultBatchType.LOGGED,
        simpleInsertBalance,
        preparedInsertExpense.bind(..., false) );
      
      session.execute(batch);
      

      对于您列表中的第 2 项,我不知道在生产中使用 Cassandra TRIGGER 的公司,因此我不建议这样做。它是实验性的,我没有足够的经验来推荐它们进行生产。

      对于第 3 项,这是物化视图试图解决的用例。从开发人员的角度来看,它们肯定要简单得多,因为表更新是在服务器端而不是客户端完成的。

      如果您没有很多表,则可以使用它们,但请注意视图的更新是异步发生的(与基表上发生突变的时间不同)。对于 MV,当视图与基表不同步时,唯一的解决方案是删除并重新创建 MV。

      如果您不想使用 BATCH 语句,只需确保您完全了解使用 MV 的权衡。如果您有兴趣,我已经在https://community.datastax.com/articles/2774/ 中进行了更详细的解释。干杯!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-10-24
        • 2021-11-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-11
        • 1970-01-01
        相关资源
        最近更新 更多