【问题标题】:Best practice to update large number of rows in Cassandra reliably (relational update)在 Cassandra 中可靠地更新大量行的最佳实践(关系更新)
【发布时间】:2017-09-15 07:13:44
【问题描述】:

我有几个相互关联的表,看起来像这样:

organizations: 
- id
- name
- ... other fields

users:
- id
- name
- organization_id
- organization_name
- ... other fields

我将organization_name 字段保留在users 表中,这样它就不必查找组织来获取组织名称

问题在于,如果更改了组织名称,则必须更新与该组织相关的所有用户以反映新名称。在我的真实场景中,我存储了更多的表 organization_name

问题:目前我只是异步启动更新语句,如果它中途失败,那么我最终会得到不一致的数据

问题:是否有处理此类问题的最佳实践?

可能的解决方案

  • 使用BATCH 语句。但我发现它非常有限,因为默认情况下它只允许 50kb 查询大小(在我的情况下,1 次更新可能会导致从两个或三个不同的表中更新 8,000 个其他实体,字段值的长度不同 - 所以查询大小是相当不可预测的)
    • 我实际上尝试使用 BATCH 语句更新 100 个项目(共 600 个需要更新的项目),但由于“批量太大”异常而失败...
  • 更新失败重试

PS - 我的行不是太宽,每个表最多有 20 列


更新:

忘了补充,这是一个webapp,更新需要尽快反映,所以批处理作业不适用


更新 2:

关于读取模式,我当前的示例过于简单,但无论如何我都需要获取用户列表(它可以来自多个组织) - 这可能会返回数百个组织中的数千个用户,这就是我存储的原因users 表中的organization_name,据我了解,Cassandra 数据非规范化是可行的方法

【问题讨论】:

  • 你的阅读模式是什么?为什么要避免按用户查找组织名称?如果你想显示一个用户的信息,最好有一个额外的请求来获取组织名称,而不是支持多个表之间的一致性。
  • @MikhailBaksheev 我更新了问题以包含更多详细信息。我同意如果为一个用户显示,存储组织名称没有意义:-)
  • 你打算通过哪个字段来获取用户?还是所有用户?
  • 将我的回答读作:“更新 X 记录组中的所有记录。选择 X 以最好地反映您的需求。连续运行多个“组更新”,就像您应该一次更新所有记录一样,但只需为每个组添加书签,以便在出现问题时能够恢复。”这不是“尽快”吗?
  • 没有批处理,只有异步。并将您的查询设计为幂等的,这样您就可以一次又一次地运行它们......

标签: cassandra


【解决方案1】:

就像在每个长时间运行的更新过程中一样,您应该使用书签的概念

  • 运行 jobs 的(比如 100 个)异步更新,然后将您刚刚完成更新 100 行的存储在某处。
  • 运行另外 100 行的另一个作业,然后为刚刚更新的 200 行添加书签。
  • 等等……

如果发生崩溃,您只需阅读书签即可恢复崩溃的位置。

要执行此类任务,您必须已经知道必须更新哪些记录,但我假设您已经知道它们或知道如何检索这些信息。

【讨论】:

    【解决方案2】:

    尝试使用分页。大多数驱动程序都支持它。

    1) 从 users 表接收更新结果,每页分页 x 行。

    2) 为页面中的每条记录运行异步更新。

    3) 移至下一页。

    【讨论】:

      猜你喜欢
      • 2019-06-29
      • 2017-08-07
      • 1970-01-01
      • 2020-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多