HDD, SSD, NVMe — ba cơ chế, ba thang độ trễ
Đĩa từ quay với đầu đọc cơ học, NAND flash phải xoá trước khi ghi cùng wear leveling, NVMe với hàng đợi song song — và hệ quả lên độ trễ, IOPS, tuổi thọ.
TL;DR: HDD chậm vì độ trễ của nó là chuyện cơ học — đầu đọc phải trượt tới đúng rãnh rồi chờ đĩa quay tới đúng chỗ, và với ổ 7200 vòng/phút thì riêng khoản chờ quay đã trung bình hơn 4 mili-giây. SSD bỏ hết phần cơ khí đó, nhưng mang về một luật lạ: nó ghi theo trang nhỏ mà xoá theo khối lớn hơn hàng trăm lần, và chính chênh lệch này đẻ ra write amplification cùng tuổi thọ hữu hạn. NVMe thì không phải một loại chip nhớ nào cả — nó là giao thức, và thứ nó đổi là số hàng đợi.
Một service ghi log chạy mượt sáu tháng trên máy ổ SSD. Rồi sau một năm, cũng máy đó, cũng workload đó, độ trễ ghi bắt đầu nhảy theo cơn — thỉnh thoảng một request đứng hình rồi mới trả về. Code không đổi dòng nào, đĩa vẫn còn trống 40%.
Chuyện này không giải thích nổi nếu bạn coi ổ đĩa là "chỗ cất dữ liệu, đọc ghi tuỳ ý". Phải xuống tới cơ chế: dữ liệu nằm trên vật liệu gì, sửa nó cần làm gì, và ai xếp hàng cho các yêu cầu.
1. Analogy — kho hồ sơ và cái luật lạ của tủ
Kho thứ nhất là băng chuyền tròn khổng lồ, hồ sơ gắn dọc vành, một cánh tay máy trượt ra vào để với tới đúng vòng. Lấy một tờ thì cánh tay phải trượt tới đúng vòng, rồi đứng chờ băng chuyền quay tới chỗ tờ giấy.
Kho thứ hai thay băng chuyền bằng bức tường đầy ô vuông đánh số — với tới ô nào cũng nhanh như nhau. Nhưng nội quy có điều kỳ quặc: viết vào ô trống thì được, còn muốn xoá thì phải xoá nguyên khay hàng trăm ô. Sửa một tờ trong khay đang đầy, bạn buộc phải chép những tờ còn dùng sang khay khác rồi mới đốt khay cũ.
Kho thứ ba không phải kho — nó là cái quầy tiếp nhận đứng trước kho, và số quầy mới là thứ nó đổi.
| Trong kho hồ sơ | Trong máy tính |
|---|---|
| Cánh tay trượt tới đúng vòng | Seek — đầu đọc HDD di chuyển tới đúng track |
| Đứng chờ băng chuyền quay tới | Rotational latency — chờ đĩa quay tới đúng sector |
| Bức tường ô vuông, với đâu cũng như nhau | NAND flash — không có bộ phận chuyển động |
| Viết vào ô trống thì được, xoá phải xoá cả khay | Ghi theo page, xoá theo erase block |
| Chép tờ còn dùng sang khay khác rồi đốt khay cũ | Garbage collection + write amplification |
| Số quầy tiếp nhận và sức chứa mỗi quầy | Queue depth — SATA/AHCI so với NVMe |
HDD trả tiền bằng chuyển động. SSD trả tiền bằng sự bất đối xứng giữa ghi và xoá. NVMe không đụng gì tới hai thứ trên — nó chỉ mở rộng hàng đợi.
2. HDD — độ trễ là một bài toán cơ học
Dữ liệu nằm trên những đĩa từ quay đều, và một đầu đọc trượt trên bề mặt để với tới từng vòng dữ liệu, gọi là track. Đọc một khối bất kỳ cần hai việc nối nhau: seek (trượt đầu đọc sang track chứa dữ liệu) rồi rotational latency (chờ mặt đĩa quay tới đúng sector). Khoản thứ hai tính được, chẳng cần benchmark nào:
7200 vong/phut = 120 vong/giay
1 vong = 1 / 120 s = 8,33 ms
Cho quay TB = 8,33 / 2 = 4,17 ms (request roi ngau nhien -> cho nua vong)
Neu tong (seek + cho quay) ~ 10 ms
-> 1 / 0,010 = ~100 thao tac ngau nhien / giay
Con số cỡ hàng trăm thao tác ngẫu nhiên mỗi giây không phải chuyện thương hiệu hay đời ổ — nó là hệ quả trực tiếp của tốc độ quay, mà tốc độ quay thì bị chặn bởi vật liệu và lực ly tâm. Đó là lý do IOPS ngẫu nhiên của HDD gần như đứng yên suốt hai chục năm trong khi dung lượng tăng cả nghìn lần.
Để ý một điều: hai khoản phạt này chỉ trả một lần cho mỗi lần nhảy chỗ. Đọc liền mạch thì đầu đọc đứng yên, đĩa cứ quay và dữ liệu cứ chảy ra.
Bạn đã dựng thang độ trễ ở đó: thanh ghi, L1/L2/L3, RAM, rồi đĩa, rồi mạng. Bài này đứng đúng ở nấc "đĩa" và mổ xem vì sao nấc đó xa các nấc trên đến vậy — mili-giây cơ học so với nano-giây điện tử.
3. Vì sao SSD chậm dần theo thời gian?
SSD lưu dữ liệu trong ô nhớ NAND flash nên hai khoản phạt cơ học biến mất sạch. Nhưng NAND mang theo ràng buộc riêng, và gần như mọi hành vi khó hiểu của SSD đều bắt nguồn từ đúng ràng buộc đó:
Muốn ghi lại giá trị cũ, ô NAND phải được xoá trước. Mà đơn vị ghi là page, còn đơn vị xoá là erase block — lớn hơn page rất nhiều.
Theo tài liệu kỹ thuật của SPDK, page cỡ vài tới vài chục kilobyte còn erase block nằm trong khoảng 1 MiB đến 8 MiB — chênh lệch giữa hai đơn vị mới là thứ đáng nhớ, không phải con số cụ thể. Sửa một khối 4 KB nằm giữa erase block đang đầy, ổ không ghi đè tại chỗ được:

