- Thử nghiệm so sánh hiệu năng khi lưu dữ liệu Delta Lake quy mô 650GB trên S3 và xử lý trong môi trường một nút bằng Polars, DuckDB, Daft, Spark
- Xác minh liệu từng engine có thể xử lý dữ liệu lớn trên một instance EC2 với 32GB bộ nhớ hay không, đồng thời khám phá khả năng của mô hình một nút so với Spark dựa trên cụm
- DuckDB mất 16 phút, Polars 12 phút, Daft 50 phút, PySpark hơn 1 giờ, cho thấy khả năng xử lý thực tế ngay cả trên một nút
- Polars không hỗ trợ Deletion Vector, trong khi chỉ DuckDB hỗ trợ tính năng này nên có khác biệt về khả năng tương thích Lake House
- Kết quả cho thấy các framework một nút vẫn có thể xử lý dữ liệu quy mô lớn trên phần cứng chi phí thấp, đặt ra nhu cầu xem xét lại mức độ phụ thuộc vào điện toán phân tán
Mệt mỏi vì cluster và lựa chọn thay thế bằng một nút
- Chi phí và độ phức tạp khi vận hành các cluster Lake House dựa trên SaaS ngày càng tăng, dẫn đến hiện tượng “mệt mỏi vì cluster (cluster fatigue)”
- Trước đây gần như không có lựa chọn nào ngoài Pandas nên phải dùng Spark, nhưng sự xuất hiện của DuckDB·Polars·Daft (D.P.D.) đã mở rộng khả năng xử lý trên một nút
- D.P.D. có thể xử lý bộ dữ liệu lớn hơn bộ nhớ (LTM) và thực hiện tính toán tốc độ cao
- Bài viết đưa ra hai hướng lựa chọn là phân tán và không phân tán, đồng thời nhấn mạnh khái niệm “Single Node Rebellion”
Cấu hình môi trường thử nghiệm
- Tạo bảng Delta Lake trên S3 và lưu khoảng 650GB dữ liệu (mục tiêu ban đầu là 1TB nhưng đã dừng lại)
- Chạy DuckDB, Polars, Daft trên instance EC2 (32GB RAM, 16 CPU) rồi so sánh với Spark
- Dữ liệu là dữ liệu mô phỏng dưới dạng bài đăng mạng xã hội; tạo Python dict, chuyển sang Daft DataFrame rồi lưu thành file Parquet
- Sau đó chuyển các file Parquet thành bảng Delta Lake trong Databricks, với phân vùng theo năm và tháng
- Khi loại trừ Delta log, xác nhận có khoảng 650GB dữ liệu
Giới hạn bộ nhớ và nhu cầu streaming
- Vì phải xử lý 650GB dữ liệu trên một nút đơn (32GB bộ nhớ), bài viết nêu ra sự cần thiết của thực thi truy vấn theo kiểu streaming
- Trích dẫn issue trên GitHub của Polars, bài viết đề cập đến trường hợp yêu cầu tính năng ghi streaming sang Iceberg
- Nhấn mạnh rằng các framework thế hệ mới như Polars và DuckDB cần có hỗ trợ gốc để đọc/ghi các định dạng Lake House theo kiểu streaming
Kết quả thử nghiệm theo từng engine
- DuckDB
- Là engine duy nhất hỗ trợ Deletion Vector
- Xử lý thành công 650GB dữ liệu chỉ trong 16 phút trên máy Linux 32GB
- Mã đơn giản và file kết quả được tạo bình thường
- Polars
- Không hỗ trợ Deletion Vector nên có hạn chế trong môi trường Lake House
- Cần sử dụng Lazy API (Scan/Sink)
- Hoàn tất xử lý trong 12 phút, nhanh hơn DuckDB
- Daft
- Dựa trên Rust, trải nghiệm sử dụng tốt nhưng thời gian xử lý 50 phút là chậm nhất
- Được xác nhận hoạt động ổn định trong các tác vụ liên quan đến Iceberg
- PySpark (Databricks Single Node)
- Mất hơn 1 giờ, chạy không tinh chỉnh
- Hiệu quả thấp hơn so với các engine một nút
- Mục tiêu thí nghiệm không phải là tốc độ mà là xác minh tính khả thi của mô hình một nút
Kết luận và hàm ý
- Thử nghiệm chứng minh rằng các framework một nút có thể xử lý dữ liệu Lake House dung lượng lớn
- Ngay cả trên phần cứng chi phí thấp vẫn đạt được thời gian thực thi hợp lý và cấu trúc mã đơn giản
- DuckDB, Polars, Daft đều mang lại hiệu năng thực dụng ngay cả khi không dùng cluster phân tán
- Điều này cho thấy điện toán phân tán không phải là lời giải duy nhất, đồng thời đặt ra nhu cầu xem xét lại kiến trúc Lake House hiện đại
- Thông qua khái niệm “Single Node Rebellion”, bài viết làm nổi bật khả năng tiếp cận data engineering theo hướng hiệu quả chi phí
1 bình luận
Bình luận Hacker News
Daft là một engine xử lý dữ liệu hiệu năng cao cho workload AI, hoạt động cả trên một node lẫn trong môi trường phân tán
Qua benchmark này, chúng tôi đã phát hiện ra khá nhiều dư địa để cải thiện tính song song và pipeline. Đặc biệt là còn nhiều điểm có thể tối ưu ở deltalake reader và toán tử groupby
Chúng tôi dự định sẽ phản ánh các cải tiến này trong những bản phát hành sắp tới; có thể xem chi tiết tại GitHub, Twitter, LinkedIn
Nếu thấy Daft thú vị, bạn có thể tự dùng thử với
pip install daftThay vì tooling quá mức, cứ dùng các công cụ GNU là được
Nhân tiện, đây là một bài cũ nhưng vẫn đáng đọc — command-line tools can be 235x faster than your Hadoop cluster
Nếu tổng hợp 650GB dữ liệu JSON bằng công cụ CLI thì khó mà theo kịp hiệu năng xử lý song song của DuckDB hay ClickHouse. Tôi cũng đã thử với GNU Parallel nhưng có giới hạn
Trong thực tế, bạn sẽ cần data catalog và công việc chạy trên cluster
Tôi truy vấn bằng cách duyệt trực tiếp các file Parquet thay vì dùng Delta hay Iceberg
Tôi tải kết quả truy vấn từ BigQuery xuống thành các file Parquet cục bộ (khoảng 1GB mỗi file) rồi phân tích bằng DuckDB. Dữ liệu lớn hơn RAM khá nhiều nhưng vẫn chạy tốt
Tôi cũng so sánh chênh lệch hiệu năng tổng hợp giữa BigQuery và DuckDB để chia workload chạy trên hai engine. Kiểu kết hợp này là phần thú vị của data engineering
Với băng thông tối đa 10Gbps của instance c5.4xlarge, chỉ riêng việc đọc 650GB từ S3 đã mất ít nhất 9 phút
Có vẻ khác biệt nhỏ trong cách lên lịch I/O đã tạo ra ảnh hưởng lớn đến kết quả
Thậm chí dùng instance lớn hơn để chạy xong nhanh hơn còn có thể kinh tế hơn
NVMe storage nhanh hơn S3 rất nhiều, và CPU cục bộ 8~16 lõi có thể còn tốt hơn cloud
S3 là một sản phẩm tuyệt vời, nhưng không thể sánh với hiệu năng storage cục bộ
Phân bố kích thước file hay độ lệch của các lệnh gọi API có lẽ mới là biến số lớn hơn
Tôi hoàn toàn đồng ý với ý rằng “instance lớn hơn có thể kết thúc rẻ hơn”
Spark phù hợp với các tập dữ liệu lớn nhiều giai đoạn, và khi dùng S3 làm backend thì nút thắt mạng sẽ hiện ra dưới dạng chi phí
Hiệu năng single-node của DuckDB/Polars rất ấn tượng, nhưng điều đó giống như cho máy bay trên đường băng đua với xe máy
Chính những khác biệt kiểu này khiến nhiều người mệt mỏi với distributed computing
Nếu xác định được giới hạn tài nguyên và biểu diễn hiệu năng thực tế dưới dạng tỷ lệ so với giới hạn đó, mọi thứ sẽ rõ ràng hơn nhiều
Việc thử nhiều hệ thống khác nhau là tốt, nhưng tôi muốn thấy họ thực sự xử lý các truy vấn lớn hơn bộ nhớ
DuckDB mạnh ở streaming vượt quá bộ nhớ, còn Polars thì vẫn chưa đủ trưởng thành
Cấu hình mặc định của S3 không ngăn việc đọc song song, nên cuối cùng băng thông mạng của VM nhiều khả năng mới là nút thắt
ClickHouse là nhanh nhất, còn DuckDB là tốt nhất về độ đơn giản và ổn định
Flink và PySpark chậm hơn 3~5 lần, Dask và Ray cũng quá chậm
Giờ tôi khuyên nên bắt đầu với DuckDB hoặc ClickHouse cho hầu hết workload. Thay Pandas bằng DuckDB khi Pandas chậm là chiến lược mặc định của tôi
Ngay cả với thư viện single-node thì xử lý khoảng 1TB cũng hoàn toàn ổn, còn từ hơn 10TB thì có thể chuyển sang Spark
Vấn đề liên quan
Nhưng trong nhiều trường hợp có thể giải quyết bằng công cụ tốt hơn
Trước đây có một kỹ sư junior mất 18 tiếng để xử lý vài trăm file JSON 5GB bằng ghép chuỗi Python,
nhưng khi đổi sang công cụ console đơn giản và multiprocessing thì giảm xuống còn 35 phút
Chọn đúng công cụ mới là cốt lõi
Chi phí bảo trì và vận hành rất rẻ, là một công cụ có hiệu quả chi phí cao
Để giải quyết vấn đề có quá nhiều file Parquet khi ghi theo batch nhỏ, DuckLake lưu inline chúng vào DBMS (như Postgres)
Chỉ gần đây mới có tính năng ghi lại ra Parquet, nhưng hiện vẫn cần thêm thời gian để ổn định
Tài liệu liên quan
Catalog phải được biểu diễn bằng SQL DB, trong khi ưu điểm của Parquet chính là tránh đi sự phức tạp đó
Nếu catalog cũng được làm trên nền Parquet thì có lẽ sẽ trở thành một định dạng tự bootstrap