Dữ liệu & bảng tính

DuckDB 2.0 alpha mang đến tốc độ đọc S3 nhanh hơn và truy vấn đệ quy

Bản DuckDB 2.0 alpha giới thiệu I/O bất đồng bộ cho lưu trữ đám mây, tối ưu hóa CTE đệ quy và kiểu dữ liệu VARIANT mới giúp phân tách (shred) JSON để nâng cao hiệu suất.

Hình minh họa xử lý dữ liệu nhanh với đầu vào stream và đầu ra có cấu trúc
Ảnh minh họa tạo riêng cho bài viết

Bài được dịch tự động từ bản gốc tiếng Anh.

Đội ngũ phát triển DuckDB đã ra mắt phiên bản alpha của DuckDB 2.0, đánh dấu một bước tiến đáng kể về hiệu suất cho các khối lượng công việc phân tích. Bản cập nhật này tập trung vào ba cải tiến kiến trúc chính: nhập/xuất bất đồng bộ cho lưu trữ đám mây, động cơ được viết lại cho biểu thức bảng chung đệ quy (recursive common table expressions), và một kiểu dữ liệu gốc mới để xử lý dữ liệu bán cấu trúc. Những thay đổi này nhằm mục đích giảm thời gian truy vấn và chi phí lưu trữ cho các kỹ sư xây dựng đường ống dữ liệu (data pipelines) trên máy tính xách tay hoặc trên đám mây.

Chuyện gì đã xảy ra

Lợi ích hiệu suất tức thì nhất đến từ cách DuckDB 2.0 xử lý dữ liệu được lưu trữ từ xa, chẳng hạn như trên Amazon S3. Trong các phiên bản trước, các luồng làm việc (worker threads) phải luân phiên giữa việc tải xuống các khối dữ liệu và xử lý chúng, khiến tài nguyên CPU bị nhàn rỗi trong thời gian chờ mạng. Phiên bản mới giới thiệu một nhóm luồng riêng biệt chỉ dành cho việc tải trước dữ liệu. Điều này cho phép hệ thống giữ cả kết nối mạng và CPU hoạt động đồng thời, giảm đáng kể tổng thời gian cần thiết để đọc các tệp Parquet hoặc CSV lớn từ bộ nhớ đối tượng (object storage).

Ngoài tốc độ thô, bản phát hành này giải quyết các mẫu truy vấn phức tạp liên quan đến dữ liệu phân cấp. Các biểu thức bảng chung đệ quy (CTE), thường được sử dụng để duyệt qua sơ đồ tổ chức hoặc cây phụ thuộc, đã được tái thiết kế hoàn toàn. Trước đây, mỗi cấp độ đệ quy yêu cầu quét toàn bộ bảng nguồn, khiến các cấu trúc phân cấp sâu trở nên cực kỳ chậm. Động cơ mới đọc bảng một lần và xây dựng một cấu trúc tra cứu nội bộ, cho phép nó nhảy trực tiếp đến các hàng liên quan cho từng cấp độ đệ quy tiếp theo. Thay đổi này biến các thao tác trước đây mất vài giây hoặc vài phút thành các tác vụ dưới một giây.

Sự bổ sung lớn thứ ba là kiểu dữ liệu VARIANT, được thiết kế để xử lý JSON và các định dạng bán cấu trúc khác một cách hiệu quả hơn. Thay vì lưu trữ JSON dưới dạng chuỗi văn bản thuần túy, DuckDB 2.0 phân tích dữ liệu trong quá trình ghi. Nó xác định các trường xuất hiện nhất quán với cùng một kiểu dữ liệu ở hầu hết các hàng và lưu trữ chúng dưới dạng các cột riêng biệt, được tối ưu hóa. Chỉ những trường không đều hoặc hiếm gặp mới được giữ lại trong một blob nhị phân. Quá trình này, được gọi là shredding (phân tách), giảm dung lượng lưu trữ và tăng tốc các truy vấn lọc hoặc tổng hợp dựa trên các trường nhất quán đó.

Chi tiết chính

  • I/O bất đồng bộ cải thiện tốc độ đọc S3 gấp hai đến ba lần mà không cần thay đổi bất kỳ câu truy vấn SQL hiện có nào.
  • Cài đặt read_ahead_depth kiểm soát số lượng nhóm hàng (row groups) được tải trước, mặc định là tự động điều chỉnh dựa trên số lượng luồng.
  • Hiệu suất CTE đệ quy được cải thiện đáng kể trong các bài kiểm tra, giảm từ tối đa 16 giây xuống còn 0,10 giây khi duyệt lịch sử git gồm 20.000 commit.
  • Kiểu VARIANT mới giảm yêu cầu lưu trữ khoảng 2,7 lần so với việc lưu trữ JSON dưới dạng chuỗi văn bản.
  • Các truy vấn lọc trên các trường VARIANT đã được shred chạy nhanh hơn khoảng sáu lần so với việc phân tích cú pháp văn bản JSON và đạt gần bằng tốc độ của các cột có kiểu dữ liệu gốc.
  • Các thao tác danh sách (list operations) trong dữ liệu VARIANT hiện tại thực hiện chậm hơn so với truy cập trường, gợi ý rằng người dùng nên tránh ép kiểu danh sách trong các đường dẫn truy vấn quan trọng về hiệu năng.

Bối cảnh

