Hệ thống Dữ liệu Phân tán/Partition theo key-range vs hash — và bài toán hot spot
15/38
Bài 15 / 38~12 phútPhân mảnh (partitioning)Miễn phí lượt xem

Partition theo key-range vs hash — và bài toán hot spot

Hai cách chia dữ liệu ra partition: theo dải khoá (range) giữ thứ tự nhưng dễ hot spot, hay theo hash phân bố đều nhưng mất range query. Đánh đổi và skew.

TL;DR: Có hai cách cơ bản chia dữ liệu ra partition. Key-range: mỗi partition giữ một dải khoá liền nhau (a–f, g–m, ...), giữ thứ tự nên range query nhanh — nhưng dễ hot spot khi ghi dồn vào một dải (ví dụ khoá là timestamp, mọi ghi mới rơi vào partition cuối). Hash: băm khoá rồi chia theo giá trị hash, phân bố đều nên chống hot spot — nhưng mất thứ tự, range query phải hỏi mọi partition. Không cách nào thắng tuyệt đối: range đổi phân bố đều lấy range query; hash đổi range query lấy phân bố đều. Và cả hai vẫn có thể skew nếu một khoá đơn lẻ quá nóng (một celebrity, một sản phẩm viral) — lúc đó phải xử riêng khoá đó.

Module trước giữ cùng dữ liệu trên nhiều bản. Giờ ta chia khác dữ liệu ra nhiều node — và quyết định đầu tiên, quan trọng nhất, là chia theo cái gì. Chọn sai làm một node gánh gần hết tải trong khi các node khác ngồi chơi (hot spot), phá tan lợi ích của việc chia.

Bài này so hai cách chia, chỉ ra đánh đổi cốt lõi (phân bố đều ↔ range query), và cảnh báo cái bẫy skew mà cả hai đều dính.

Nhớ lại Hash function

Bạn đã học hàm hash biến một khoá bất kỳ thành một số phân bố đều, cố tình phá vỡ mọi thứ tự để tránh cụm. Chính tính chất "phân bố đều, xoá thứ tự" đó là lý do hash partition chống hot spot nhưng mất range query — hai mặt của cùng một đồng xu.

1. Analogy — thư viện xếp sách theo vần vs theo số ngẫu nhiên

Một thư viện lớn chia sách ra nhiều phòng. Cách A: xếp theo vần tên (phòng A–F, G–M, N–Z). Tìm một dải ("mọi sách vần L–N") cực nhanh — đi thẳng vào đúng phòng. Nhưng nếu tự dưng ai cũng mượn sách vần "H" (một tác giả nổi bật), phòng G–M quá tải trong khi các phòng khác vắng.

Cách B: mỗi sách dán một số ngẫu nhiên, chia phòng theo số. Lượng khách vào mỗi phòng đều nhau (không phòng nào bị dồn). Nhưng muốn "mọi sách vần L–N" thì chịu — chúng rải khắp mọi phòng, phải đi hỏi tất cả.

Thư việnPartitioning
Xếp theo vần (A–F, G–M...)Key-range partition
Tìm một dải vần cực nhanhRange query nhanh
Phòng "H" quá tải khi vần H hotHot spot
Dán số ngẫu nhiên, chia theo sốHash partition
Khách vào mỗi phòng đều nhauPhân bố đều, chống hot spot
Tìm một dải vần = hỏi mọi phòngRange query = scatter/gather
💡 Cách nhớ

Range = xếp theo vần (tìm dải nhanh, dễ dồn một phòng). Hash = dán số ngẫu nhiên (đều tải, mất tìm-theo-dải). Chọn theo việc bạn hay hỏi kiểu nào.

Hai cach chia canh nhau, moi ben mot dong duoc va mot dong tra

2. Key-range partition — giữ thứ tự, nhưng dễ hot spot

Chia không gian khoá thành các dải liền nhau, mỗi partition giữ một dải: partition 1 giữ khoá af, partition 2 giữ gm, ... Ranh giới dải chọn theo phân bố dữ liệu để mỗi partition cỡ nhau.

