【问题标题】:Cassandra table synchronizationCassandra 表同步
【发布时间】:2015-07-25 02:14:58
【问题描述】:

我刚刚阅读了 DataStax 帖子“Basic Rules of Cassandra Data Modeling”,总而言之,我们应该通过查询而不是关系/对象来建模我们的数据库模式。因此,许多表可以有相同的重复数据,例如users_by_emailusers_by_username 都具有相同的数据。

如何处理对象更新?
例如,用户编辑他的电子邮件,我是手动 UPDATE 两个表还是只 INSERT 包含所有列的对象并且不关心以前的数据(它们仍在我的数据库中,但列值错误=>电子邮件)。

如果是UPDATE,我该如何处理数据同步?
目前,我正在手动操作,但有什么工具可以帮助我吗?因为,我可能有 5 或 6 个具有不同分区/集群键的表。
听说Hadoop可以,Apache Spark也可以。

【问题讨论】:

    标签: cassandra datastax nosql


    【解决方案1】:

    为确保包含相同数据但布局不同的多个表之间的数据一致性,建议您在 CQL 中使用 LOGGED BATCH 进行更新。这样你的 BATCH 中的 CQL 语句(更新数据)是 ACID,你不必担心一些失败和重试。

    使用链接文章的架构,它看起来像:

    BEGIN BATCH
      INSERT INTO users_by_email (email, username, age) VALUES ('fromanator@email.com', 'fromanator', 24);
      INSERT INTO users_by_username (email, username, age) VALUES ('fromanator@email.com', 'fromanator', 24);
    APPLY BATCH;
    

    整个语句是原子的,如果一个插入失败,它们都失败并且没有进行任何更改。

    【讨论】:

    • 但是您如何维护更新?就像表 T1 的 PK 是 id 而表 T2 的 PK 是 new_id,假设在给定时间我只有 id 而没有 new_id 我如何更新 T2?我应该从 T1 读取 new_id 并使用它来更新 t2 吗?因为这听起来很沉重
    【解决方案2】:

    在 Cassadnra 中,给定现有记录,使用相同主键的更新或插入将导致旧记录标记为删除(带有墓碑),新记录变为“活动”。插入和更新之间的区别很少有细微差别,例如计数器和空值,但这些可能与问题无关。

    在 Cassandra 3.0 之前,同步维护相同数据的多个视图的责任由客户端应用程序负责。是的,这意味着在需要它的所有不同表中插入/更新新数据。

    Cassandra 3.0 引入了"Materialized Views",它允许您维护数据的“主”表及其上的多个视图,所有这些都由 Cassandra 管理。它需要仔细的数据建模,以便“主”表的主键包含创建所需的不同视图和相关查询所需的实体。

    另外一点:如果您发现您的数据是高度相关的并且需要多个/多个视图才能使其可查询,那么 Cassandra 可能不适合该问题空间,您可能应该考虑使用 RDBMS。

    为了扩展所提供的示例,我们可能希望将用户信息保留在关系数据库中,而这些用户的大量操作可以在 Cassandra 中注册。 (购买、点击、心率样本……)

    【讨论】:

    • 拥有两个(或更多?!)系统来管理您的数据,例如 Cassandra 和一个 RDBMS,会使事情变得更加复杂。再加上一个或另一个可能会成为您当前安装的瓶颈。
    • 除非在插入或更新具有显式空值的数据时,您不会创建墓碑。相反,Cassandra 会将更新写入新的 SSTable,并在读取路径期间通过在多个 SSTable 中查找最近更新的列值来创建“实时”数据。 Compaction 最终会运行以确保 Cassandra 不必读取太多 SSTables 来获取最新数据。
    • @AlexisWilke 总是有赞成和反对的。如果高度相关的数据相对较小,则可以在 CQL 边界内进行额外的建模工作。在其他情况下,一个组织可能已经有一个 RDBMS,而不是尝试将所有内容迁移到 Cassandra,只需使用 cassandra 的可扩展性属性来补充架构,以获取实际需要的数据。我已经看到了几种精心设计的 Relational-+-NoSQL 架构。
    【解决方案3】:

    我在我的系统中所做的就是为每个用户设置一个唯一的标识符。

    我使用一张电子邮件/标识符表(和一些其他数据)。当用户登录或使用系统时,我使用他的电子邮件来查找标识符,然后其他一切都使用该标识符。

    用户现在可以更改他的电子邮件地址,标识符保持不变,因此所有其他表不需要更新来进行此类更改。

    关于旧的电子邮件地址,我还没有全部完成,但我计划让当前的电子邮件引用旧的电子邮件地址(如果您愿意,可以使用“链接”)并在一段时间后,也许 12 个月,旧电子邮件将被删除。在这 12 个月内,该帐户被阻止(其他人无法重复使用该帐户。)出于各种安全原因,这是一个好主意。

    附:对于唯一标识符,人们使用不同的解决方案,比如 Zookeeper,我个人喜欢使用Cassandra with the Lamport's bakery algorithm

    【讨论】:

    • 对于您的唯一标识符,为什么不使用 Cassandra 已经为您提供的 timeuuid
    • 首先,我从 0.8 和 thrift 开始。因此,这些功能并不全部存在。其次,对于希望拥有 URI(例如 example.com/user/123)的用户,使用 UUID 真的很难看。最后,尽管您可能会认为这可能无关紧要,但我的标识符可以是 32 位整数,而 UUID 是 128 位。这是要移动的更多数据。
    猜你喜欢
    • 2011-06-10
    • 2017-10-02
    • 2015-08-22
    • 2015-06-11
    • 1970-01-01
    • 2016-02-03
    • 2021-10-20
    • 2020-12-22
    • 2023-04-10
    相关资源
    最近更新 更多