1.1 起源与发展


1.1 起源与发展

本节摘要:Cassandra 诞生于 Facebook Inbox Search 的 MySQL 双写困境——2008 年 7 月开源,2010 年进入 Apache 孵化器,2011 年 CQL 成为默认接口。本节对照 Dynamo 论文与 Bigtable 列族模型,说明它为何从第一天起就是「为失败而设计」的 AP 系统。

学习目标

阅读完本节,你应当能够:

  1. 说明 2006 年 Inbox 双写导致「发了却搜不到」的根因
  2. 列举 Lakshman/Malik 设计信条中的三条写入/可用性原则
  3. 描述 CQL 1.2 相对 Thrift 的范式意义
  4. 对比 MongoDB(2009 文档)与 HBase(2008 Bigtable 实现)的协调差异

一、问题与直觉

2004 年 Facebook 消息系统已在 MySQL 上吃力:主从断裂、单点故障、写入延迟随规模恶化。2006 年 Inbox Search 更棘手——用户要求数秒内可搜到新消息,团队采用「写 MySQL + 异步推索引」的双写。网络一旦分区,MySQL 成功而索引失败,产品信任直接受损。MongoDB 当时尚未成熟;HBase 强依赖 HDFS 与 ZooKeeper,运维链路过长。Facebook 需要的是:任意节点失效仍服务、写入延迟不随集群线性恶化、读取陈旧度由客户端 CL 决定

二、核心原理

内部设计文档凝练三条信条(SOURCE 1.1):

「系统必须在任意节点失效时持续提供服务。」
「写入延迟不应随集群规模线性增长。」
「读取延迟由客户端可容忍的陈旧度决定,而非服务端强同步。」

2008 年 7 月代码开源;2009 年 Jonathan Ellis 推动 Gossip 升级为带版本向量的反熵同步;2010 年 2 月进入 ASF 孵化器,RFC 流程约束重大特性;2011 年 Cassandra 1.2 弃用 Thrift,CQL 成为默认接口——表面像 SQL,内核强制 PRIMARY KEY 分区,禁止无分区键全表扫描。

年份 里程碑 与竞品对照
2008 Facebook 开源 HBase 0.18 仍绑 Hadoop 0.20
2010 Apache 孵化 MongoDB 1.6 副本集
2011 CQL 默认 Mongo 仍 BSON 查询为主
2015– 3.x LWT/MV HBase 强一致读适合离线 MR
2020+ 4.x 增量 repair、SAI PostgreSQL 仍是 OLTP 默认

2006 年启动的代号「Cassandra」隐喻:系统能预言数据最终状态,分区时却无人保证「此刻谁对」——与 Mongo 主节点仲裁、HBase Master+ZK 形成鲜明对照。

三、工程实践要点

版本选型:生产建议 4.x LTS;4.0 起 Incremental Repair 与 ZDU 显著降低运维窗口。从 2.x 跳跃升级需先读 release note 中 sstable 格式变更。

生态位:Netflix 全球会话、Apple iMessage 后端、Uber 轨迹——共同点是写入 QPS 高、查询路径预定义。若团队期望「像 PostgreSQL 一样 ad-hoc 分析」,应优先考虑 Timescale/ClickHouse,而非硬上 Cassandra。

⚠️ 常见坑:把 Cassandra 当 MySQL 分库分表替代品,却保留 JOIN 思维——上线后第一个 ALLOW FILTERING 就是事故前兆。

💡 关键直觉:Cassandra 的历史是「把应用层分布式复杂度下沉到内核」——LWT、MV、TTL 都是这一思路的延续。

一节小结

  • Inbox 双写是 AP 路线的直接诱因,不是理论推演
  • 2008 开源 + 2010 ASF 把 Facebook 私产变成可治理的社区项目
  • CQL 1.2 是语法层对分布式拓扑的契约,不是 SQL 方言
  • Dynamo 环 + Bigtable 宽列构成基因;协调方式与 HBase 根本不同
  • 4.x repair/SAI 解决的是 2.x 时代「不敢用」的运维缺口

下一节在 CAP 三角上精确标注 Cassandra 的默认锚点,以及 QUORUM 背后的 W+R≥N 算术。

升级路线:从 0.x 到 4.x 的迁移要点

生产集群不会一直停留在老版本。社区维护的升级路径通常跳不过中间版,每步都有前置条件:

起点 终点 关键前置
2.1.x 2.2.x 迁移 cassandra.yaml 参数名
2.2.x 3.0.x 磁盘格式升级(sstables upgrade
3.0.x 3.11.x 滚动升级,逐节点验证
3.11.x 4.0.x 滚动升级,注意 gc_grace_seconds 与 repair 窗口
# 升级前快照 + 全量 repair,是任何跨大版本动作的底线 nodetool snapshot -t pre_upgrade_20240814 nodetool repair -full # 滚动升级:一次一个节点,验证 UN 状态后再动下一个 systemctl stop cassandra # 替换安装包后启动 systemctl start cassandra nodetool status

生态对照:DynamoDB 同源不同路

Cassandra 与 DynamoDB 都受 2007 年 Dynamo 论文启发,但演化方向分叉:DynamoDB 走托管化、API 私有化,强一致选项收窄;Cassandra 走开源社区、CQL 标准化,可调 CL 完整保留。若团队已在 AWS,且不想维护集群,DynamoDB 的单分区键查询与 TTL 机制与 Cassandra 的建模直觉高度相似,迁移成本低于从 PostgreSQL 迁移。

复现 Inbox 双写困境的思考实验

用一段伪代码复现 2006 年的问题,理解「发了却搜不到」的根因:

# 伪代码:双写模式在分区下的失效路径 def send_message(msg): mysql.insert(msg) # 主库成功 index.push(msg) # 异步索引,可能失败或延迟 # 若网络分区,用户已发出但搜索索引缺失 → 搜不到

Cassandra 的答案不是消灭分区,而是把两份数据放进同一分区,让主数据与索引副本要么一起可见,要么在修复后一起收敛——这正是第3章「查询驱动建模 + 双表」的源头。

关键配置文件探秘

# cassandra.yaml 中与版本演进相关的三个开关 partitioner: org.apache.cassandra.dht.Murmur3Partitioner # 升级时若发现旧集群用 RandomPartitioner,需先规划数据迁移 snapshot_before_compaction: false enable_materialized_views: true

理解这三个开关,就理解了 Cassandra「配置即契约」的版本观:分区器决定数据分布不可轻易变更,快照与物化视图开关则按运维预算权衡。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U