2026-10-26·par Sijie Wang#fundamentals#storage#nosql

nosql

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

NoSQL, contrasted against the relational set

What it is. "NoSQL" does not mean "no SQL". It means non-relational data models: the engine does not store rows in tables with JOINs, and each shape below trades relational generality for one workload.

The four shapes.

  • Key-value: Redis, DynamoDB. One key maps to one opaque value. Fastest lookup, no query inside the value.
  • Document: MongoDB, CouchDB, Cloud Datastore. JSON-like documents with queryable fields and flexible schema.
  • Wide-column: Cassandra, HBase, Bigtable. See below.
  • Graph: Neo4j. See below.

Wide-column: column families fixed, columns free. A table has a row key and a few column families, fixed at creation. Columns inside a family are added any time, and a row can be extremely wide: one row per user, one column per message. Missing columns cost nothing (sparse), and a read touches one family only. Typical: event logs, message inboxes.

Graph: relations are the data. Nodes are entities, edges are relations carrying properties. Built for relation-chain queries: friends of friends, also-bought, fund paths. The engine walks pointers instead of repeating JOINs.

The WAL family: same job, different names. Any engine that must not lose an acknowledged write keeps a write-ahead log; only the name changes: Cassandra commitlog, MongoDB journal, Redis AOF (see wal).

Cassandra write path. A write goes to the coordinator, lands in the commitlog on disk (append-only) and in the memtable in memory, and only then is acknowledged. When the memtable fills, it flushes to an immutable SSTable on disk.

Commitlog segments have a fixed size (32 MB by default) and roll: a full segment closes, a new one opens. Reclaim granularity is the whole segment: a segment is deletable only when everything in it has flushed. And a down replica's writes never reached it, so its commitlog cannot restore them: the commitlog is local crash recovery, not replica catch-up.

Version models, contrasted.

  • Cassandra/HBase: timestamp multi-version. SSTables are immutable, so writes append and never overwrite in place. The same key written twice lives in several places (memtable plus older SSTables). A read merges them and picks by timestamp: last-write-wins. It reads like a hash map (one visible value) but stores many.
  • MongoDB (WiredTiger): snapshot mvcc. A B-tree with logically in-place updates: one current copy on disk. Multi-version lives in memory update chains, giving concurrent reads a snapshot; old versions are cleaned after readers and checkpoints. Multi-document transactions (4.0+) rest on this: a transaction reads the snapshot as of its start, sees its own writes, and aborts with WriteConflict if someone else changed a document it writes; the client retries the whole transaction. Snapshot isolation, not serializable.
  • Deletes in LSM land are writes too: a tombstone carrying a timestamp wins reads until compaction drops it after gc_grace_seconds.

Replica consistency versus isolation: two different axes. The relational side has one primary deciding, and concurrency is governed by isolation-levels. Cassandra has no leader at all (Dynamo-style quorum, NOT Raft): all nodes are equal.

  • Replication factor is set at keyspace creation: RF=3 means three machines each hold a copy.
  • Consistency level is chosen per operation: ONE (one acknowledgement), QUORUM (majority), ALL (every copy).
  • R + W > N guarantees a read meets the new value: any two majorities of three overlap in at least one node.

Catch-up when a replica is down. Hinted handoff: the coordinator stores the write as a hint and replays it when the replica returns (default 3-hour window; past it, hints are dropped). Read repair: a later read finds a stale replica and the coordinator pushes the new version. Anti-entropy repair (nodetool repair, Merkle trees) is the backstop. Boundary: the only consensus inside Cassandra is lightweight transactions (IF NOT EXISTS, CAS) via Paxos, not Raft, and not on the daily read/write path.

Why it is rarely seen in small-team circles. Heavy operations (compaction, tombstones, repair, JVM tuning); a constrained query model (partition-key-first design, no JOINs, ALLOW FILTERING scans); no cross-partition transactions or strong consistency; and its home ground (massive write-heavy, multi-datacenter workloads) has been split by specialized systems. It is not dead: it is still used at scale where that workload exists (Netflix, Apple, Discord have talked about theirs publicly). It is just not a general-purpose default.

à propos de cette entrée

L'une des entrées de wiki de sijie. L'IA sur ce site est fondée sur le même corpus et répond à la voix de sijie, avec citations revenant à des entrées comme celle-ci — répondre coûte argent à sijie, donc cela attend derrière un code : entrer un code d'accès →