Spark: Thành phần & Tuning
🟠 Quan trọng · Data Platform
Spark có những thành phần nào?
3 tầng kiến trúc
| Tầng |
Thành phần |
Vai trò |
| API layer |
DataFrame, Dataset, SQL, RDD |
Interface cho developer viết code |
| Engine layer |
Catalyst optimizer, Tungsten execution engine |
Tối ưu query plan, quản lý memory |
| Runtime layer |
Driver, Executors, Cluster Manager |
Điều phối và chạy task song song |
Tip phỏng vấn: Trả lời theo đúng 3 tầng này sẽ gây ấn tượng tốt — không chỉ liệt kê "có DataFrame, có RDD".
Runtime chi tiết
- Driver (1 per app): Chứa SparkContext, DAG Scheduler, Task Scheduler. Điều phối toàn bộ.
- Executors (N workers): Chạy task thực tế, cache dữ liệu.
- Cluster Manager: YARN / Kubernetes / Standalone — cấp tài nguyên.
4 thư viện đi kèm
Spark SQL · Structured Streaming · MLlib · GraphX
Tune Spark job thế nào?
⚠️ Bước đầu tiên: Luôn xem Spark UI trước
Xác định bottleneck: stage nào chậm nhất, có skew không, shuffle bao nhiêu, có OOM không. Rồi mới chọn kỹ thuật.
Resource allocation
| Config |
Mô tả |
Rule of thumb |
spark.executor.memory |
Memory mỗi executor |
4-8 GB |
spark.executor.cores |
Cores mỗi executor |
4-5 cores |
spark.executor.instances |
Số executor |
Hoặc bật dynamicAllocation |
spark.driver.memory |
Memory driver |
Tăng khi collect() nhiều |
Shuffle & parallelism
| Config |
Mô tả |
spark.sql.shuffle.partitions |
Default 200. Data nhỏ giảm (20-50), data lớn tăng (500-2000) |
spark.sql.adaptive.enabled=true |
AQE — Spark 3.x tự coalesce partition nhỏ, convert join, xử lý skew |
Join optimization
| Kỹ thuật |
Khi nào |
Cách làm |
| Broadcast join |
1 bảng nhỏ (< 10MB) |
broadcast(df_small) hoặc set autoBroadcastJoinThreshold |
| Xử lý data skew |
1 partition quá lớn |
Salting key, AQE skew join, repartition key khác |
| Tránh cross join |
Luôn luôn |
Kiểm tra join condition |
Code-level
- Cache/persist:
df.cache() khi DataFrame dùng lại nhiều lần. Nhớ unpersist() khi xong.
- Filter sớm: Filter trước khi join. Predicate pushdown tự động với Parquet/Delta.
- Tránh UDF Python: Chạy ngoài JVM, không được Catalyst optimize. Ưu tiên built-in functions.
💾 Storage Tuning
| Khuyến nghị |
Lý do |
| Dùng Parquet/Delta thay CSV/JSON |
Column pruning, predicate pushdown, nén tốt hơn 5-10x |
Compression: snappy (default) |
Balance speed/size. Dùng zstd cho cold data |
Partition strategy
| Kỹ thuật |
Mô tả |
df.write.partitionBy("data_date") |
Chỉ đọc folder ngày cần thiết |
df.repartition(N) trước write |
Kiểm soát số file output. Target: 128-256 MB/file |
Delta Lake specific
| Lệnh |
Mục đích |
OPTIMIZE table ZORDER BY (col) |
Gộp small files, sắp xếp data theo cột thường filter |
VACUUM table RETAIN 168 HOURS |
Xóa file cũ, giải phóng storage |
autoCompact.enabled=true |
Tự động gộp file nhỏ sau mỗi write |
💡 Mẹo phỏng vấn
Khi được hỏi "tune Spark job thế nào", trả lời theo flow:
- Xác định bottleneck — xem Spark UI, tìm stage chậm nhất
- Áp dụng kỹ thuật tương ứng
- Kể case thực tế nếu có
Đừng nói "em tăng memory" mà không biết tại sao. Kể 1 case thực tế đã gặp sẽ rất được đánh giá cao.