8 điểm bởi GN⁺ 2025-11-16 | 1 bình luận | Chia sẻ qua WhatsApp
  • 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

 
GN⁺ 2025-11-16
Bình luận Hacker News
  • Tôi là một kỹ sư phần mềm làm việc tại Eventual, và muốn cảm ơn vì đã chia sẻ benchmark của Daft do nhóm chúng tôi xây dựng
    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 songpipeline. Đặ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 daft
    • Không rõ có kế hoạch đưa Daft ra làm backend của ibis hay không. Nếu vậy thì sẽ rất tiện để kiểm thử và chuyển đổi mượt mà từ các engine khác
    • Trông giống như đây là một tài khoản được tạo ra để quảng bá công ty
  • Awk à? Có một bài viết khá thú vị liên quan — Command-line tools can be 235x faster than your Hadoop cluster
  • 650GB thì nhỏ đến mức ngay cả điện thoại của tôi cũng chứa được
    Thay 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
    • Bây giờ đã khác thời kỷ nguyên Hadoop năm 2014 mà bài đó đề cập
      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
    • Nếu là 650TB thì câu chuyện sẽ hoàn toàn khác. Bài đó chỉ là một microbenchmark
      Trong thực tế, bạn sẽ cần data catalog và công việc chạy trên cluster
    • Chia sẻ video này kèm câu đùa: “Tôi quên mất phải đếm những con số nhỏ như thế nào”
  • Tôi thường xử lý ‘biggish data’ trên một node bằng DuckDB
    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
    • Cỡ 650GB thì ngay cả trên filesystem cục bộ cũng xử lý đủ tốt. Không cần công cụ phức tạp
  • Benchmark này trông như một thử nghiệm bị chi phối hoàn toàn bởi băng thông NIC
    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
    • Sẽ khá thú vị nếu thử cả trên desktop thông thường hoặc laptop đủ tốt
      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ộ
    • Khả năng cao truy vấn thực tế không quét toàn bộ file, mà tận dụng đọc theo byte range của S3 để chỉ xử lý một số cột
      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”
    • Giá trị của thí nghiệm này không rõ ràng
      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
    • 10Gbps là quá thấp. Ở Google, họ dùng NIC 400Gbps và TCP congestion control được cải thiện
      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
    • Tôi đồng cảm với nhận xét này. Có một bài học tôi học được ở Phố Wall 30 năm trước — trước khi kiểm thử hiệu năng hệ thống, hãy hiểu giới hạn lý thuyết tối đa trước
      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
  • Bài này là một bài viết diễn đạt sai vấn đề ở hai khía cạnh
    1. Trên thực tế rất có thể đã áp dụng column pruning nên chỉ truy cập 2 cột + metadata
    2. Phần lớn thời gian có lẽ bị khóa vào S3 I/O, và giới hạn số kết nối đồng thời mới là yếu tố ảnh hưởng lớn hơn
      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ớ
    • Điều quan trọng là truy vấn này là một projection chỉ trả về một phần của toàn bộ 650GB
      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
  • Gần đây tôi phải xử lý vài TB dữ liệu JSON, và vấn đề là vô số file nhỏ cỡ 10~20MB
    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
    • Không rõ bạn có chuyển dữ liệu JSON sang định dạng khác trước hay là làm việc trực tiếp trên JSON
  • Polars phụ thuộc vào delta-rs để hỗ trợ Delta Lake, và implementation này không hỗ trợ Deletion vectors
    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
    • Rất nhiều người chuyển sang Spark quá sớm chỉ vì nghĩ rằng “Spark dễ song song hóa”
      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
  • Presto (AWS Athena) cũng có thể là một lựa chọn nhanh hơn và tốt hơn. Tôi cũng muốn thử 650GB dữ liệu trên máy cục bộ
    • Presto giờ đã đổi tên thành Trino
      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
  • Định dạng catalog DuckLake mới của DuckDB cũng có vẻ là một ứng viên đáng thử — ducklake.select
    • Tính năng flush inline dữ liệu của DuckLake vẫn đang ở giai đoạn alpha
      Để 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
    • Định dạng DuckLake có một vấn đề con gà - quả trứng về phụ thuộc SQL
      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