0%

Cassandra数据建模实践


Cassandra系列文章共四篇,本篇是第四篇。内容如下:

  1. Cassandra集群架构及算法剖析
  2. Cassandra可调一致性的使用及原理
  3. Cassandra内部架构及读写流程
  4. Cassandra数据建模实践

Cassandra数据模型

前几篇中,我们已经从架构的角度研究了Cassandra,并解释了其内部工作方式。 本篇中,我们将研究Cassandra的数据模型,并说明为什么它非常适合处理超大型分布式数据库。

乍一看,Cassandra看起来很像一个关系型数据库。 它具有带有行和列的表,有标准的schema,并且CQL命令语法看起来很像SQL。 但是,Cassandra的行为和存储与关系型数据库不同。

举一个典型的互联网应用的例子来分析Cassandra处理问题以及关系型数据库处理问题的区别。

典型案例

假设一个场景,一个在线服务提供商或零售商管理数百万个客户帐户。出于说明目的,我们仅关注两个表:

  • 客户表(customer),维护使用在线服务的人员列表。它包含客户的唯一ID,用户名,加密密码等详细信息。
  • 客户事件表(customer_events),每当客户与系统进行重大交互时,客户事件表都会记录一条记录,如登录,购买,页面浏览等。

现在想象一下,系统有一千万个用户,其中每个用户平均记录了1,000个事件,每个事件的大小约为1KB。 仅在customer_events表中就需要存储10TB的数据。

关系型数据库的挑战

对于关系型数据库,通常使用两个表来处理此问题。客户表将保存有关客户的信息,并将通过两个表中存在的客户ID(关系)连接到客户事件表。客户事件表的主键可能是事件发生时的时间戳,或者是其他保证唯一的复合键。

这种方法存在几个问题:

  • 性能将是巨大的挑战。需要客户和事件信息的任何查询都将涉及联接两个非常大的表。
  • 来自潜在的数百万用户的流量几乎肯定会压垮单个数据库实例。开发人员可以对数据库进行分库分表,但这会使设计和开发复杂化,并且很难汇总聚合数据。
  • 确保跨云区域或数据中心的可用性和数据完整性也将是一个挑战。当关系型数据库不可避免地发生故障转移到备库时,用户将经历一段时间的停机时间。
  • 在关系型模型中,可能需要许多空字段。例如,客户代表的姓名可能仅与特定类型的客户有关。在关系型模型中,字段必须在每一行中存在,无论它们是否与事件类型相关。

Cassandra的最佳实践

在下图中,似乎冗余地存储了客户名称和电子邮件地址,但是正如我们后面看到的,这只是CQL如何显示表格数据视图的问题。Cassandra支持静态列,其中每个分区键都关联一个值。

表模型

Cassandra不会将数据存储在传统的行和列中,而是将数据存储为键值对。例如,一行中的单个数据项具有一个键(例如”cust_email”)和一个关联值(haorunaru@laoren.tech)。 同样,并非每一列都需要在一行中表示。如果该列没有值,Cassandra根本不会存储该记录的键值对。

表结构

上图显示了我们的customer_events表如何在逻辑上在Cassandra中存储的。主键由cust_id(分区键)和event_time(集群键)组成。客户名称和邮箱地址存储为静态列,这意味着每个关联的分区键仅存储一个副本。

如前所述,分区键被散列为令牌值,该令牌值确定了副本的群集节点。这种分区策略可确保客户信息和关联的客户事件都驻留在同一节点上。 另外,由于客户记录将在整个群集中分布,因此Cassandra可以同时在多个物理节点之间分配工作,因此可以同时处理涉及所有客户的交易。

群集键属于”宽行”设计,因为每个客户可能有成千上万条事件。通过对数据进行分区并允许用户使用静态列和集群键定义数据的存储和分组方式,Cassandra避免了建多个表的需求,避免了冗余存储数据,并提供了出色的性能。

Cassandra解决了我们在关系型数据库方法中遇到的所有问题:

  • 没有单点瓶颈,因为任何Cassandra节点都可以当做查询协调器。随着节点添加到集群中,事务吞吐量也会随之增加。
  • 跨数据中心,跨云区域完整性问题也得到解决。客户只需访问其位置附近的节点,Cassandra即可自动管理到其他可用性区域,数据中心或公有云的副本。
  • 因为每个宽行都写入多个副本,所以可以确保数据可用性。如果主机不可用,Cassandra将透明地从其他副本中获取数据。
  • Cassandra避免了存储空字段值的开销,因为它仅存储现有数据项的键-值对。

查询优先设计

在Cassandra中,并不是像关系型数据的设计方法一样,需要从概念领域入手,将领域中的名词抽象出数据表然后指定表之间的关系。Cassandra要先对查询建模,然后根据查询来组织数据,先考虑你的应用最常用的查询路径,然后创建支持这些查询所需要的的表。

在Cassandra数据建模领域,有一种叫做Chebotko图的建模方法可以指导模型设计。可以参考论文:A Big Data Modeling Methodology for Apache Cassandra。这篇论文由浅入深地讲解了基于查询优先的设计理论和Chebotko建模方法,可以说是一篇理论加实践的好文。强烈建议有Cassandra数据建模需求的朋友读一读。

总结

本篇介绍了Cassandra数据库的数据建模特点及和关系型数据库的差异。并使用了一个客户及客户事件的示例对Cassandra数据建模进行了分析。并提出了查询优先的设计理念。

坚持原创技术分享,您的支持将鼓励我继续创作!