Cassandra table 同步

Cassandra table synchronization

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

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

如果是UPDATE,我该如何处理数据同步?
目前,我正在手动执行此操作,但有没有工具可以帮助我?因为,可能,我可以有 5 或 6 个具有不同 partition/clustering 键的表。
听说Hadoop可以,或者Apache Spark。

在 Cassadnra 中,给定现有记录,使用相同主键进行更新或插入将导致旧记录标记为删除(带有逻辑删除),新记录变为 "live"。 Insert 和 Update 之间的区别很少,例如计数器和空值,但这些可能与问题无关。

在 Cassandra 3.0 之前,同步维护同一数据的多个视图的责任在客户端应用程序手中。是的,这意味着 insert/update 需要它的所有不同 table 中的新数据。

Cassandra 3.0 引入了 "Materialized Views",它让您可以维护 "master" table 数据及其多个视图,全部由 Cassandra 管理。它需要仔细的数据建模,以便 'master' table 的主键包含创建不同视图和所需相关查询所需的实体。

附加说明:如果您发现您的数据高度相关并且需要 several/many 视图才能使其可查询,那么 Cassandra 可能不适合解决该问题 space 并且可能您应该考虑使用 RDBMS。

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

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

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

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

关于旧的电子邮件地址,我还没有全部完成,但我计划让当前的电子邮件参考旧的("link",如果你愿意的话)并在一定时间,也许是 12 个月,旧电子邮件将被删除。在这 12 个月里,该帐户被阻止(没有其他人可以重新使用该帐户。)出于各种安全原因,这是一个好主意。

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

为了确保包含相同数据但布局不同的许多表的数据一致性,建议您使用 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;

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