2026-10-26·作者 Sijie Wang#fundamentals#storage#nosql

nosql

NoSQL, contrasted against the relational set: four shapes, WAL family, version models, replica consistency.

NoSQL:拿关系型那套逐项对照

它是什么。 NoSQL 不是“没有 SQL”,是非关系型数据模型:引擎不把数据存成带 JOIN 的表,每种形态都是拿关系型的通用性换一种负载。

四种基本形态。

  • 键值:Redis、DynamoDB。一个 key 对一个不透明 value,查最快,value 里头不能再查。
  • 文档:MongoDB、CouchDB、Cloud Datastore。类 JSON 文档,字段可查,schema 灵活。
  • 宽列:Cassandra、HBase、Bigtable。见下。
  • 图:Neo4j。见下。

宽列:列族定死,列随便加。 一张表有一个 row key 和几个列族,建表时定死。列族里的列随时加,一行可以非常宽:一行一个用户,一列一条消息。缺失的列不占地方(稀疏),读只读一个列族。典型:事件日志、消息收件箱。

图:关系本身就是数据。 节点是实体,边是带属性的关系。为关系链查询而生:朋友的朋友、买过这个的也买过、资金路径。引擎走指针,不用反复 JOIN。

WAL 家族:活一样,名字不同。 任何不能丢已确认写的引擎都要有一个先写日志,名字不同而已:Cassandra 的 commitlog、MongoDB 的 journal、Redis 的 AOF(见 wal)。

Cassandra 写路径。 写发给协调节点,先落 commitlog(盘上,只追加)再进 memtable(内存),然后才算写成功。memtable 满了,刷成不可变的 SSTable 落盘。

commitlog 按固定大小分段(默认 32MB),滚动着存:一段写满就关掉开新的一段。回收的单位是整段:只有段里的数据全刷盘了,整段才能删。挂掉的副本在挂期间的写根本没到过它,它的 commitlog 里没有这条写,所以恢复不回来:commitlog 管的是本机崩溃恢复,不是副本追赶。

版本模型,对照着看。

  • Cassandra/HBase:时间戳多版。SSTable 不可变,写是追加、从不原地覆盖。同一个 key 写两次,在盘上是好几份(memtable 加老 SSTable)。读把它们找出来比时间戳:最新时间戳赢,叫 last-write-wins。读起来像 hash map(只看到一个值),盘上其实是多份。
  • MongoDB(WiredTiger):快照 mvcc。B 树、逻辑上原地更新:盘上同一文档只有一份当前值。多版本只活在内存的更新链里,给并发读做快照;读完、检查点过后旧版本就清掉。多文档事务(4.0+)就立在这个上:事务读它开始那一刻的快照,自己的写自己看得见,提交时如果别人改了它要改的文档就报 WriteConflict,客户端把整个事务重试一遍。快照隔离,不是可串行化。
  • LSM 这边的删也是写:墓碑带时间戳,读的时候墓碑赢着,直到 compaction 并且过了 gc_grace_seconds 才真清掉。

副本一致性轴和隔离级别轴:两根不同的轴。 关系型那边一个主库说了算,并发靠 isolation-levels 管。Cassandra 完全没有 leader(Dynamo 式 quorum,不是 Raft),所有节点对等。

  • 副本数 RF 建 keyspace 时定:RF=3 就是 3 台机器各存一份。
  • 一致性级别每次操作自己选:ONE(1 份点头)、QUORUM(多数派)、ALL(全都要)。
  • 读要的份数加写要的份数大于总份数,就能保证读到新值:3 份里随便两个多数派一定至少重叠 1 台。

副本挂了,事后怎么追。 Hinted handoff:协调节点把写暂存成 hint,等挂的副本恢复后补发(默认 3 小时窗口,超了 hint 就丢了)。Read repair:之后读发现副本旧了,协调节点把新版本推过去。Anti-entropy repair(nodetool repair,比 Merkle 树)是兜底。边界:Cassandra 里唯一用共识的地方是轻量事务(IF NOT EXISTS 那种 CAS),走 Paxos,不是 Raft,也不在日常读写路径上。

为什么小团队圈子里少见。 运维重(compaction、墓碑、repair、JVM 调优);查询模型受限(按分区键设计、没有 JOIN、ALLOW FILTERING 就是全表扫);没有跨分区事务和强一致;它的主场(超大规模写密集、多数据中心)又被各路专用系统分了。不是它死了:那个量级的地方还在用(Netflix、Apple、Discord 都公开讲过自己的部署),只是它不是通用默认选项。

關於這一條

sijie 的一條 wiki 條目。本站的 AI 以同一套語料庫為依據、以 sijie 的口吻作答,並附有指向此類條目的引用——回答會花 sijie 的錢,所以它在存取碼後等待: 輸入存取碼 →