Đây là write amplification: lượng dữ liệu thật sự chạm vào NAND lớn hơn nhiều lượng ứng dụng yêu cầu ghi. Phần dọn dẹp do một tầng firmware gọi là FTL (Flash Translation Layer) đảm nhiệm — nó giữ bản đồ giữa địa chỉ hệ điều hành nhìn thấy và vị trí vật lý thật, đồng thời chạy garbage collection ở nền.
Từ đây suy ra câu trả lời cho cảnh mở đầu. Còn nhiều block trống thì FTL dọn dẹp thong thả lúc rảnh; đĩa càng đầy thì garbage collection càng phải chen vào giữa các request thật, nên độ trễ nhảy theo cơn chứ không tăng đều. Nhà sản xuất chừa sẵn một phần dung lượng người dùng không thấy để giảm bớt chuyện này, gọi là over-provisioning.
Cùng ràng buộc đó đẻ ra hệ quả thứ hai: mỗi ô NAND chịu được số hữu hạn chu kỳ xoá-ghi rồi mòn, nên firmware cố ý rải các lần ghi đều khắp ổ — đó là wear leveling.
4. NVMe khác SSD SATA ở chỗ nào?
Người ta hay nói "ổ SSD" với "ổ NVMe" như hai loại để chọn một, nhưng chúng không cùng trục so sánh. SSD nói về vật liệu lưu trữ; NVMe nói về giao thức mà CPU dùng để ra lệnh cho ổ. Một ổ hoàn toàn có thể vừa là SSD vừa nói giao thức SATA — đó chính là SSD SATA thông thường.
| Giao thức | Số hàng đợi | Lệnh mỗi hàng đợi |
|---|---|---|
| SATA / AHCI | 1 | 32 (NCQ) |
| NVMe | tới 65.535 | tới 65.535 |
AHCI được thiết kế cho thời đĩa quay, khi thiết bị bên dưới chỉ có một đầu đọc vật lý. Xếp hàng dài hơn cũng vô ích; 32 lệnh đủ để ổ sắp lại thứ tự sao cho đầu đọc di chuyển ít nhất.
NAND thì khác hẳn: bên trong một SSD có nhiều chip, nhiều kênh chạy song song thật, nên bắt chúng xếp qua một hàng đợi duy nhất là tự trói tay. NVMe sinh ra để cởi nút đó, và nó nói chuyện thẳng qua PCIe — cũng chính là bus mà card đồ hoạ dùng.
Điều đáng nhớ nhất mục này là: NVMe không chỉ làm ổ nhanh hơn, nó làm hỏng cách bạn đo xem ổ có bận hay không. Khi thiết bị phục vụ hàng nghìn yêu cầu song song, bận theo nghĩa "có việc" khác hẳn bận theo nghĩa "hết chỗ nhận việc" — bạn sẽ gặp lại đúng chuyện này ở module 3 với chỉ số %util.
5. Pitfall của riêng concept này
❌ Nhầm 1 — coi "SSD" và "NVMe" là hai loại thiết bị để chọn một.
✅ Hai từ nằm ở hai tầng khác nhau: SSD là vật liệu, NVMe là giao thức. Câu hỏi đúng khi mua ổ là hai câu tách bạch — vật liệu gì, và nói giao thức nào.
❌ Nhầm 2 — tin rằng ổ còn trống nhiều thì không có gì phải lo.
✅ "Còn trống" theo hệ điều hành khác "còn block đã xoá sẵn" theo firmware; ổ vừa xoá nhiều file vẫn có thể đầy block bẩn chờ dọn. Đây là lý do TRIM tồn tại — nó báo cho ổ biết block nào không cần nữa, để firmware xoá lúc rảnh thay vì xoá gấp giữa lúc bạn đang ghi.
❌ Nhầm 3 — lấy IOPS ghi trên tờ quảng cáo làm số để thiết kế hệ thống.
✅ Số quảng cáo đo trên ổ mới tinh, còn nhiều block trống, đo ngắn nên garbage collection chưa kịp chen vào. Muốn số dùng được thì phải đo trên ổ đã ghi bão hoà.
6. 📚 Đào sâu (tuỳ chọn)
- SPDK — NAND Flash SSD Internals — erase-before-write, kích thước erase block, vai trò FTL và over-provisioning. Nguồn cho các con số hình học NAND ở mục 3.
- fsync(2) — man7.org — vì sao "ổ đã nhận dữ liệu" và "dữ liệu đã bền" là hai chuyện khác nhau.
Ghi chú: số liệu hiệu năng SSD công khai phần lớn đến từ nhà sản xuất và gắn chặt với model. Cơ chế thì ổn định qua nhiều đời, con số thì không.
7. Liên hệ các bài khác
- Tuần tự vs ngẫu nhiên — lấy hai khoản phạt cơ học ở mục 2 và ràng buộc erase block ở mục 3 để giải thích vì sao kiểu truy cập quyết định hiệu năng nhiều hơn cả loại ổ.
- fsync và độ bền — ổ đĩa còn bộ đệm riêng bên trong; dữ liệu có thể nằm đúng đó khi mất điện.
- Mini-challenge — đo ổ đĩa của chính bạn — tự kiểm chứng mọi con số ở bài này trên phần cứng thật.
- Đo I/O bằng iostat — hệ quả trực tiếp của bảng hàng đợi ở mục 4.
8. Tóm tắt
- Chờ quay của HDD tính được từ tốc độ vòng: 7200 vòng/phút cho ra trung bình 4,17 mili-giây, chưa kể seek — nên một luồng chỉ đạt cỡ trăm thao tác ngẫu nhiên mỗi giây. Hai khoản phạt này chỉ trả khi nhảy chỗ.
- NAND ghi theo page nhưng xoá theo erase block cỡ 1–8 MiB; chênh lệch này sinh ra write amplification, garbage collection và wear leveling.
- Ổ SSD chậm dần khi đầy vì firmware hết block trống để xoay xở, phải dọn dẹp xen vào giữa các request thật — nên độ trễ nhảy theo cơn.
- NVMe là giao thức trên PCIe, không phải loại chip; nó mở hàng đợi từ một hàng 32 lệnh lên hàng chục nghìn, và vì thế làm hỏng luôn cách đo "ổ có bận không" thời HDD.
9. Tự kiểm tra
Q1Một ổ HDD 15.000 vòng/phút được quảng cáo là 'ổ doanh nghiệp tốc độ cao'. Tính khoản chờ quay trung bình, rồi giải thích vì sao nó vẫn thua SSD phổ thông hàng chục lần ở truy cập ngẫu nhiên.▸
250 vòng mỗi giây, một vòng 4 mili-giây, chờ trung bình nửa vòng là 2 mili-giây — cải thiện khoảng hai lần so với ổ 7200 vòng/phút. Nhưng seek thì không giảm theo tốc độ quay vì nó phụ thuộc cơ cấu truyền động, nên một thao tác ngẫu nhiên vẫn tốn cỡ vài mili-giây.
SSD không có bộ phận chuyển động nào nên độ trễ thuộc thang micro-giây, nhỏ hơn khoảng ba bậc. Tăng tốc độ quay là cải tiến tuyến tính trên cơ chế đã chạm trần vật liệu; bỏ chuyển động cơ học là đổi cơ chế.
Q2Vì sao SSD có khái niệm 'write amplification' còn HDD thì không? Trả lời bằng cơ chế, đừng chỉ nêu tên.▸
Trên HDD, đơn vị ghi và đơn vị ghi đè là một: muốn đổi nội dung một sector, đầu từ chỉ việc ghi lại từ trường trên đúng sector đó, nên lượng dữ liệu chạm vào đĩa đúng bằng lượng ứng dụng yêu cầu.
NAND thì bất đối xứng: ghi theo page nhỏ, nhưng chỉ xoá được theo erase block lớn hơn hàng trăm lần. Sửa dữ liệu trong block đã đầy, firmware phải chép những page còn dùng sang block trống khác, ghi dữ liệu mới, rồi xoá cả block cũ — nên một yêu cầu ghi 4 KB có thể kéo theo hàng megabyte thao tác thật.
Q3Đồng nghiệp nói: 'Máy chủ này chậm I/O, thay ổ SATA SSD bằng NVMe là xong.' Khi nào lời khuyên đó đúng, khi nào nó không giải quyết được gì?▸
Nó đúng khi nút thắt nằm ở độ song song của hàng đợi: nhiều luồng cùng phát I/O, mỗi luồng phải chờ vì AHCI chỉ có một hàng đợi 32 lệnh. Đổi sang NVMe thì các yêu cầu không còn xếp sau nhau.
Nó không giúp khi nút thắt ở chỗ khác: workload một luồng tuần tự thì hàng đợi vốn đã chẳng đầy; ứng dụng gọi fsync sau mỗi lần ghi thì cái nó chờ là độ bền chứ không phải thông lượng. Đo trước khi mua — hàng đợi luôn nông mà độ trễ vẫn cao thì vấn đề không ở giao thức.
Q4Một ổ SSD 1 TB còn trống 400 GB nhưng tốc độ ghi tụt hẳn so với lúc mới mua. Nêu cơ chế gây ra chuyện này và một biện pháp giảm nhẹ.▸
Mấu chốt là "trống" theo hệ điều hành khác "đã xoá sẵn" theo firmware. Khi bạn xoá file, hệ điều hành chỉ gỡ tham chiếu trong filesystem; các block NAND tương ứng vẫn giữ bit cũ và chưa được xoá. Càng ít block đã-xoá-sẵn thì mỗi lần ghi mới càng dễ phải chờ trọn chu trình đọc-chép-xoá, và vì garbage collection chen vào giữa các request thật, độ trễ nhảy theo cơn.
Biện pháp: bật TRIM để hệ điều hành báo cho ổ biết block nào không còn cần, giúp firmware xoá lúc rảnh. Chừa sẵn dung lượng không dùng tới cũng cho firmware thêm chỗ xoay xở — đúng nguyên lý over-provisioning.
Q5Vì sao AHCI chỉ thiết kế một hàng đợi 32 lệnh, và vì sao thiết kế đó hợp lý lúc ra đời nhưng thành nút cổ chai với SSD?▸
AHCI sinh ra cho ổ đĩa quay, mà bên dưới giao thức chỉ có một cánh tay đọc vật lý phục vụ tuần tự. Xếp hàng dài bao nhiêu thì cuối đường vẫn một bộ phận cơ khí làm việc; 32 lệnh đủ để ổ sắp lại thứ tự sao cho đầu đọc di chuyển ít nhất — con số hợp lý chứ không phải giới hạn tuỳ tiện.
Ràng buộc đó biến mất khi thiết bị bên dưới là NAND với nhiều chip và nhiều kênh song song thật. Lúc này một hàng đợi trở thành nút cổ chai do chính giao thức tạo ra chứ không phải do phần cứng.
Bài tiếp theo: Tuần tự vs ngẫu nhiên — cùng 1 GB, chênh trăm lần
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
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