Coursera 笔记

Module 03 · Introducing Apache Cassandra: An Open-Source NoSQL Database

Apache Cassandra Data Model: Part 1Apache Cassandra 数据模型(第一部分)

Coursera ↗

欢迎观看关于 Apache Cassandra 数据模型 的介绍视频。在本视频中,您将能够:

  • 描述 Cassandra 数据模型中的逻辑实体,
  • 描述 主键 在 Cassandra 表中的作用,
  • 解释 分区键 的含义,
  • 描述 Cassandra 支持的两种表类型。

 数据模型:键空间和表

键空间(Keyspace)

Cassandra 将数据存储在 表 中,而表的存储方式在集群和节点级别定义。键空间 是一个逻辑实体,包含一个或多个表。键空间还定义了一些选项,这些选项适用于该键空间中的所有表,其中最重要的选项是 复制策略,它定义了数据的冗余方式。

  • 键空间 通常建议每个应用程序使用一个。

表(Table)

表是数据存储的逻辑实体,每个表包含 行 和 列。您可以创建、删除和更改表,而不会影响正在运行的数据更新或查询。


 主键和分区键

主键(Primary Key)

在 Cassandra 中,主键由两部分组成:

  1. 分区键(Partition Key):这是必需的部分,它决定了数据的分布和存储位置。
  2. 聚类键(Clustering Key)(可选):它用于在分区内部排序数据。

主键的作用是:

  • 优化查询性能:主键的设计应基于您常用的查询。
  • 确保数据的唯一性:主键保证每条数据的唯一性。

分区键的作用

分区键 用于确定数据在集群中的存储位置。它通过哈希函数计算,将数据分配到合适的节点和副本。

  • 数据本地化:分区键决定了数据在集群中的位置,确保了数据的高效存储和检索。

例如,假设我们要存储与 groupid 相关的数据,Cassandra 会根据 groupid 对数据进行分区,并将其分配到集群中的不同节点。

分区和聚类

  • 分区 是 Cassandra 存储的基本单元。每个分区的所有数据都会存储在同一节点上,并有副本分布在其他节点上。
  • 聚类:在分区内部,数据会根据 聚类键 排序。

 静态表与动态表

Cassandra 支持两种类型的表:

  1. 静态表(Static Table):
    • 主键只包含分区键,没有聚类键。
    • 静态表的每个分区只有一个条目,称为 静态分区。
  2. 动态表(Dynamic Table):
    • 主键包含分区键和一个或多个聚类键。
    • 动态表可以在一个分区中存储多个条目,并根据聚类键排序。

静态表示例

例如,用户表 可以是一个静态表,其主键仅由 分区键(例如,用户 ID) 组成。每个用户将有一个对应的分区。


 总结

通过本视频,您学习了:

  • Cassandra 将数据存储在 表 中,而表被组织在 键空间 中。
  • 每个表有一个 主键,主键包含 分区键 和(可选的)聚类键。
  • 分区键 确定数据的分布和存储位置,而 聚类键 用于对数据进行排序。
  • Cassandra 支持 静态表 和 动态表,静态表只包含 分区键,而动态表包含 分区键 和 聚类键。

核心概念深度解析

1. 逻辑存储结构:Keyspace -> Table

  • ​​Keyspace (键空间):​​
    • ​​通俗理解:​​ 一个Keyspace就像一个​​数据库​​(Database)或一个​​命名空间​​。它是一个逻辑容器,里面可以包含多张表(Table)。通常,​​一个应用对应一个Keyspace​​。这是一种很好的逻辑隔离方式。
    • ​​架构师视角:​​ 在Keyspace层面,你需要定义最重要的​​副本策略(Replication Strategy)​​ 和​​复制因子(Replication Factor)​​。这些设置将作用于该Keyspace下的所有表,决定了数据在集群中如何分布和复制,直接关系到系统的​​可用性和容灾能力​​。这是你在做容量规划和容灾方案时必须配置的。
  • ​​Table (表):​​
    • ​​通俗理解:​​ 表就是实际存放数据的地方,由行(Row)和列(Column)组成。
    • ​​架构师视角:​​ Cassandra支持​​在线执行DDL操作​​(如CREATE, DROP, ALTER TABLE),而不会阻塞线上的读写操作,这为业务迭代和模型变更提供了极大的灵活性。但需要注意的是,频繁的ALTER操作可能会带来一些性能开销。

2. 核心中的核心:主键 (Primary Key) 的设计