Để hiểu rõ những cải tiến này, sẽ hữu ích nếu biết cách các cơ sở dữ liệu phân tích thường xử lý dữ liệu. Các động cơ truyền thống thường coi độ trễ mạng và xử lý CPU là các bước tuần tự. Khi đọc từ lưu trữ đám mây, cơ sở dữ liệu phải chờ dữ liệu đến trước khi bắt đầu tính toán. I/O bất đồng bộ tách rời các nhiệm vụ này, cho phép cơ sở dữ liệu tải trước dữ liệu trong khi đồng thời xử lý các khối dữ liệu đã được tải trước đó. Điều này tương tự như cách một trình phát video đệm các cảnh tiếp theo trong khi bạn đang xem cảnh hiện tại.

CTE đệ quy là một tính năng SQL được sử dụng để truy vấn các cấu trúc phân cấp, chẳng hạn như dòng báo cáo của nhân viên hoặc cây thư mục tệp. Trong các cài đặt cũ, cơ sở dữ liệu sẽ lặp đi lặp lại việc quét toàn bộ bảng để tìm cấp độ tiếp theo của cấu trúc phân cấp. Nếu một cây có mười cấp độ, bảng sẽ được quét mười lần. Cách tiếp cận mới xây dựng một cấu trúc giống chỉ mục trong bộ nhớ sau lần quét đầu tiên, cho phép cơ sở dữ liệu xác định các bản ghi con ngay lập tức mà không cần đọc lại dữ liệu nguồn. Điều này chuyển chi phí từ việc tỷ lệ thuận với độ sâu của cây nhân với kích thước bảng, sang tỷ lệ thuận chỉ với số lượng hàng thực sự được truy cập.

Tại sao điều này quan trọng

Đối với các đội ngũ vận hành hạ tầng dữ liệu riêng, những thay đổi này giảm nhu cầu sử dụng các công cụ chuyên biệt. Trước đây, các truy vấn phân cấp sâu có thể đòi hỏi xuất dữ liệu sang cơ sở dữ liệu đồ thị hoặc viết mã ứng dụng tùy chỉnh để quản lý việc duyệt. Với DuckDB 2.0, các thao tác này trở nên khả thi trong phạm vi SQL tiêu chuẩn, đơn giản hóa ngăn xếp công nghệ. Tương tự, hiệu suất S3 được cải thiện nghĩa là việc giữ dữ liệu trong bộ nhớ đối tượng chi phí thấp trở nên khả thi hơn cho phân tích tương tác, giảm áp lực phải di chuyển mọi thứ sang bộ nhớ khối hiệu suất cao đắt đỏ.

Kiểu VARIANT cung cấp một giải pháp trung gian thực tế để xử lý dữ liệu thực tế lộn xộn. Các kỹ sư thường gặp khó khăn khi lựa chọn giữa các schema cứng nhắc, vốn dễ vỡ khi định dạng dữ liệu thay đổi, và các chuỗi JSON linh hoạt nhưng chậm khi truy vấn. Bằng cách tự động tối ưu hóa các phần nhất quán của dữ liệu JSON trong khi vẫn giữ tính linh hoạt cho phần còn lại, DuckDB 2.0 cho phép các đội ngũ nạp dữ liệu nhật ký hoặc sự kiện bán cấu trúc mà không hy sinh hiệu suất truy vấn. Điều này giảm nỗ lực kỹ thuật cần thiết để làm sạch và mô hình hóa dữ liệu trước khi nó có thể được phân tích.

Tuy nhiên, những lợi ích này đi kèm với trách nhiệm mô hình hóa. Hiệu suất của VARIANT phụ thuộc rất nhiều vào tính nhất quán của dữ liệu. Nếu một trường đôi khi chứa số và đôi khi chứa chuỗi, nó không thể được shred hiệu quả và sẽ vẫn nằm trong kho lưu trữ nhị phân chậm hơn. Các đội ngũ phải đảm bảo rằng đường ống dữ liệu của họ tạo ra các kiểu dữ liệu nhất quán cho các trường chính để đạt được mức tăng hiệu suất. Ngoài ra, mặc dù I/O bất đồng bộ giúp ích cho các tệp lớn, nó không giải quyết được độ trễ cố hữu khi truy cập hàng nghìn tệp nhỏ, củng cố thông lệ tốt nhất là hợp nhất các tập dữ liệu nhỏ thành các phân vùng lớn hơn.

Bạn có thể làm gì

  • Kiểm tra bản phát hành alpha trên máy cục bộ của bạn bằng cách sử dụng script cài đặt được cung cấp để đo điểm chuẩn (benchmark) cho các khối lượng công việc cụ thể của bạn.
  • Xem xét lại các truy vấn dựa trên S3 của bạn để đảm bảo bạn đang đọc các tệp Parquet lớn thay vì nhiều tệp nhỏ để tối đa hóa lợi ích của I/O bất đồng bộ.
  • Xác định các truy vấn đệ quy trong codebase của bạn, chẳng hạn như duyệt sơ đồ tổ chức hoặc mở rộng danh sách vật liệu (bill-of-materials), và chạy lại chúng để đo lường mức nền hiệu suất mới.
  • Kiểm toán các bảng nặng JSON của bạn để tìm các trường có kiểu dữ liệu nhất quán và cân nhắc chuyển đổi chúng sang kiểu VARIANT để giảm lưu trữ và cải thiện tốc độ lọc.
  • Tránh ép kiểu danh sách VARIANT sang mảng trong các truy vấn quan trọng về hiệu năng cho đến khi các bản cập nhật trong tương lai tối ưu hóa thao tác này.
  • Theo dõi cài đặt read_ahead_depth nếu bạn gặp áp lực bộ nhớ, mặc dù cấu hình tự động mặc định nên phù hợp với hầu hết các môi trường.

Tin khác

Tất cả tin