Cassandra Architecture
The ring, the write and read paths, and how the storage engine turns writes into SSTables.
Ring Architecture
Cassandra hashes the partition key with Murmur3 to produce a token. The token space is divided among nodes, and each node owns the ranges assigned to it. Replicas are placed on the next nodes clockwise around the ring, respecting rack and datacenter awareness.
There is no primary node and no metadata server. Any node can coordinate any request: it computes the token, identifies the replicas, and forwards the operation to them.
nodetool status # nodes, state, ownership percentage, datacenter and rack
nodetool ring # token ranges per node
nodetool describecluster # schema agreement across the clusterWrite path
- The write is appended to the commit log on disk (durability).
- It is applied to the memtable in memory for that table.
- The coordinator waits for as many replica acknowledgements as the consistency level requires.
- When the memtable reaches its threshold, it is flushed to an immutable SSTable.
- Compaction merges SSTables in the background.
Writes never read before writing. There is no read-modify-write, no in-place update, and no
uniqueness check — which is exactly why writes scale linearly and why an INSERT and an UPDATE
are the same operation (an upsert).
Read path
- The coordinator identifies the replicas for the partition.
- It contacts as many as the consistency level requires.
- Each replica merges data from its memtable and its SSTables, using a bloom filter per SSTable to skip those that cannot contain the key, then the partition index.
- The coordinator resolves conflicts by cell timestamp, newest wins.
- If replicas disagree, read repair may write the newest value back to the stale ones.
Reads are more expensive than writes, and their cost grows with the number of SSTables a partition spans — which is what compaction strategy controls.
# How many SSTables a read touches, per table. Rising values mean compaction is behind.
nodetool tablehistograms shop events_by_user
nodetool tablestats shop.events_by_userTimestamps and last-write-wins
Every cell carries a timestamp, and conflicts are resolved by taking the highest. Two consequences:
Conflict resolution is per cell, not per row, so two concurrent updates to different columns of the same row both survive. That is usually helpful and occasionally surprising.
Storage components
- Commit log — sequential, shared by all tables on the node. Put it on its own device where possible.
- Memtable — per table, in memory, flushed on size or time thresholds.
- SSTable — immutable sorted files with bloom filters, partition indexes and compression.
- Hints — writes stored by a coordinator for a replica that was down; see Hinted Handoff.