Bắt đầu từ cái gì đã thay đổi, rồi mới tới tuning. Phần lớn trường hợp nguyên nhân nằm ở dữ liệu hoặc code, không phải cấu hình.
1. Khoanh vùng: job chậm dần theo ngày (dữ liệu tăng) hay chậm đột ngột từ một ngày (deploy mới, nguồn đổi)? So input size, số dòng, số file giữa ngày nhanh và ngày chậm; xem lịch sử commit và thay đổi cluster.
2. Đọc Spark UI của lần chạy chậm:
- Jobs/Stages: stage nào chiếm phần lớn thời gian.
- Summary Metrics của stage đó: max duration gấp nhiều lần median → skew; Shuffle Read lớn → join hoặc groupBy đang shuffle nhiều; Spill cao → partition quá to so với RAM; GC time cao → executor thiếu bộ nhớ.
- SQL tab: xem plan thực tế — bảng dim lớn dần có thể vượt ngưỡng broadcast và chuyển sang sort-merge join; filter có được đẩy xuống lúc đọc không.
3. Nguyên nhân hay gặp:
| Dấu hiệu | Nguyên nhân | Hướng xử lý |
|---|---|---|
| Vài task chạy lâu hơn hẳn | Data skew | AQE skew join, tách key nóng, salting |
| Hàng chục nghìn task rất ngắn | Small files | Compact file, coalesce trước khi ghi |
| Đọc toàn bộ bảng | Mất partition pruning (bọc hàm lên cột partition) | Lọc thẳng trên cột partition |
| Spill nhiều | Partition quá to | Tăng shuffle.partitions, bật AQE |
| Task chờ lâu mới chạy | Cluster bị job khác chiếm | Kiểm tra queue, lịch chạy |
4. Sửa và chặn tái phát: mỗi lần sửa một thứ rồi đo lại; thêm cảnh báo khi thời gian chạy vượt ngưỡng, ví dụ gấp đôi trung vị 7 ngày gần nhất.
Lưu ý: thêm executor là phản xạ đầu tiên của nhiều người, nhưng với skew hay small files thì tốn tiền hơn mà gần như không nhanh hơn. Nêu được bạn đã nhìn metric nào trên Spark UI để kết luận là phần nhà tuyển dụng muốn nghe nhất.