---
id: database-cassandra
title: "Cassandra"
shortTitle: "Cassandra"
track: database
trackTitle: "Database"
order: 4
level: important
status: published
estimatedMinutes: 30
prerequisites:
  - database-sqlserver
next: database-dynamodb
reviewedAgainst: 2026-10-12
sources:
  - title: "Cassandra documentation"
    url: https://cassandra.apache.org/doc/latest/
  - title: "CREATE KEYSPACE"
    url: https://cassandra.apache.org/doc/latest/cassandra/cql/ddl.html
---

# Cassandra

Cassandra là database phân tán, đọc ghi theo partition key. Không có join như PostgreSQL. Bài này để đọc được keyspace và replication, không để dựng cụm.

## Để làm gì

Viết một `CREATE KEYSPACE` đúng replication, và biết vì sao query không kèm partition key thì cụm phải hỏi mọi node.

## Gồm những gì

- Keyspace, table, partition key.
- Replication factor.
- Khác database SQL ở chỗ Cassandra không gom cụm về một máy primary như Postgres.

Không gồm sửa `cassandra.yaml` của production, hay thêm node vào ring.

## Dùng khi nào

Dữ liệu ghi nhiều, tra theo một khóa rõ, và team chấp nhận không join. Nếu app cần transaction nhiều bảng, ở lại PostgreSQL hoặc SQL Server.

Đừng chọn Cassandra chỉ vì sơ đồ ghi chữ “scale”. Một node lab không cho thấy replication factor 3 hoạt động thế nào.

## Kiến thức cốt lõi

Mỗi dòng nằm trong partition do partition key xác định. Các node khác giữ bản sao theo replication factor. Factor 3 nghĩa là ba bản. Ghi thành công khi đủ số bản mà consistency level yêu cầu. `LOCAL_QUORUM` là đa số trong một datacenter.

Query có partition key thì coordinator biết node nào giữ dữ liệu. Query chỉ lọc cột không phải key thì Cassandra phải đọc rộng. Đó là full cluster scan, không phải index nhỏ bạn quen ở SQL.

`CREATE KEYSPACE ... WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}` chỉ hợp một cụm lab một datacenter. Production nhiều datacenter dùng `NetworkTopologyStrategy` và khai số bản theo từng tên datacenter. Docs DDL của Cassandra nói rõ SimpleStrategy không phải lựa chọn production.

## Lệnh và code mẫu

CQL, không cần cụm để đọc:

```sql
CREATE KEYSPACE lab WITH replication = {
  'class': 'SimpleStrategy',
  'replication_factor': 1
};

CREATE TABLE lab.session (
  user_id text,
  created_at timestamp,
  token text,
  PRIMARY KEY (user_id, created_at)
);
```

`user_id` là partition key. `created_at` là clustering column, sắp trong partition.

Container chính thức nặng và khởi động lâu. Chỉ chạy nếu máy lab còn RAM:

```bash
docker rm -f lab-cassandra
docker run -d --name lab-cassandra cassandra:5
docker logs -f lab-cassandra
```

Dừng theo dõi khi log báo sẵn sàng, rồi `docker rm -f lab-cassandra` nếu bạn không định dùng tiếp. Không có RAM trống thì bỏ khối docker.

## Thực hành

1. Đọc câu `CREATE TABLE` và chỉ ra cột nào là partition key.
2. Viết một câu `SELECT` có `WHERE user_id = 'a1'`.
3. Không tạo keyspace trên cụm dùng chung.

## Kết quả mong đợi

Partition key là `user_id`. Câu SELECT có khóa đó. Bạn không để lại container Cassandra nếu đã chạy thử.

## Checklist

- [ ] Mọi query đường nóng đều có partition key.
- [ ] Production dùng `NetworkTopologyStrategy`, không để `SimpleStrategy`.
- [ ] Replication factor và consistency level được ghi trong thiết kế, không để mặc định của máy dev.

## Lỗi thường gặp

**`ALLOW FILTERING` trên bảng lớn.** Cassandra đọc nhiều partition rồi mới lọc. Lệnh chạy trên lab vài dòng, rồi timeout trên dữ liệu thật. Đổi khóa hoặc bảng cho đúng đường đọc.

**Replication factor 1 trên cụm ba node.** Một node chết là mất partition nằm ở node đó. Lab một máy mới dùng factor 1.

## Nguồn

1. [Cassandra documentation](https://cassandra.apache.org/doc/latest/) — mô hình dữ liệu phân tán.
2. [Data definition](https://cassandra.apache.org/doc/latest/cassandra/cql/ddl.html) — `CREATE KEYSPACE` và replication.

## Tiếp theo

[DynamoDB](./05-dynamodb.md)
