Phép đo và benchmark
Tài liệu này liệt kê mọi phép đo Access Hub Scanner cần, sẵn để chạy khi có máy đo riêng (Q47, chủ dự án đồng ý 2026-10-03). Máy production (máy đang chạy Access Hub) không được dùng cho phép đo quy mô lớn sau hai sự cố đầy đĩa ngày 2026-10-02 (R25). Trên máy production chỉ chạy make bench-small và các phép đo nhỏ đã ghi ở cột "máy production, quy mô nhỏ".
1. Máy đo đề xuất
| Máy | Cấu hình | Dùng cho |
|---|---|---|
| M1. Máy đo trung tâm (bắt buộc) | 8 vCPU (x86_64, không chia sẻ lõi), 32 GB RAM, 200 GB SSD NVMe, Ubuntu 24.04 LTS, quyền root, mạng ra Internet (tải nguồn dữ liệu), không chạy dịch vụ nào khác | B1 đến B5, B8, B9. Secmatch được giới hạn về đúng đích SNFR-43 (4 vCPU, 16 GB) bằng GOMAXPROCS=4 và systemd-run -p CPUQuota=400% -p MemoryMax=16G; phần còn lại cho bộ sinh dữ liệu và công cụ đo |
| M2. Máy đo trên host (nên có) | 2 vCPU, 2 GB RAM, 20 GB đĩa, Ubuntu 24.04; thêm một máy Debian 12 cùng cỡ nếu có | B6, B7 với unit systemd thật (ambient capability, IPAddressDeny bằng BPF, MemoryMax), thứ mà máy production và hộp cát người dùng không đo được |
M1 có thể là VM cloud thuê theo giờ: cả bộ phép đo lớn chạy trong khoảng một ngày. M2 có thể là hai VM nhỏ. Không cần dữ liệu khách hàng: mọi bộ dữ liệu là công khai hoặc tổng hợp.
2. Quy tắc an toàn chung
- Mọi công cụ đo trong repo từ chối quy mô lớn nếu không đặt
AHS_BENCH_MACHINE=1(chỉ đặt trên M1, M2). - Kiểm tra dung lượng trống trong vòng ghi, không chỉ trước khi chạy: dừng khi đĩa trống dưới 30 GiB (
--min-free-gib), kho vượt trần (--max-store-mib), heap vượt trần (--max-heap-mib). - Mọi lệnh chạy dưới
nice -n 19 ionice -c3khi đo trên host (B6, B7) để không làm nhiễu số đo của chính máy; trên M1 thì chạy bình thường nhưng secmatch bị giới hạn bằng cgroup như mục 1. - Không giải nén nguồn lớn ra đĩa (Ubuntu VEX khoảng 20 GB khi giải nén là nguyên nhân sự cố 1): mọi bộ đọc nguồn đọc theo luồng.
- Bẫy biến thể kernel (nguyên nhân sự cố 2, 16:22 ngày 2026-10-02): bộ sinh máy tổng hợp từng gán ngẫu nhiên các gói nguồn kernel biến thể của Ubuntu (
linux-aws,linux-oem-6.8,linux-gcp, ...) cho máy. Mỗi biến thể mang hàng nghìn CVE chưa sửa, nên trạng thái finding và outbox phình tới 23 GB trên đĩa và 12 GB RSS. Máy thật chỉ chạy một kernel.tools/bench-rematchloại mọi gói nguồnlinux*khỏi lựa chọn ngẫu nhiên và gán đúng một kernel đang chạy (linux-signedcủa một phiên bản có trong DB). Bất kỳ bộ sinh nào khác phải giữ quy tắc này. - Kết quả ghi vào bảng ở mục 5 kèm commit, ngày dữ liệu nguồn, cấu hình máy.
3. Bộ dữ liệu
| Bộ | Nguồn | Cách tạo |
|---|---|---|
| D1. DB lỗ hổng đầy đủ | Debian tracker, Freexian ELTS tracker, Ubuntu OSV (khoảng 1 GB tải, 2,43 triệu bản ghi, 14,2 MB nén) | make bench-secdb (B3) trên M1, giữ thư mục phát hành ở /bench/secdb |
| D2. Tập con kiểm thử | testdata/secdb (625 KB, đã commit) | Có sẵn; dùng cho chạy nhỏ |
| D3. Máy mẫu thật | testdata/fixtures/* (5 ảnh gốc chính thức) cộng dpkg/status của M2 và các VM cài sẵn gói phổ biến (LAMP, Docker, Node) | Chép var/lib/dpkg/status và os-release vào thư mục gốc giả, không chép tệp khác |
| D4. Máy tổng hợp | Sinh từ D1 bằng tools/bench-rematch: mỗi máy 3.000 gói; khoảng một phần ba là gói nguồn có advisory trong DB, phiên bản lấy từ phiên bản sửa thật (nên có finding đã sửa và chưa sửa), phần còn lại là gói không có advisory; đúng một kernel; --profiles đặt số inventory khác nhau (máy giống hệt nhau như đội máy thật, để đo bộ nhớ đệm so khớp); hạt giống cố định --seed để lặp lại được | Không ghi gì ra đĩa ngoài --store-dir (nếu đặt) |
| D5. Ground truth | Kết quả Trivy, Grype trên D3 cộng phân loại thủ công từng khác biệt | Mục B2 |
4. Danh mục phép đo
B1. So khớp lại toàn bộ 10.000 máy (S5)
- Mục đích: chứng minh secmatch so khớp lại cả đội máy đủ nhanh khi DB đổi, và đo bộ nhớ, kích thước kho.
- Yêu cầu: SNFR-43 (10.000 máy, 3.000 gói, dưới 30 phút trên 4 vCPU, 16 GB), SNFR-24, SNFR-25.
- Máy: M1, secmatch giới hạn 4 vCPU, 16 GB.
- Dữ liệu: D1, D4 với
--hosts 10000 --packages 3000 --profiles 200(mỗi inventory dùng chung cho 50 máy), rồi lặp với--profiles 10000(mọi máy khác nhau, trường hợp xấu nhất). - Lệnh:shChạy lại với
export AHS_BENCH_MACHINE=1 GOMAXPROCS=4 systemd-run --scope -p CPUQuota=400% -p MemoryMax=16G \ go run ./tools/bench-rematch --db /bench/secdb --pubkey /bench/secdb-cache/key/bench-local.pub \ --hosts 10000 --packages 3000 --profiles 200 --workers 4 --store-dir /bench/store --max-heap-mib 12288 # hoặc: make bench-rematch BENCH_HOSTS=10000--profiles 10000, và không có--store-dir(kho trong bộ nhớ) để tách chi phí đĩa. - Ghi:
db_load_seconds,ingest_seconds(so khớp lần đầu của mọi máy),rematch_seconds,memo_hits,heap_mib_after_gc,store_mib, RSS đỉnh (/usr/bin/time -v), số sự kiện. - Đạt:
rematch_secondsdưới 1.800 với--profiles 10000; RSS đỉnh dưới 16 GB; kho dưới 50 GB. - An toàn:
--max-heap-mib 12288,--max-store-mib 20480,--min-free-gib 30; cgroupMemoryMax=16G.
B2. Độ chính xác với ground truth phân loại thủ công
- Mục đích: con số precision, recall công bố được (S3 mới so khớp với Trivy, Grype, chưa phân loại tay).
- Yêu cầu: SNFR-40 (recall và precision không dưới 95% với gói OS của distro chính thức).
- Máy: M1 (hoặc bất kỳ máy nào có 10 GB trống cho DB của Trivy, Grype).
- Dữ liệu: D3 (ít nhất 5 fixture cộng 3 máy thật), D1 cùng ngày dữ liệu với DB của Trivy, Grype.
- Lệnh:
- Cài Trivy và Grype bản ghim, kiểm SHA-256 (
docs/spikes/README.mdS3); xuất kết quả ra TSV theo định dạng củatools/accuracy. go run ./tools/accuracy -db /bench/secdb -pubkey ... -root <fixture> -name <tên> -ref trivy=out/trivy-{name}.tsv -ref grype=out/grype-{name}.tsv -detail- Mỗi dòng "ours-only" và "theirs-only" được phân loại tay vào
testdata/groundtruth/<fixture>.tsvvới cộtvuln_id, package, verdict (tp, fp, fn), lý do, nguồn kiểm(tracker distro, changelog gói). Hai người duyệt. - Precision = TP / (TP + FP), recall = TP / (TP + FN), tính riêng finding có bản sửa và chưa có bản sửa, riêng từng distro.
- Cài Trivy và Grype bản ghim, kiểm SHA-256 (
- Ghi: bảng TP, FP, FN theo fixture, distro, trạng thái sửa; danh sách nguyên nhân (dữ liệu nguồn sai, chính sách khác, lỗi của ta).
- Đạt: precision và recall từ 95% trở lên cho mỗi distro đang hỗ trợ.
- An toàn: chỉ quét thư mục gốc giả, không quét
/của máy đo.
B3. secdb-build bản đầy đủ
- Mục đích: thời gian, bộ nhớ, kích thước của một lần dựng đầy đủ với mọi nguồn.
- Yêu cầu: ADR 0005, ADR 0012 (dựng mỗi giờ phải nhanh hơn nhiều so với 1 giờ), đích nội bộ RSS dưới 1 GB.
- Máy: M1.
- Lệnh:
AHS_BENCH_MACHINE=1 OUT=/bench/secdb make bench-secdb(gọiscripts/bench/secdb-build.sh). - Ghi: thời gian thực, CPU, RSS đỉnh, số bản ghi theo nguồn, kích thước
secdb.pb.zst, kích thước nguồn thô. - Đạt: dưới 5 phút, RSS dưới 1 GB, không lỗi kiểm tra hợp lý.
- An toàn: script dừng khi đĩa trống dưới 32 GiB;
--min-free-gib 30trongsecdb-build.
B4. Secmatch nạp DB và độ trễ so khớp lại
- Mục đích: thời gian và bộ nhớ khi secmatch nạp phiên bản DB mới trong lúc đang phục vụ, và độ trễ từ khi phát hành tới khi sự kiện ra outbox.
- Yêu cầu: SNFR-25 (finding trên Access Hub không quá 2 giờ sau khi nạp DB), SNFR-43.
- Máy: M1.
- Lệnh: chạy B1 với hai phiên bản D1 dựng cách nhau một giờ (B3 hai lần,
OUTkhác nhau);bench-rematchindb_load_secondsvàrematch_seconds; thêmgo run ./tools/accuracy -db ...cho thời gian nạp và RSS khi chỉ nạp. - Ghi: thời gian nạp, RSS khi nạp (hai chỉ mục cùng lúc lúc chuyển), thời gian so khớp lại, số sự kiện delta thật giữa hai phiên bản.
- Đạt: nạp dưới 30 s, RSS lúc chuyển dưới 2 GB, so khớp lại theo B1.
B5. Thông lượng ingest mỗi bản và giới hạn tốc độ
- Mục đích: số báo cáo mỗi giây một bản ingest chịu được (TLS, kiểm chữ ký, giới hạn, hàng đợi bền vững), và xác nhận giới hạn theo máy (6 mỗi giờ, burst 8) làm đúng dưới tải. Quyết định khi nào phải chuyển giới hạn và khử trùng sang kho dùng chung (Q46).
- Yêu cầu:
07mục 3.2,10mục 2; đội 10.000 máy gửi báo cáo đầy đủ mỗi ngày vàHASH_ONLYmỗi giờ. - Máy: M1.
- Lệnh:
AHS_BENCH_MACHINE=1 go run ./tools/bench-ingest --hosts 2000 --concurrency 64 --data-dir /bench/ingest(make bench-ingest); lặp với--packages 20000(phần lớn nhất). - Ghi:
accepted_per_second, p50, p95, p99,rate_limited(phải bằng số máy: phần thứ 9 mỗi máy bị 429), RSS, IO đĩa của hàng đợi. - Đạt: một bản chịu được tải đỉnh của 10.000 máy với hệ số an toàn 10 (khoảng 30 báo cáo mỗi giây), p95 dưới 500 ms,
rate_limit_ok: true. - An toàn: hàng đợi được rút liên tục, dừng khi đĩa trống dưới 30 GiB.
B6. Bộ đọc trên host: CPU, IO, RAM trong ngân sách unit
- Mục đích: chứng minh
accesshub-scannernằm trong ngân sách trên máy thật, dưới unit systemd thật. - Yêu cầu: SNFR-01, SNFR-03, SNFR-04, SNFR-05, SNFR-06, SNFR-07, SNFR-08, SNFR-11.
- Máy: M2 (cộng một lần trên máy production, đã làm, mục 5).
- Lệnh:
make bench-footprint(gọiscripts/bench/footprint.sh, chỉ đọc DB gói, ghi vào thư mục tạm). Trên M2 thêm: cài gói,systemctl start accesshub-scanner.service, đọcsystemctl show -p CPUUsageNSec,MemoryPeak,IOReadBytes accesshub-scanner.service; lặp trên máy có 3.000 và 20.000 gói (cài thêm gói hoặc dùngdpkg/statustổng hợp qua--root). - Ghi: CPU (user, sys), RSS đỉnh, byte đọc, kích thước spool, kích thước binary.
- Đạt: 3.000 gói dưới 3 s CPU, RSS dưới 128 MB, báo cáo dưới 150 KB nén, spool dưới 5 MB, binary dưới 25 MB.
B7. Bộ gửi trên host
- Mục đích: dấu chân của
accesshub-scan-uploadermỗi lượt và trong ngày. - Yêu cầu: ADR 0001 (unit
MemoryMax=48M,CPUQuota=20%), SNFR-11. - Máy: M2 (cộng một lần trên máy production với ingest thử cục bộ, đã làm).
- Lệnh:
make bench-footprintđo lượtFULL,HASH_ONLY, rảnh vớibench-ingest --servecục bộ; trên M2 thêm chạy unit thật 24 giờ với ingest thử và đọcCPUUsageNSec,MemoryPeak,IPEgressBytescủa unit. - Ghi: RSS đỉnh, CPU mỗi lượt, byte gửi đi mỗi ngày.
- Đạt: RSS dưới 32 MB, CPU dưới 1 s mỗi ngày khi không có báo cáo mới, byte gửi mỗi ngày dưới 200 KB với máy 3.000 gói.
B8. Kích thước tải DB và delta
- Mục đích: lượng tải mỗi phiên bản DB với secmatch (cloud và Dedicated), và lợi ích của delta theo bản ghi (ADR 0012).
- Yêu cầu: ADR 0005, ADR 0012, SNFR-31.
- Máy: M1.
- Lệnh: chạy B3 hai lần cách nhau một giờ, rồi một ngày (
OUTkhác nhau), sau đóPREV=<thư mục trước> make bench-secdb, hoặcgo run ./tools/secdb-diff --old <cũ> --new <mới> --pubkey .... - Ghi: kích thước tệp đầy đủ, số bản ghi thêm, đổi, xóa, kích thước delta theo bản ghi (zstd).
- Đạt: không có ngưỡng cứng; quyết định có làm định dạng delta hay không (đề xuất: làm nếu delta mỗi giờ dưới 5% tệp đầy đủ).
B9. Độ trễ nguồn (ADR 0012)
- Mục đích: thay các ước lượng ở
03mục 6.1 bằng số đo: từpublishedcủa bản ghi tới khi secdb-build thấy. - Yêu cầu: ADR 0012, SNFR-25.
- Máy: M1, chạy 7 ngày.
- Lệnh: chờ
SDB-6(chỉ số độ trễ theo nguồn); trước đó: B3 mỗi giờ bằng cron, somodifiedcủa bản ghi mới với giờ dựng. - Ghi: phân vị độ trễ theo nguồn.
B10. Về sau (chờ giai đoạn tương ứng)
| Mã | Phép đo | Yêu cầu | Giai đoạn |
|---|---|---|---|
| B10a | Ngân sách lượt nội dung: CPU, IO, RAM, PSI, nhường tài nguyên dưới tải chuẩn | SNFR-12 đến SNFR-17, SNFR-49 | P2 |
| B10b | Độ chính xác detector bí mật, dữ liệu cá nhân trên bộ mẫu | SNFR-47, SNFR-48 | P2, P4 |
| B10c | Trang finding 100.000 dòng của Access Hub | SNFR-46 | P3 (phía Access Hub) |
| B10d | Bộ đọc trên họ RHEL (rpmdb) | SNFR-01 đến SNFR-08 | P3 |
5. Bảng kết quả
Ghi mỗi lần đo một dòng. Các dòng hiện có là số đo nhỏ trên máy production (Ubuntu 24.04, 4 vCPU, chia sẻ với Access Hub), chạy dưới nice -n 19 ionice -c3, GOMAXPROCS=2, GOMEMLIMIT 512 MiB (3 GiB cho secdb-build). Chúng không thay cho phép đo trên máy đo riêng.
| Phép đo | Ngày, commit | Máy | Quy mô | Kết quả | Đạt |
|---|---|---|---|---|---|
| B1 | 2026-10-03, nay | máy production, quy mô nhỏ | 100 máy x 3.000 gói, 20 inventory khác nhau, DB tập con D2 | so khớp lần đầu 0,63 s; so khớp lại 0,09 s (2 worker, 80 lần dùng bộ nhớ đệm); RSS đỉnh dưới 170 MB (gồm trình biên dịch) | Chưa đo quy mô thật |
| B1 | 2026-10-02 | máy production | 10.000 máy (bản đầu) | Dừng: làm đầy đĩa (bẫy biến thể kernel, mục 2.5) | Chờ M1 |
| B2 | 2026-10-02 (S3) | máy production, quy mô nhỏ | 5 fixture cộng máy này, so với Trivy 0.74.0, Grype 0.119.0 | finding có bản sửa: trùng 100% phiên bản sửa; recall 99,9% so với hợp hai công cụ; chưa phân loại tay | Chờ ground truth |
| B3 | 2026-10-02 | máy production, quy mô nhỏ | đủ nguồn (Debian, ELTS, Ubuntu), dữ liệu cùng ngày | 62 s, RSS đỉnh 0,67 GB, 2.428.996 bản ghi, 14,2 MB nén (290 MB giải nén); bản trước tối ưu: 75 s, 3,0 GB | Đạt (đích nội bộ) |
| B4 | 2026-10-02 | máy production, quy mô nhỏ | DB đầy đủ, 5 fixture | nạp và lập chỉ mục 4,0 s, RSS đỉnh 0,30 GB (trước tối ưu 9,3 s, 1,44 GB) | Đạt phần nạp |
| B5 | 2026-10-03, nay | máy production, quy mô nhỏ | 20 máy, 9 phần mỗi máy, 3.000 gói mỗi phần (15,7 KB), 8 luồng, TLS cục bộ | 268 báo cáo/s, p95 31 ms, p99 39 ms; đúng 20 lần 429 (phần thứ 9 mỗi máy) | Chưa đo quy mô thật |
| B6 | 2026-10-03, nay | máy production, quy mô nhỏ | 747 gói thật | quét đầy đủ 10 ms CPU, RSS 9,4 MB; không đổi 5,4 MB; spool 14 KB mỗi báo cáo | Đạt |
| B6 | 2026-10-02 (S5) | máy production, quy mô nhỏ | dpkg/status tổng hợp 3.000, 20.000, 45.000 gói | 30 ms, 11,9 MB, 17,5 KB; 0,27 s, 22 MB, 105 KB; 0,61 s, 40 MB, 3 phần 213 KB; binary 5,2 MB | Đạt |
| B7 | 2026-10-03, nay | máy production, quy mô nhỏ | ingest thử cục bộ, báo cáo 747 gói | lượt FULL 20 ms thực, RSS 12,5 MB; HASH_ONLY 12,7 MB; rảnh 11,8 MB | Đạt (chưa đo unit thật) |
| B8 | Chưa đo (cần hai phiên bản D1 cách nhau) | Chờ M1 | |||
| B9 | Chưa đo (chờ SDB-6) | Chờ M1 |
Mẫu dòng mới:
| Phép đo | Ngày, commit | Máy | Quy mô | Kết quả | Đạt |
|---|---|---|---|---|---|
| Bx | YYYY-MM-DD, abcdef0 | M1 (8 vCPU, 32 GB, NVMe, Ubuntu 24.04) | ... | số đo theo mục "Ghi" của phép đo | Đạt, không đạt, ghi chú |
6. Công cụ trong repo
| Công cụ | Việc | Chạy được trên máy production |
|---|---|---|
tools/bench-rematch | B1, B4: sinh máy tổng hợp (có bẫy kernel), nạp vào secmatch, so khớp lại | Có, tối đa 100 máy (tự từ chối hơn nếu thiếu AHS_BENCH_MACHINE=1) |
tools/bench-ingest | B5: tải lên ingest qua TLS, đo thông lượng và giới hạn; --serve cho B7 | Có, tối đa 50 máy |
tools/accuracy | B2 | Có (chỉ đọc thư mục gốc giả) |
tools/secdb-diff | B8 | Không cần: chỉ chạy trên M1 với hai phiên bản D1 |
scripts/bench/footprint.sh | B6, B7 | Có (chỉ đọc DB gói, ghi thư mục tạm, không cài gì) |
scripts/bench/secdb-build.sh | B3, B8 | Không (cần AHS_BENCH_MACHINE=1, tải khoảng 1 GB) |
make bench-small, bench-rematch, bench-ingest, bench-footprint, bench-secdb | Gói các lệnh trên | Chỉ bench-small, bench-footprint |