
Trả lời nhanh: Phải phân biệt hai loại tải. Tác vụ chờ như gọi API bên ngoài hoặc truy vấn database thì CPU rảnh, nút thắt nằm ở độ trễ và ở ổ đĩa của database. Tác vụ tính toán như xử lý ảnh hay phân tích dữ liệu thì CPU là nút thắt, và do đặc thù của Python, thêm nhân chỉ giúp khi bạn chạy nhiều tiến trình chứ không phải nhiều luồng. Đo bằng top: CPU thấp mà phản hồi chậm nghĩa là đang chờ, không phải thiếu CPU.
Ứng dụng chậm, nhìn vào thấy CPU chỉ dùng mười phần trăm. Thêm nhân không giải quyết được gì, vì vấn đề không nằm ở CPU.
- Tác vụ chờ và tác vụ tính toán cần cấu hình khác hẳn nhau.
- CPU thấp mà chậm nghĩa là đang chờ database hoặc dịch vụ ngoài.
- Với Python, chạy nhiều tiến trình mới tận dụng được nhiều nhân.
- Số worker hợp lý thường bằng số nhân cộng một, không phải càng nhiều càng tốt.
Phân biệt hai loại tải
| Loại tải | Ví dụ | Nút thắt | Nên tăng gì |
|---|---|---|---|
| Chờ | Gọi API, truy vấn database, đọc file | Độ trễ và ổ đĩa | Ổ nhanh, tối ưu truy vấn |
| Tính toán | Xử lý ảnh, phân tích dữ liệu, mã hoá | CPU | Xung nhịp và số nhân |
Phần lớn ứng dụng web thuộc loại chờ. Đó là lý do nhiều người nâng CPU mà không thấy khác biệt.
Đo để biết mình thuộc loại nào
top # xem mức dùng CPU và chỉ số wa
iostat -x 2 # xem %util của ổBa kịch bản:
- CPU thấp, phản hồi chậm: đang chờ. Tìm ở database hoặc dịch vụ ngoài.
- CPU cao ở một nhân: tác vụ tính toán chạy đơn tiến trình, cần chạy nhiều tiến trình hơn hoặc cần xung cao hơn.
- %util của ổ gần 100: ổ đĩa là nút thắt.
Chọn số worker cho đúng
Công thức thường dùng cho tải hỗn hợp: số worker bằng số nhân cộng một. Máy bốn nhân thì năm worker.
Đặt quá nhiều worker phản tác dụng: mỗi worker chiếm một phần RAM, và khi tổng vượt RAM máy thì hệ thống bắt đầu dùng swap, lúc đó mọi thứ chậm đi hàng chục lần. Nhiều trường hợp giảm số worker lại làm ứng dụng nhanh hơn.
Với tải chờ nhiều, cách hiệu quả hơn là dùng mã bất đồng bộ để một worker phục vụ được nhiều yêu cầu đang chờ, thay vì tăng số worker.
Khi worker xử lý file
Worker xử lý ảnh, chuyển đổi tài liệu hay tạo báo cáo đều ghi rất nhiều file tạm. Đây là loại tải vừa nặng CPU vừa nặng ổ đĩa, và là trường hợp hiếm mà nâng cả hai đều thấy khác biệt.
Mẹo nhỏ: đặt thư mục file tạm trên ổ nhanh nhất và dọn định kỳ. File tạm không được dọn là nguyên nhân đầy ổ phổ biến trong hệ thống có worker.
Đo để biết mình thuộc loại tải nào
# Trong luc he thong dang tai that
top -bn1 | head -5
vmstat 2 30 # cot us cao la chay vi xu ly; cot wa cao la cho o dia
iostat -x 2 10 # %util gan 100 la nghen o dia
# Xem tien trinh nao dang lam gi
py-spy dump --pid PID # neu da cai py-spy
cat /proc/PID/io # tong byte doc ghi
# Do thoi gian phan hoi tu ben ngoai
for i in $(seq 1 30); do
curl -o /dev/null -s -w "%{time_total}\n" http://127.0.0.1:8000/health
done | sort -n | awk '{a[NR]=$1} END {print "trung vi", a[int(NR/2)], "cham nhat", a[NR]}'| Bạn thấy | Loại tải | Cách chọn số tiến trình xử lý |
|---|---|---|
| Vi xử lý gần 100%, chờ ổ đĩa thấp | Nặng tính toán | Số tiến trình bằng số nhân, không hơn |
| Vi xử lý thấp, chờ ổ đĩa hoặc chờ mạng cao | Nặng chờ vào ra | Số tiến trình cao hơn số nhân, và dùng cơ chế bất đồng bộ |
| Cả hai đều thấp mà vẫn chậm | Nghẽn ở nơi khác | Kiểm cơ sở dữ liệu và dịch vụ bên ngoài |
| Bộ nhớ đầy, có tráo trang | Thiếu bộ nhớ | Giảm số tiến trình hoặc thêm RAM |
Chọn số tiến trình cho đúng
- Việc nặng tính toán: số tiến trình bằng số nhân. Nhiều hơn chỉ làm hệ thống bận chuyển qua lại giữa các tiến trình.
- Việc chủ yếu chờ cơ sở dữ liệu hoặc dịch vụ ngoài: dùng cơ chế bất đồng bộ trong một tiến trình sẽ hiệu quả hơn nhiều so với tăng số tiến trình.
- Mỗi tiến trình chiếm bộ nhớ riêng. Nhân số tiến trình với bộ nhớ mỗi cái, cộng phần dư cho hệ điều hành, rồi so với bộ nhớ máy.
- Đừng đặt số tiến trình theo công thức chép trên mạng. Đo bằng ba lệnh ở trên rồi điều chỉnh, vì mỗi ứng dụng một khác.
Khi tiến trình xử lý tệp
- Đây là loại tải nặng ổ đĩa, và ổ NVMe tạo khác biệt rõ. Xem VPS NVMe.
- Đừng để tệp tạm nằm cùng chỗ với dữ liệu quan trọng, vì tệp tạm làm đầy ổ rất nhanh.
- Đặt giới hạn kích thước tệp tải lên ở cả lớp gác cổng lẫn ứng dụng, và đặt hai nơi cùng một con số.
- Với việc xử lý dài, tách ra hàng đợi thay vì xử lý ngay trong lượt gọi. Người dùng không phải chờ, và bạn kiểm soát được số việc chạy song song.
Câu hỏi thường gặp
Vì sao thêm CPU mà ứng dụng không nhanh hơn?
Vì phần lớn thời gian nó đang chờ database hoặc dịch vụ ngoài chứ không tính toán. Kiểm tra bằng top, CPU thấp mà chậm là dấu hiệu rõ.
Nên chạy bao nhiêu worker?
Thường bằng số nhân cộng một cho tải hỗn hợp. Đặt quá nhiều làm tràn RAM và phản tác dụng.
Ổ NVMe giúp gì cho ứng dụng Python?
Giúp nhiều nếu ứng dụng đọc ghi file hoặc truy vấn database trên cùng máy. Với ứng dụng chỉ gọi API bên ngoài thì ít ảnh hưởng.
Nên tách worker ra máy riêng không?
Nên khi worker chạy tác vụ nặng và bạn không muốn nó làm chậm phần phục vụ người dùng. Dự án nhỏ thì để chung vẫn ổn nếu đặt hạn mức tài nguyên.
Bài viết liên quan
- Sửa lỗi Tailscale is stopped và error 503 no backend
- Top 10 workflow n8n cho doanh nghiệp Việt 2026
- Claude Code đọc repo lớn bị chậm: vì sao và cách xử lý
- VPS free dùng thử 2026: 5 cách get VPS miễn phí + caveat thật
- Sự kết hợp hoàn hảo: TND Cloud và PingPong Payment
- Playwright + Crawlee + VPS scrape 10k page mỗi ngày không bị ban



