Cassandra表同步

8
我刚刚阅读了DataStax的文章 "Cassandra数据建模基础规则",总结来说,我们应该根据查询而不是关系/对象来建模数据库架构。因此,许多表可以具有相同的重复数据,例如users_by_emailusers_by_username,两者都具有相同的数据。
我该如何处理对象更新?例如,用户编辑了他的电子邮件,我需要手动UPDATE两个表还是只需INSERT所有列的对象并不关心以前的数据(仍然在我的数据库中,但列值错误 = >电子邮件)。
如果进行UPDATE,我该如何处理数据同步?目前,我正在手动执行此操作,但是否有工具可以帮助我?因为可能会有5或6个具有不同分区/聚簇键的表。我听说Hadoop可以做到这一点,或者Apache Spark。
3个回答

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

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

1
但是如何保持更新呢?比如对于表T1,主键是id,而对于表T2,主键是new_id,假设在某个时刻我只有id而没有new_id,那么我该如何更新T2呢? 我应该从T1中获取完整的行,读取new_id并使用它来更新T2吗?因为这听起来非常繁重。 - im_bhatman

3
在Cassandra中,如果给定一个现有记录,并使用相同的主键进行更新或插入,将导致旧记录被标记为删除(具有墓碑),而新记录变为“活动”。关于插入和更新之间的差异,如计数器和空值等细微之处,可能与问题无关。
直到Cassandra 3.0,同步维护相同数据的多个视图的责任由客户端应用程序承担。是的,这意味着要在所有需要它的不同表中插入/更新新数据。
Cassandra 3.0引入了"Materialized Views",它允许您维护数据的“主”表以及对其的几个视图,所有这些都由Cassandra管理。它需要仔细的数据建模,以便“主”表的主键包含创建所需的不同视图和相关查询所需的实体。
另外一点:如果您发现您的数据高度相关并且需要多个/许多视图才能使其可查询,那么Cassandra可能不适合该问题空间,您应该考虑使用RDBMS。
为了扩展所提供的示例,可能我们希望将用户信息保存在关系型数据库中,而这些用户的高频操作可以在Cassandra中进行记录。(购买、点击、心率样本等)

拥有两个(或更多?!)系统来管理您的数据,例如Cassandra和关系型数据库,会使事情变得更加复杂。而且其中一个可能会成为当前安装中的瓶颈。 - Alexis Wilke
除非使用显式空值插入或更新数据,否则您不会创建墓碑。相反,Cassandra将在新的SSTable中编写更新,而“实时”数据是通过在多个SSTable中查找最近更新的列值来创建读取路径的。压缩最终将运行以确保Cassandra不必读取太多的SSTable即可获取最新数据。 - fromanator
@AlexisWilke 总是有利弊。如果高度关联的数据相对较小,可以在 CQL 范围内建模而不必花费额外的精力。在其他情况下,组织可能已经拥有了 RDBMS,并且可以仅使用 Cassandra 的可扩展性属性来补充架构,而无需尝试将所有内容迁移到 Cassandra。我见过几个形式良好的关系型-+-NoSQL 架构。 - maasg

1
在我的系统中,我为每个用户设置了唯一标识符。我使用一个包含电子邮件/标识符(以及其他数据)的表格。当用户登录或使用系统时,我使用他的电子邮件查找标识符,然后其他所有操作都使用该标识符。现在,用户可以更改他的电子邮件地址,但标识符保持不变,因此所有其他表不需要更新这种更改。关于旧电子邮件地址,我还没有全部完成,但我计划让当前的电子邮件引用旧电子邮件(如果您愿意,可以称之为“链接”),并在一定时间内,可能是12个月后,删除旧电子邮件。在这12个月中,该帐户被封锁(没有人可以重新使用该帐户),出于各种安全原因,这是个好主意。另外,对于唯一标识符,人们使用不同的解决方案,例如Zookeeper,我个人喜欢使用Lamport烘培算法的Cassandra

为什么不使用Cassandra已经提供的timeuuid作为您的唯一标识符呢? - fromanator
首先,我从0.8和thrift开始。因此,并非所有这些功能都存在。其次,对于用户而言,如果您想要一个像example.com/user/123这样的URI,使用UUID真的很丑陋。最后,尽管您可以争论它可能不会有太大影响,但我的标识符可以是32位整数,而UUID是128位。这意味着需要移动更多的数据。 - Alexis Wilke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接