Điểm mạnh — range query. Vì khoá trong partition đã sắp xếp và các partition liền dải, một truy vấn WHERE key BETWEEN 'g' AND 'j' chỉ chạm đúng partition chứa dải đó, quét tuần tự. Đây là điều hash không làm được.

Điểm yếu — hot spot khi khoá không đều. Cạm bẫy kinh điển: khoá là timestamp (hoặc ID tăng dần). Mọi ghi mới đều có timestamp lớn nhất → rơi vào cùng một partition cuối. Kết quả: partition đó nhận toàn bộ tải ghi, còn các partition khác chỉ giữ dữ liệu cũ, hầu như không được ghi.

Khoa = timestamp, range partition:
  partition A: 00:00-08:00 (du lieu cu, it ghi)
  partition B: 08:00-16:00 (du lieu cu)
  partition C: 16:00-now   <- MOI ghi moi roi vao day -> HOT SPOT
=> chia ra nhieu node nhung chi 1 node nhan tai ghi.

Cách chữa thường là đổi khoá: ghép một tiền tố phân tán vào trước timestamp (ví dụ <sensor_id>-<timestamp>), để ghi rải theo sensor_id — nhưng lúc đó range query "mọi dữ liệu trong giờ qua" lại phải hỏi nhiều partition. Đánh đổi không biến mất, chỉ dời chỗ.

3. Hash partition — phân bố đều, nhưng mất range query

Áp một hàm hash lên khoá để ra một số phân bố đều, rồi chia partition theo dải giá trị hash (hoặc theo consistent hashing — bài sau). Vì hash rải khoá đều bất kể phân bố gốc, tải ghi/đọc phân bố đều — kể cả khi khoá gốc là timestamp tăng dần (hash của các timestamp liền nhau rơi rải rác).

Điểm mạnh — chống hot spot theo dải. Không còn "partition cuối" nhận mọi ghi mới; các khoá liền nhau về giá trị bị hash tán đi khắp nơi.

Điểm yếu — mất thứ tự. Chính vì hash phá thứ tự, hai khoá liền nhau (user1001, user1002) rơi vào hai partition cách xa. Một range query giờ không có "dải" để đi — phải hỏi mọi partition rồi gộp (scatter/gather), chậm và tốn.

Khoa = timestamp, hash partition:
  hash(16:00:01) -> partition A
  hash(16:00:02) -> partition C   <- ghi lien nhau tan ra -> DEU tai
  hash(16:00:03) -> partition B
  Nhung: "moi ban ghi 16:00-17:00" -> phai hoi CA A,B,C roi gop.

4. Skew — vì sao hash cũng không cứu được "celebrity key"?

Hash chia đều theo số lượng khoá, nhưng không đều theo tải trên một khoá. Nếu một khoá đơn lẻ cực nóng — tài khoản của một người nổi tiếng nhận hàng triệu tương tác, một sản phẩm viral — thì mọi thao tác lên khoá đó hash về cùng một partition. Partition đó nóng rực dù tổng thể phân bố "đều". Đây là skew ở mức khoá, và cả range lẫn hash đều dính.

⚠️ Hash không chia nhỏ được một khoá nóng

Hash phân bố đều giữa các khoá khác nhau, không trong một khoá. hash(celebrity_id) luôn ra cùng một partition — thêm node cũng vô ích cho khoá đó. Cách xử phải làm ở tầng ứng dụng: thêm hậu tố ngẫu nhiên vào khoá nóng (celebrity_id-00..celebrity_id-09) để tách nó ra 10 partition, đổi lại đọc phải gộp 10 mảnh. Hệ thường chỉ áp mẹo này cho một số ít khoá được phát hiện là nóng, không cho mọi khoá.

5. Pitfall — chọn cách chia theo thói quen, không theo pattern truy vấn

Pitfall — hash mọi thứ, rồi ngạc nhiên vì range query chậm

Vì hash "nghe an toàn" (chống hot spot), nó hay được chọn mặc định cho mọi bảng — kể cả bảng mà truy vấn chính là range.

