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.