ADR 0016: Retention theo gói bằng nhãn ngày và xóa theo ngày trên VictoriaMetrics OSS
1. Tiêu đề quyết định (Title)
Mỗi mẫu được ghi kèm nhãn ah_day (ngày UTC). Collector đọc chính sách retention theo gói của từng công ty từ Access Hub, cắt mọi lần đọc theo chính sách, khóa ghi phần cũ hơn retention hiện tại, và xóa vật lý cả ngày của một công ty bằng delete_series khi ngày đó nằm ngoài cửa sổ được giữ.
2. Trạng thái (Status)
Chấp nhận (Accepted) ngày 02/10/2026. Chính sách (Q17) do Product Owner (Thiện Phan Ngọc) quyết định ngày 01/10/2026: khi retention của một công ty giảm, dữ liệu cũ hơn retention mới bị khóa chỉ đọc 30 ngày rồi xóa vật lý. Trong 30 ngày đó khách tự xuất dữ liệu của mình bằng chức năng export của Access Hub (job đọc API series của collector); nền tảng không khôi phục dữ liệu đã xóa. Phương án kỹ thuật được nhóm Collector chọn theo ủy quyền đó, sau khi đo trên dev (mục 7). Xem lại sau kiểm thử tải X-7.
3. Ngữ cảnh (Context)
- Gói của Access Hub có hạn mức
metrics_retention_days(Free 7, Pro 30, Expert 60, Team 30, Business 90, gói riêng có thể khác). Kho hiện tại:vm-rawgiữ 30 ngày,vm-long(rollup) giữ 400 ngày cho mọi công ty. - VictoriaMetrics OSS: một retention cho mỗi instance,
delete_seriesxóa cả series (không xóa theo khoảng thời gian),-retentionFiltertheo nhãn chỉ có ở bản Enterprise (không dùng được). - Yêu cầu: (a) đọc không vượt chính sách; (b) trong 30 ngày ân hạn sau khi giảm, phần cũ vẫn đọc được nhưng không được ghi thêm; (c) hết ân hạn thì xóa khỏi đĩa; (d) cô lập tuyệt đối giữa công ty; (e) không thêm phụ thuộc trả phí.
4. Quyết định (Decision)
- Nhãn ngày. Bộ ghi (
internal/tsdb/vm.go) tách mỗi series thành một dòng import cho mỗi ngày UTC của mẫu và gắnah_day=YYYYMMDD(collector tự đặt, nhãn agent gửi lên bị bỏ). Mỗi ngày của một series là một series riêng. Rollup của vmalert giữ nguyên nhãn này, nênvm-longcũng chia theo ngày. Luật rollup không đổi. - Đọc. Mọi truy vấn gộp nhãn ngày:
min/max without(ah_day),avgtính bằng tổng chia số đếm (chính xác qua ranh giới ngày),lastghép trong Go theotlast_over_time(mẫu mới nhất thắng). Nhãnah_daykhông bao giờ ra khỏi collector. - Chính sách từ Access Hub.
GET /settings/{company_id}trảmetrics_retention_days,metrics_retention_previous_days,metrics_retention_grace_until(docs/03mục 5.1,docs/06mục 4.6). Giới hạn đọc = retention cũ khi còn ân hạn, retention hiện tại sau đó. Phần cũ hơn retention hiện tại là vùng khóa: worker bỏ mọi mẫu rơi vào đó (ahc_worker_locked_samples_dropped_total), ingest vốn không nhận mẫu cũ hơn 24 giờ. - Xóa vật lý (janitor). Vai trò admin, một tiến trình nhờ lease Redis, mỗi giờ: liệt kê công ty trong từng kho (
label/company_id/values), hỏi Access Hub chính sách mới nhất (không dùng cache), tính cửa sổ giữ, liệt kê ngày của công ty (label/ah_day/valuescómatch[]theo công ty) và xóa các ngày kết thúc trước mốc cắt bằngdelete_series{company_id="C",ah_day=~"..."}. Sau đó/internal/force_mergecho phân vùng tháng bị ảnh hưởng (tối đa 1 lần mỗi ngày) để dữ liệu rời khỏi đĩa ngay. - Lưới an toàn. Không xóa khi Access Hub lỗi hoặc không trả lời; không xóa gì trẻ hơn 1 ngày; không xóa công ty mới thấy chưa đủ 24 giờ; janitor tự nhớ retention lớn nhất thấy trong 30 ngày gần nhất (lưu Redis) và giữ ít nhất mức đó, kể cả khi Access Hub quên gửi ân hạn; chế độ
dry_run; chỉ số tổng hợp, không nêu tên công ty trên bề mặt vận hành. - Dữ liệu cũ (không có nhãn ngày).
vm-rawhết hạn tự nhiên sau 30 ngày (bằng thời gian ân hạn).vm-long: janitor xuất, gắn nhãn ngày, nhập lại và xóa bản cũ cho từng công ty, chỉ khi series cũ đã ngừng nhận mẫu 3 giờ.
5. Cơ sở lý luận (Rationale)
- Xóa theo ngày là thao tác siêu dữ liệu: 2 đến 5 ms mỗi lần gọi, không phụ thuộc lượng dữ liệu còn giữ. Hai phương án còn lại có chi phí tỉ lệ với dữ liệu phải giữ (viết lại) hoặc với số lần đổi gói nhân dữ liệu phải chuyển (tách instance).
- Không thêm tiến trình, không định tuyến theo công ty, không có giai đoạn "dữ liệu ở hai nơi". Đổi gói chỉ đổi con số trong Access Hub, không di chuyển dữ liệu.
- Độ mịn 1 ngày cho cả mẫu thô và rollup: dữ liệu rời đĩa muộn nhất khoảng 1 ngày (cộng chu kỳ quét 1 giờ) sau khi ra khỏi cửa sổ giữ.
- Chi phí đo được chấp nhận được (mục 7): chỉ mục tăng khoảng 40 phần trăm, ghi chậm khoảng 15 phần trăm, truy vấn gần như không đổi.
6. Ảnh hưởng (Consequences)
- Tích cực: retention theo gói đúng nghĩa vật lý cho mọi giá trị ngày, ân hạn chính xác theo ngày, cô lập theo công ty (bộ chọn xóa luôn có
company_id, kiểm thử hai tenant ởinternal/retention,internal/app,deploy/dev/vmcheck). - Tiêu cực: số series lịch sử tăng theo số ngày (series hoạt động không đổi); mỗi nửa đêm UTC mọi series "xoay" sang series mới (đo được khoảng 110.000 đến 150.000 series mới/giây, 700.000 series ở 10.000 máy mất khoảng 5 giây); truy vấn phải luôn gộp
ah_day(đã đóng gói tronginternal/tsdb, không ai được truy vấn VM trực tiếp); ở ranh giới nửa đêm, một bước rolluplastcó thể đến từ hai series (đã xử lý ở đọc). - Vận hành: proxy đứng trước VictoriaMetrics phải cho qua
/api/v1/label/*/values,/api/v1/admin/tsdb/delete_series,/api/v1/export,/internal/force_merge. Theo dõiahc_retention_*.force_mergetốn IO trên phân vùng tháng hiện tại, chạy tối đa một lần mỗi ngày.
7. Phương án đã cân nhắc (Alternatives) và số đo
Đo bằng deploy/dev/vmcheck/retbench_test.go trên VictoriaMetrics v1.153 single node riêng (cổng 18430, 4 vCPU, 16 GB), 58 máy x 69 series x 7 ngày, mẫu 30 giây (80,7 triệu mẫu mỗi công ty):
| Phép đo | Kết quả |
|---|---|
| Ghi không nhãn ngày / có nhãn ngày | 4,8 đến 7,0 / 4,1 đến 5,7 triệu mẫu/s (chậm khoảng 15 phần trăm) |
| Chỉ mục tăng thêm (4.002 series x 7 ngày) | 1.023 KiB không nhãn ngày / 1.440 KiB có nhãn ngày (cộng khoảng 40 phần trăm) |
| Truy vấn 7 ngày một chỉ số một máy (500 điểm) | 2 đến 4 ms không nhãn / 1,7 đến 4,9 ms gộp max / 2,3 đến 6,1 ms avg chính xác |
| Xóa 2 ngày của một công ty bằng nhãn ngày | 2 đến 5 ms |
| Viết lại (xuất 5 ngày giữ lại, xóa, nhập lại) | 49,5 triệu mẫu trong 21,8 s: xuất 3,2 triệu/s, nhập 7,7 triệu/s, khoảng 2,3 triệu mẫu giữ lại/s |
force_merge phân vùng bị xóa | khoảng 1 s ở cỡ này, dữ liệu 2,6 MiB xuống 0,9 MiB |
| Đăng ký series mới | 106.000 đến 153.000 series/s |
| Instance VM rỗng | 24 MiB RSS |
| Phương án | Cách làm | Chi phí ở 10.000 máy | Kết luận |
|---|---|---|---|
| A. Viết lại định kỳ | Mỗi chu kỳ: xuất cửa sổ giữ của công ty, delete_series, nhập lại | Tỉ lệ với dữ liệu giữ lại: một công ty Business 2.000 máy, rollup 90 ngày khoảng 15,7 tỉ mẫu, khoảng 1,9 giờ IO mỗi lần; mẫu ghi trong lúc xuất sẽ mất trừ khi giữ ghi; đọc thấy lỗ trong lúc xóa và nhập | Không chọn: không mở rộng được, có rủi ro mất dữ liệu |
| B. Tách instance theo mức retention | vm-raw-7, vm-raw-30, vm-long-30/60/90/400, vmagent định tuyến rollup theo nhãn tầng; đổi gói thì chuyển dữ liệu giữa tầng | Thêm khoảng 5 tiến trình VM và vmagent (rẻ: 24 MiB mỗi instance rỗng); mỗi lần đổi gói chuyển toàn bộ dữ liệu giữ lại (như A, một lần); đọc phải ghép nhiều tầng trong lúc chuyển và trong ân hạn; nhãn tầng làm series đổi danh tính khi đổi gói; chỉ hỗ trợ các mức cố định | Không chọn: phức tạp vận hành và mã, chi phí di chuyển lớn với khách hàng lớn |
| C. Nhãn ngày (chọn) | Như mục 4 | Xóa: mili giây. Chỉ mục cộng khoảng 40 phần trăm, ghi chậm khoảng 15 phần trăm | Chọn |
| D. Nhãn tuần hoặc tháng | Như C nhưng thô hơn | Chỉ mục nhỏ hơn chút, nhưng dữ liệu nằm lại tới 7 hoặc 31 ngày sau hạn | Không chọn: chi phí của nhãn ngày đã thấp, độ mịn ngày đáp ứng chính sách tốt hơn |
E. -retentionFilter (Enterprise), VM cluster đa tenant | Cần bản trả phí; retention theo tenant cũng chỉ có ở Enterprise | Loại theo yêu cầu |
8. Tài liệu liên quan (Related)
docs/03-protocol.md mục 4 và 5.1, docs/04-data-model.md "Retention và rollup", docs/06-access-hub-integration.md mục 4.4 và 4.6, docs/13-risks-open-questions.md Q4 và Q17, docs/14-production-deployment-guide.md mục 5. Mã: internal/tsdb/epoch.go, retain.go, vm.go, internal/retention, internal/worker (Floor). ADR 0005, 0014, 0015. ADR 0017 (cụm VictoriaMetrics: cách janitor và purge xóa trên cụm). Phương án E ở mục 7 chỉ loại retention theo tenant của bản Enterprise; cụm OSS vẫn dùng được làm kho.
9. Phê duyệt (Approval)
| Vai trò | Người | Ngày |
|---|---|---|
| Product Owner (chính sách Q17) | Thiện Phan Ngọc | 01/10/2026 |
| Enterprise Architect | chưa chỉ định | |
| Solution Architect | chưa chỉ định |