❌ Bang su kien, truy van chinh: "moi su kien trong 24h qua"
   -> chon HASH partition (vi so hot spot)
   -> range query nay bien thanh scatter/gather MOI partition -> cham

❌ Bang ghi log theo thoi gian -> chon RANGE theo timestamp
   -> moi ghi don vao partition cuoi -> hot spot ghi

Cả hai đều sai vì chọn cách chia không khớp pattern truy vấn/ghi thật.

Hướng đúng: chọn theo pattern truy cập chi phối. Nếu truy vấn chính là range theo khoá (thời gian, thứ tự) → key-range, và xử hot spot bằng cách đổi khoá (thêm tiền tố phân tán) nếu cần. Nếu truy cập chủ yếu là điểm theo khoá (tra một user, một order) và sợ hot spot → hash. Với khoá nóng đơn lẻ, xử riêng bằng hậu tố. Không có "cách chia mặc định" đúng cho mọi bảng.

6. 📚 Deep Dive

📚 Deep Dive — Partitioning of key-value data

Ghi chú: DDIA Ch6 là nguồn agnostic chuẩn. Điểm cốt lõi cần mang theo: cách chia quyết định cả phân bố tải lẫn loại truy vấn nào rẻ — chọn nó là chọn trước cả hai.

7. Liên hệ các bài khác

  • Module 2 — Nhân bản: partition không sống một mình — mỗi partition thường lại được nhân bản; "node giữ partition P" là "nhóm bản của P".
  • Bài 02 — Consistent hashing: hash partition đặt ra câu hỏi "thêm/bớt node thì xáo dữ liệu thế nào" — consistent hashing trả lời.
  • Bài 04 — Request routing: chia xong thì client tìm đúng partition ở đâu — bài routing.
  • Module 1 — Scalability: partitioning chính là hình thức scale-out cho dữ liệu; hot spot là lý do "chia ra" không tự động "nhanh hơn".

8. Tóm tắt

  • Key-range: giữ thứ tự → range query nhanh; nhưng hot spot khi ghi dồn vào một dải (khoá timestamp/tăng dần).
  • Hash: phân bố đều → chống hot spot theo dải; nhưng mất thứ tự → range query thành scatter/gather.
  • Đánh đổi cốt lõi: phân bố đều (hash) ↔ range query (range) — chọn theo pattern truy vấn chi phối.
  • Skew: cả hai vẫn hỏng nếu một khoá đơn lẻ quá nóng; hash không chia nhỏ được một khoá — phải thêm hậu tố tách riêng.

9. Tự kiểm tra

Tự kiểm tra
0/5 câu đã trả lời
  1. Q1
    Nêu đánh đổi cốt lõi giữa key-range và hash partition. Vì sao không thể có cả 'phân bố đều' lẫn 'range query nhanh' từ một cách chia đơn giản?
  2. Q2
    Vì sao dùng timestamp làm khoá với key-range partition gây hot spot? Cách chữa và cái giá của nó?
  3. Q3
    Range query trên hash partition tệ ở điểm nào, và vì sao 'scatter/gather' là hệ quả bắt buộc?
  4. Q4
    Vì sao hash partition KHÔNG giải quyết được 'celebrity key' (một khoá cực nóng)? Cách xử lý là gì?
  5. Q5
    Một bảng log sự kiện IoT: ghi rất nhiều (theo thời gian), và truy vấn chính là 'mọi sự kiện của thiết bị X trong khoảng thời gian T'. Chọn cách chia nào và vì sao?

Bài tiếp theo: Consistent hashing & rebalancing

Bài này đáng gửi cho bạn học cùng?

Copy link đã gắn nguồn — dán group, chat, hoặc LinkedIn.

Bài này có giúp bạn hiểu bản chất không?

Hỏi đáp về bài này

Chưa có câu hỏi

Đặt câu hỏi

Có gì chưa rõ trong bài? Đặt câu hỏi đầu tiên — câu trả lời từ cộng đồng giúp bạn (và người sau).

Đặt câu hỏi đầu tiên

Bài tiếp theo

Consistent hashing & rebalancing — thêm/bớt node ít xáo trộn