Chapter 04 · Keyspaces, Replication Strategies, Replication Factor, and Placement
Why SimpleStrategy Is for Limited / Legacy Scenarios and Not Production Multi-Rack Design
Prove why SimpleStrategy is a limited/legacy choice rather than a production multi-rack replication design.
Learning outcomes
A SimpleStrategy keyspace can appear healthy in a tiny cluster, which makes it dangerous to learn from screenshots alone. AtlasMart needs to understand the strategy semantics: it walks replica positions without a production datacenter/rack contract.
Define SimpleStrategy precisely and identify the topology information it ignores.
Compare SimpleStrategy and NTS schema maps side by side.
Inspect several endpoint samples without treating coincidence as guarantee.
Explain why a small lab cannot validate multi-rack production placement.
Convert a disposable keyspace to NTS and identify the repair obligation.
Apache Cassandra 5.0.9 is the current GA 5.0 patch as of 7
September 2026. The pinned Docker Official Image
cassandra:5.0.9 uses Java 17. The course cluster
is atlasmart-course, one DC (dc1),
three rack labels, 16 vnodes per node, no TLS/auth in this
isolated chapter lab, and no host-published CQL/JMX ports.
Docker and Cassandra are unavailable in this generation environment. Commands and result shapes were checked against current official Cassandra documentation, but outputs are expected shapes rather than fabricated captured runs. Record exact values on your own disposable cluster.
Reusable Chapter 04 lab topology
Continue the Chapter 01–03 naming and failure-domain conventions. The rack labels let Cassandra exercise rack-aware placement, but all containers still share one physical host, so the lab demonstrates placement semantics rather than true rack/AZ isolation. Require all three nodes to be Up/Normal before interpreting replica evidence.
docker network create atlasmart-cassandradocker volume create atlasmart-cass-1-datadocker volume create atlasmart-cass-2-datadocker volume create atlasmart-cass-3-datadocker run -d --name atlasmart-cass-1 --hostname atlasmart-cass-1 --network atlasmart-cassandra -e CASSANDRA_CLUSTER_NAME=atlasmart-course -e CASSANDRA_DC=dc1 -e CASSANDRA_RACK=rack1 -e CASSANDRA_ENDPOINT_SNITCH=GossipingPropertyFileSnitch -e CASSANDRA_NUM_TOKENS=16 -v atlasmart-cass-1-data:/var/lib/cassandra cassandra:5.0.9# Wait until node 1 accepts CQL before starting peers.docker run -d --name atlasmart-cass-2 --hostname atlasmart-cass-2 --network atlasmart-cassandra -e CASSANDRA_CLUSTER_NAME=atlasmart-course -e CASSANDRA_SEEDS=atlasmart-cass-1 -e CASSANDRA_DC=dc1 -e CASSANDRA_RACK=rack2 -e CASSANDRA_ENDPOINT_SNITCH=GossipingPropertyFileSnitch -e CASSANDRA_NUM_TOKENS=16 -v atlasmart-cass-2-data:/var/lib/cassandra cassandra:5.0.9docker run -d --name atlasmart-cass-3 --hostname atlasmart-cass-3 --network atlasmart-cassandra -e CASSANDRA_CLUSTER_NAME=atlasmart-course -e CASSANDRA_SEEDS=atlasmart-cass-1 -e CASSANDRA_DC=dc1 -e CASSANDRA_RACK=rack3 -e CASSANDRA_ENDPOINT_SNITCH=GossipingPropertyFileSnitch -e CASSANDRA_NUM_TOKENS=16 -v atlasmart-cass-3-data:/var/lib/cassandra cassandra:5.0.9docker exec atlasmart-cass-1 nodetool statusdocker exec atlasmart-cass-1 nodetool versiondocker exec atlasmart-cass-1 java -version
docker network create atlasmart-cassandradocker volume create atlasmart-cass-1-datadocker volume create atlasmart-cass-2-datadocker volume create atlasmart-cass-3-datadocker run -d --name atlasmart-cass-1 --hostname atlasmart-cass-1 --network atlasmart-cassandra -e CASSANDRA_CLUSTER_NAME=atlasmart-course -e CASSANDRA_DC=dc1 -e CASSANDRA_RACK=rack1 -e CASSANDRA_ENDPOINT_SNITCH=GossipingPropertyFileSnitch -e CASSANDRA_NUM_TOKENS=16 -v atlasmart-cass-1-data:/var/lib/cassandra cassandra:5.0.9# Wait until node 1 accepts CQL before starting peers.docker run -d --name atlasmart-cass-2 --hostname atlasmart-cass-2 --network atlasmart-cassandra -e CASSANDRA_CLUSTER_NAME=atlasmart-course -e CASSANDRA_SEEDS=atlasmart-cass-1 -e CASSANDRA_DC=dc1 -e CASSANDRA_RACK=rack2 -e CASSANDRA_ENDPOINT_SNITCH=GossipingPropertyFileSnitch -e CASSANDRA_NUM_TOKENS=16 -v atlasmart-cass-2-data:/var/lib/cassandra cassandra:5.0.9docker run -d --name atlasmart-cass-3 --hostname atlasmart-cass-3 --network atlasmart-cassandra -e CASSANDRA_CLUSTER_NAME=atlasmart-course -e CASSANDRA_SEEDS=atlasmart-cass-1 -e CASSANDRA_DC=dc1 -e CASSANDRA_RACK=rack3 -e CASSANDRA_ENDPOINT_SNITCH=GossipingPropertyFileSnitch -e CASSANDRA_NUM_TOKENS=16 -v atlasmart-cass-3-data:/var/lib/cassandra cassandra:5.0.9docker exec atlasmart-cass-1 nodetool statusdocker exec atlasmart-cass-1 nodetool versiondocker exec atlasmart-cass-1 java -version
Capture
SELECT cluster_name, data_center, rack, release_version FROM
system.local;,
SELECT peer, data_center, rack, release_version FROM
system.peers_v2;, and nodetool status. If those disagree with the
intended topology, stop and fix the lab rather than explaining
placement from bad metadata.
1. SimpleStrategy has one cluster-wide RF
SimpleStrategy accepts a single
replication_factor and does not express RF
independently per datacenter. It is not the normal production
choice because it does not deliberately respect datacenter/rack
layouts. NTS is the production-ready strategy documented for
topology-aware placement.
| Question | SimpleStrategy | NTS |
|---|---|---|
| RF syntax | One replication_factor | RF per DC |
| Rack-aware placement | No production rack policy | Rack-aware where topology permits |
| Multi-DC design | Not appropriate | Designed for it |
2. Build the wrong and right keyspaces together
docker exec atlasmart-cass-1 cqlsh -e "DROP KEYSPACE IF EXISTS atlasmart_simple_wrong; CREATE KEYSPACE atlasmart_simple_wrong WITH replication = {'class':'SimpleStrategy','replication_factor':3}; CREATE TABLE atlasmart_simple_wrong.inventory_by_sku (sku text PRIMARY KEY, quantity int); INSERT INTO atlasmart_simple_wrong.inventory_by_sku (sku,quantity) VALUES ('sku-1001',42);"docker exec atlasmart-cass-1 cqlsh -e "CREATE KEYSPACE IF NOT EXISTS atlasmart_replication WITH replication = {'class':'NetworkTopologyStrategy','dc1':3}; CREATE TABLE IF NOT EXISTS atlasmart_replication.inventory_by_sku (sku text PRIMARY KEY, quantity int); INSERT INTO atlasmart_replication.inventory_by_sku (sku,quantity) VALUES ('sku-1001',42);"docker exec atlasmart-cass-1 cqlsh -e "SELECT keyspace_name, replication FROM system_schema.keyspaces WHERE keyspace_name IN ('atlasmart_simple_wrong','atlasmart_replication');"
The schema already proves the semantic difference. Endpoint samples are supporting evidence, not the definition of the strategies.
3. Compare multiple replica samples
for k in sku-1001 sku-1002 sku-1003 sku-2001 sku-3001; do echo "=== $k SimpleStrategy ===" docker exec atlasmart-cass-1 nodetool getendpoints atlasmart_simple_wrong inventory_by_sku "$k" echo "=== $k NTS ===" docker exec atlasmart-cass-1 nodetool getendpoints atlasmart_replication inventory_by_sku "$k"done
Your tiny three-node ring may accidentally produce similar endpoint sets for both strategies. That does not rehabilitate SimpleStrategy: the review question is whether the strategy contains the required failure-domain rule, not whether one sample happened to look balanced.
4. Repair the anti-pattern safely
docker exec atlasmart-cass-1 cqlsh -e "ALTER KEYSPACE atlasmart_simple_wrong WITH replication = {'class':'NetworkTopologyStrategy','dc1':3};"docker exec atlasmart-cass-1 cqlsh -e "SELECT keyspace_name, replication FROM system_schema.keyspaces WHERE keyspace_name='atlasmart_simple_wrong';"docker exec atlasmart-cass-1 nodetool repair --preview --full atlasmart_simple_wrong inventory_by_skudocker exec atlasmart-cass-1 nodetool repair --full atlasmart_simple_wrong inventory_by_sku
The ALTER changes desired placement metadata. Existing data may still need repair to converge to the new placement. Do not manually manipulate tokens or relabel an established cluster just to force a dramatic screenshot.
5. Production judgment
Keep SimpleStrategy confined to explicit limited/legacy situations where its topology limitations are accepted. AtlasMart's production design cares about rack/DC failure domains, so NTS is the defensible strategy.
Verification checklist
- You created both strategy types.
- You inspected schema before endpoint samples.
- You did not claim one lucky sample proves rack safety.
- You changed the disposable keyspace to NTS.
- You treated repair as separate from schema agreement.
Check your understanding
- Why can SimpleStrategy look okay in a tiny lab?
- What is the decisive production problem?
- Does ALTER to NTS copy historical data immediately?
- Why avoid manual-token tricks here?
- What comes next?
Review the answers
1. Token order can accidentally spread replicas; that is not a topology-aware guarantee.
2. Its replication contract does not model the required DC/rack failure domains.
3. No; repair may be needed for convergence.
4. They add unrelated topology/streaming risk and obscure the strategy lesson.
5. Choose RF and CL from availability/consistency requirements.
Cleanup/reset
Remove only the disposable course-owned containers, volumes, and network. Never copy these cleanup commands into production.
docker rm -f atlasmart-cass-1 atlasmart-cass-2 atlasmart-cass-3 2>/dev/null || truedocker volume rm atlasmart-cass-1-data atlasmart-cass-2-data atlasmart-cass-3-data 2>/dev/null || truedocker network rm atlasmart-cassandra 2>/dev/null || true
docker rm -f atlasmart-cass-1 atlasmart-cass-2 atlasmart-cass-3 2>$nulldocker volume rm atlasmart-cass-1-data atlasmart-cass-2-data atlasmart-cass-3-data 2>$nulldocker network rm atlasmart-cassandra 2>$null
Summary and next step
This lesson’s concepts, evidence path, failure boundaries, and production judgment should now be explicit enough to verify rather than assume. Re-run the check-your-understanding prompts and preserve any lab evidence you need before changing or cleaning up the environment.
Next, continue to Replication Factor, Failure Tolerance, Storage Cost, and Consistency-Level Math.
Authoritative references
- Apache Cassandra downloads — current GA version evidence.
- CQL data definition — CREATE/ALTER KEYSPACE, NTS, SimpleStrategy, RF, durable_writes.
- Repair — incremental/full repair, preview, and RF increase implications.
- Cassandra FAQ — RF increase/decrease operational guidance.
- nodetool — status, getendpoints, repair, cleanup and related operator commands.
- Docker Official Image 5.0 Dockerfile — Cassandra 5.0.9 + Java 17 image baseline.