这是Cassandra与关系型数据库(RDBMS)​​最根本的区别​​,也是设计难点所在。

  • ​​主键的双重角色:​​
    1. ​​提供唯一性:​​ 确保每一行数据是唯一的。
    2. ​​优化查询性能(更重要!):​​ ​​你的查询必须基于主键来设计​​。Cassandra不像关系数据库那样可以通过任意字段加索引来灵活查询。它的高效查询严重依赖于主键的设计。这就是所谓的 ​​“查询驱动建模(Query-Driven Modeling)”​​ 。
  • ​​主键的组成:​​
    主键 = ​​分区键 (Partition Key)​​ + ​​[聚类键 (Clustering Key)]​​
    • ​​分区键 (Partition Key):​​ ​​强制必须有​​。它的作用是决定数据存储在哪个节点上。
      • ​​工作机制:​​ 对分区键的值计算一个哈希值(Token),根据这个Token值将数据分配到集群中的某个节点(及其副本)。
      • ​​架构师视角:​​ ​​分区键的设计是重中之重。​​
        • ​​目标1:数据均匀分布。​​ 要选择一个基数(不同值的数量)足够高的列作为分区键,避免产生“热点节点”(某个节点存储过多数据,承担过多压力)。例如,用user_id比用gender做分区键好得多。
        • ​​目标2:支持核心查询。​​ 你的查询的WHERE条件​​必须包含分区键​​,否则Cassandra将不得不进行全集群扫描(效率极低,被视为反模式)。
    • ​​聚类键 (Clustering Key):​​ ​​可选的​​。它的作用是在一个分区内对数据进行排序和组织。
      • ​​工作机制:​​ 在同一个分区内(即分区键相同的数据),数据行按照聚类键的顺序物理存储。
      • ​​架构师视角:​​ 聚类键用于:
        • ​​排序:​​ 让你能按聚类键的顺序高效检索分区内的数据(如按时间戳倒序排列用户消息)。
        • ​​范围查询:​​ 可以在分区内进行高效的范围查询(如WHERE partition_key = X AND clustering_key > Y)。
        • ​​进一步定义唯一性:​​ 主键的完整唯一性由分区键 + 聚类键共同决定。

​​视频中的例子解析:​​

CREATE TABLE groups (groupid int, username text, age int, group_name text, PRIMARY KEY ((groupid), username));

  • PRIMARY KEY ((groupid), username)
  • ​​分区键:​​ groupid(注意括号,复合分区键也会用括号括起来)
  • ​​聚类键:​​ username
  • ​​设计意图:​​ 为了高效查询“某个组内的所有用户”(WHERE groupid = ?)。所有groupid=12的数据都会作为一个分区存储在同一个节点上,查询时只需访问一个节点(及其副本)即可得到全部结果,性能极高。

3. 分区 (Partition):存储的原子单元

  • ​​通俗理解:​​ 一个分区就是​​所有共享同一个分区键值的数据行的集合​​。它是Cassandra中​​数据存储、复制和分发的最小单位​​。
  • ​​架构师视角:​​
    • 分区的尺寸需要被关注。一个分区过大(例如存储数十万行数据)可能会在读写和压缩时带来性能问题。设计时需要估算一个分区可能增长到的最大尺寸。
    • 如视频所说,查询WHERE groupid=12,数据库直接就能定位到存储该分区的节点,效率极高。这就是良好设计的威力。

4. 静态表 (Static Table) vs. 动态表 (Dynamic Table)

这个分类完全由主键结构决定。

  • ​​静态表 (Static Table):​​
    • ​​定义:​​ 主键​​只有分区键,没有聚类键​​。
    • ​​特点:​​ 每个分区键值只对应​​一行​​数据。例如,一个users表,以user_id作为分区键,每个用户ID在表中只有一行记录。
    • ​​数据模型:​​ 类似于键值存储(Key-Value),每个分区就是一个值。
  • ​​动态表 (Dynamic Table):​​
    • ​​定义:​​ 主键包含​​分区键和聚类键​​。
    • ​​特点:​​ 每个分区键值可以对应​​多行​​数据(这些行通过不同的聚类键值区分)。例如上面的groups表,一个groupid(分区)下可以有多个username(聚类),每个用户名是一行。
    • ​​数据模型:​​ 类似于宽列存储(Wide-Column),每个分区下包含一个有序的行集合。

总结给你(系统架构师备考者)

  1. ​​思维转变:​​ 忘记关系数据库的范式化设计。Cassandra是 ​​“为查询而生”​​ 的。设计数据模型的第一步是​​列出所有业务查询​​,然后为每个查询设计最适合它的表结构(这通常意味着大量数据冗余)。
  2. ​​核心法则:​​ ​​查询必须带分区键​​。这是保证高性能的铁律。
  3. ​​设计流程:​​
    • 确定应用所需的Keyspace和副本策略。
    • 为每个查询语句设计一张表。
    • 根据查询条件确定分区键(确保数据分布均匀)。
    • 根据排序和范围查询需求确定聚类键。
    • 将所有需要的字段都加入表中(敢于冗余)。
  4. ​​权衡:​​ 用​​存储空间​​和​​数据冗余​​来换取​​极致的读写性能​​和​​无限的水平扩展能力​​。这是NoSQL的典型 trade-off。

掌握这些概念,你就能设计出高效、稳定的Cassandra数据模型,从而支撑起庞大的业务系统。