Trả lời nhanh: Điểm mạnh lớn nhất của GitHub Actions self hosted runner so với máy dùng chung không phải là giá mà là bộ nhớ đệm nằm lại trên máy giữa các lượt chạy. Máy dùng chung bắt đầu từ con số không mỗi lần, còn máy của bạn giữ nguyên thư viện đã tải, lớp ảnh Docker đã dựng và kết quả biên dịch. Ba việc để khai thác: đừng xóa thư mục làm việc sau mỗi lượt, đặt cache trên ổ nhanh, và dọn theo lịch vì nó phình rất nhanh.
Nhiều đội dựng máy CI riêng rồi vẫn thấy chậm ngang máy dùng chung. Nguyên nhân gần như luôn là cấu hình vẫn giữ thói quen của môi trường sạch: xóa hết sau mỗi lượt, tải lại từ đầu. Bài này nói cách bố trí để máy riêng phát huy đúng lợi thế của nó.
Những gì đáng giữ lại
Bốn nhóm, xếp theo mức tiết kiệm:
- Thư viện phụ thuộc. Thư mục gói của ngôn ngữ bạn dùng. Đây là nhóm tiết kiệm nhiều nhất vì tải lại tốn cả băng thông lẫn thời gian.
- Kết quả biên dịch trung gian. Với dự án lớn, phần này cắt được rất nhiều thời gian nếu chỉ vài file thay đổi.
- Lớp ảnh Docker. Dựng lại ảnh mà không phải tải lại các lớp nền.
- Bộ nhớ đệm của công cụ build, ví dụ của công cụ build Android hoặc của trình biên dịch.
Điểm chung: chúng đều là thứ được sinh ra từ đầu vào không đổi, nên giữ lại là an toàn. Ngược lại, đừng giữ lại kết quả xuất ra cuối cùng, vì bạn muốn mỗi lượt tạo ra bản mới thật chứ không phải bản cũ còn sót.
Bố trí thư mục cache
# Dat cache o thu muc co dinh, ngoai thu muc lam viec cua tung luot/var/cache/ci/ npm/ gradle/ docker/ pip/ # Cap quyen cho tai khoan chay runnersudo chown -R runner:runner /var/cache/ciĐặt ngoài thư mục làm việc là điểm quan trọng: nhiều cấu hình CI dọn sạch thư mục làm việc trước mỗi lượt, và nếu cache nằm trong đó thì nó bị xóa theo.
Sau đó trỏ các công cụ vào đúng thư mục này bằng biến môi trường của từng công cụ. Cách này gọn hơn việc chép qua chép lại, và nó cũng tránh được lỗi khi hai lượt build chạy song song.
Với máy chạy nhiều dự án, tách cache theo dự án nếu chúng dùng phiên bản thư viện khác nhau, còn dùng chung nếu chúng cùng nền tảng. Dùng chung tiết kiệm dung lượng nhưng có thể gây lẫn lộn khi phiên bản lệch nhau.
Dọn theo lịch, việc bắt buộc
Cache không dọn sẽ đầy ổ, và điều đó luôn xảy ra vào ngày bạn cần phát hành gấp. Một tác vụ định kỳ hằng tuần là đủ:
#!/usr/bin/env bash# Don cache cu hon 14 ngay va thu muc build cua cac luot da xongfind /var/cache/ci -type f -atime +14 -deletefind /var/lib/runner/_work -maxdepth 2 -name build -type d -mtime +7 -exec rm -rf {} + # Don anh Docker khong con dungdocker image prune -af --filter "until=336h" # Bao neu o dia con duoi 15 phan tramdf -h / | awk 'NR==2 && $5+0 > 85 {print "O dia sap day: " $5}'Dòng cuối đáng thêm: một cảnh báo sớm rẻ hơn nhiều so với việc phát hiện ổ đầy lúc đang cần build. Gửi kết quả vào kênh nội bộ của đội là đủ.
Về dung lượng, hãy chuẩn bị rộng tay: máy CI cho dự án mobile dễ dàng dùng tới cả trăm GB chỉ riêng cho cache và các bản dựng, như đã nói ở bài runner cho CI mobile.
Khi cache gây lỗi
Thỉnh thoảng bản dựng lỗi một cách vô lý và cách chữa duy nhất là xóa cache. Đây là chuyện bình thường, nên hãy chuẩn bị trước thay vì mò lệnh lúc gấp.
Ba việc nên có sẵn:
- Một cách chạy tay để xóa cache và dựng lại từ đầu. Đặt thành một luồng riêng hoặc một script có tên rõ ràng.
- Khóa cache theo nội dung file khai báo phụ thuộc. Khi file đó đổi, cache cũ tự động không được dùng nữa, tránh cảnh trộn lẫn phiên bản.
- Ghi rõ trong tài liệu nội bộ rằng gặp lỗi lạ thì thử xóa cache trước khi đi tìm nguyên nhân sâu xa.
Dấu hiệu nhận biết lỗi do cache: bản dựng thất bại trên máy CI nhưng chạy tốt trên máy cá nhân, và thông báo lỗi liên quan tới phiên bản thư viện hoặc file không tìm thấy.
Ổ đĩa, yếu tố quyết định
Toàn bộ lợi ích của cache phụ thuộc vào tốc độ đọc ghi, vì đây là hàng chục nghìn file nhỏ. Trên ổ chậm, việc đọc cache đôi khi không nhanh hơn tải lại từ mạng là bao.
Ba lưu ý bố trí:
- Đặt cache trên ổ nhanh nhất của máy. Nếu máy có nhiều ổ, đây là chỗ nên ưu tiên.
- Đừng đặt trên ổ mạng. Độ trễ mạng nhân với số file nhỏ là công thức của một máy CI chậm khó hiểu.
- Theo dõi mức bận của ổ trong lúc build. Nếu ổ bận gần như liên tục còn CPU rảnh, bạn đã tìm ra nghẽn.
Cách đo và các tinh chỉnh khác cho công cụ build nằm ở bài Gradle build chậm, còn phần chọn máy chạy CI nằm ở bài CI/CD tự host.
Những gì đáng giữ lại và những gì không
| Thứ | Có đáng giữ không | Vì sao |
|---|---|---|
| Thư viện tải về | Rất đáng | Đây là phần tốn thời gian nhất mỗi lần chạy |
| Kết quả dựng trung gian | Đáng | Tác vụ không đổi thì không chạy lại |
| Ảnh container cơ sở | Đáng | Tải lại mỗi lần rất tốn |
| Kết quả kiểm thử | Không | Phải chạy lại mỗi lần |
| Tệp tạm và nhật ký | Không | Chỉ làm đầy ổ |
Đặt lịch dọn để ổ không đầy
# Khong don thi o day, va o day thi moi tac vu deu that bai.# Day la nguyen nhan so mot cua tinh trang# "hom qua chay duoc, hom nay bao loi la" # Dat mot tac vu don hang tuandocker system prune -a --volumes --filter "until=168h"find ~/.gradle/caches -type f -atime +30 -delete 2>/dev/nullfind ~/.npm/_cacache -type f -atime +30 -delete 2>/dev/null # Theo doi dung luongdf -hdu -sh ~/.gradle ~/.npm ~/.cache /var/lib/docker 2>/dev/null # Dat canh bao khi o dia con duoi 20%# Canh bao nay dang gia hon moi thu khac trong baiKhi bộ nhớ đệm gây lỗi
- Dấu hiệu: tác vụ thất bại với lỗi lạ, và chạy lại trên máy sạch thì thành công. Đây là dấu hiệu kinh điển của bộ nhớ đệm hỏng.
- Cách xử nhanh: xóa bộ nhớ đệm rồi chạy lại. Có tùy chọn chạy bỏ qua bộ nhớ đệm để kiểm.
- Đừng vì một lần lỗi mà tắt hẳn bộ nhớ đệm. Lợi ích lớn hơn nhiều so với vài lần phải xóa.
- Với lỗi lặp lại, tìm nguyên nhân: thường là khóa bộ nhớ đệm đặt sai, khiến kết quả cũ được dùng cho đầu vào mới.
Ổ đĩa là yếu tố quyết định
Bộ nhớ đệm chỉ có tác dụng khi đọc lại nhanh. Trên ổ chậm, việc đọc hàng chục nghìn tệp nhỏ từ bộ nhớ đệm có khi không nhanh hơn tải lại là bao. Đây là lý do máy chạy tác vụ nên dùng ổ NVMe: nó làm cho chính cơ chế bộ nhớ đệm phát huy tác dụng. Xem VPS NVMe.
Câu hỏi thường gặp
Vì sao máy CI riêng vẫn chậm như máy dùng chung?
Thường vì cấu hình vẫn dọn sạch thư mục làm việc và tải lại thư viện mỗi lượt. Hãy đặt cache ở thư mục cố định ngoài thư mục làm việc và trỏ các công cụ vào đó.
Cache chiếm bao nhiêu dung lượng?
Với dự án web thì vài GB, với dự án mobile thì có thể tới hàng chục GB do bộ công cụ và các bản dựng trung gian. Hãy chuẩn bị ổ rộng và đặt tác vụ dọn định kỳ ngay từ đầu.
Làm sao biết lỗi build là do cache?
Dấu hiệu điển hình là lỗi chỉ xảy ra trên máy CI mà không xảy ra trên máy cá nhân, kèm thông báo liên quan tới phiên bản thư viện hoặc file không tìm thấy. Thử xóa cache và dựng lại trước khi tìm nguyên nhân khác.
Nhiều dự án có nên dùng chung cache không?
Dùng chung nếu chúng cùng nền tảng và cùng dải phiên bản, vì như vậy tiết kiệm dung lượng. Tách riêng nếu các dự án dùng phiên bản lệch nhau, tránh lẫn lộn gây lỗi khó hiểu.
