- F3(Future-proof File Format) là định dạng lưu trữ dạng cột mã nguồn mở thế hệ tiếp theo, với các nguyên tắc thiết kế cốt lõi là khả năng tương tác, khả năng mở rộng và hiệu quả, nhằm loại bỏ nhu cầu phải tạo ra định dạng mới mỗi khi môi trường xử lý dữ liệu và tính toán thay đổi
- Mỗi tệp F3 có cấu trúc tự mô tả (self-describing), nhúng không chỉ dữ liệu và siêu dữ liệu mà còn cả bộ giải mã nhị phân WebAssembly(Wasm), nhờ đó bảo đảm khả năng tương thích trên mọi nền tảng ngay cả khi không có bộ giải mã native
- Cung cấp bố cục lưu trữ hiệu quả bao gồm các kỹ thuật mã hóa hiện đại như cascading compression và vectorized decoding, đồng thời cải thiện các vấn đề về bố cục của Parquet và ORC bằng cách tách riêng I/O, mã hóa và đơn vị từ điển
- Thông qua API giải mã dựa trên plugin và cơ chế nhúng Wasm, nhà phát triển có thể dễ dàng thêm các sơ đồ mã hóa mới, và mọi tệp đều có thể được đọc bất kể phiên bản thư viện, qua đó giải quyết vấn đề tương tác của Parquet
- Kết quả đánh giá cho thấy hiệu quả của bố cục lưu trữ F3 và lợi ích của giải mã dựa trên Wasm đã được chứng minh; phần chi phí lưu trữ chỉ ở mức kilobyte và mức suy giảm hiệu năng giải mã Wasm so với native ở mức 10~30%, chấp nhận được
Bối cảnh và động lực
Giới hạn của các định dạng dạng cột hiện có
- Parquet và ORC được phát triển vào đầu thập niên 2010 cho các hệ thống phân tích dữ liệu như Hive, Impala và Spark, cho phép chia sẻ dữ liệu giữa data warehouse và data lake
- Sau 10 năm, các nghiên cứu hiện nay cho thấy những định dạng này không còn đáp ứng tốt cho phân tích dữ liệu hiện đại, vì chúng được xây dựng dựa trên các giả định lỗi thời về hiệu năng phần cứng và giả định về mẫu truy cập workload tại thời điểm thiết kế
- Trong 10 năm qua, hiệu năng lưu trữ và mạng đã tăng lên hàng chục lần, trong khi CPU thì không, khiến hệ thống bị nghẽn ở khâu tính toán thay vì I/O
- Sự trỗi dậy của data lake khiến nhiều dữ liệu hơn được lưu trên cloud storage có băng thông cao nhưng độ trễ lớn (ví dụ: Amazon S3)
- Ứng dụng không còn chỉ lưu dữ liệu dạng bảng với số lượng cột ít. Trong workload ML, việc lưu các bảng rộng với hàng nghìn cột, vector embedding đa chiều và blob dung lượng lớn (hình ảnh, video) đã trở nên phổ biến
- Nhu cầu thực hiện truy cập ngẫu nhiên hoặc cập nhật cũng tăng lên, nhưng các định dạng hiện có không phù hợp với những kiểu sử dụng này
- Những tiến bộ gần đây về nén, lập chỉ mục và lọc đang cố gắng khắc phục các thiếu sót đó, nhưng các định dạng tệp hiện tại vốn không được thiết kế để dễ mở rộng
- Dù có thêm tính năng mới, vẫn khó kỳ vọng các thư viện Parquet và ORC ở nhiều ngôn ngữ khác nhau đều cập nhật lên phiên bản mới nhất
- Các hệ thống dùng thư viện cũ có thể không giải mã được nội dung của tệp mới, vì vậy phần lớn hệ thống chỉ hỗ trợ tập tính năng mẫu số chung thấp nhất để tránh vấn đề tương tác
Sự xuất hiện của các định dạng tệp mới và giới hạn của chúng
- Để vượt qua điều này, đã xuất hiện các đề xuất về những định dạng tệp hoàn toàn mới như Meta Nimble, Lance, TSFile, Bullion, BtrBlocks
- Tuy nhiên, chúng cũng mắc cùng những sai lầm như các thế hệ trước
- Được thiết kế dựa trên các giả định về phần cứng và workload hiện đại
- Không thúc đẩy được khả năng mở rộng dễ dàng để hỗ trợ tính năng mới mà không phá vỡ khả năng tương tác với các triển khai hiện có
- Ngay cả khi một trong số đó trở thành định dạng chủ đạo thay thế Parquet hoặc ORC, thì sau 10 năm nữa vẫn sẽ nảy sinh cùng một vấn đề: cần tạo ra một định dạng khác để khắc phục các khiếm khuyết của nó
Cách tiếp cận của F3
- F3 hướng tới việc đồng thời đạt được khả năng tương tác, khả năng mở rộng và hiệu quả
- Cốt lõi của F3 là định nghĩa ba đặc tả sau:
- Siêu dữ liệu của nội dung tệp
- Bố cục nhóm vật lý của dữ liệu đã được mã hóa trong tệp
- API truy cập dữ liệu không phụ thuộc vào sơ đồ mã hóa của dữ liệu
- Lược đồ siêu dữ liệu của F3 tối thiểu hóa lượng dữ liệu cần thiết để truy xuất một tập con cột của bảng
- F3 loại bỏ khái niệm "row group" bao trùm của Parquet và giải quyết vấn đề bố cục bằng cách tách riêng I/O, mã hóa và đơn vị từ điển
- Tích hợp các phương pháp hiện đại như cascading compression và vectorized decoding
Tổng quan về F3
Cấu trúc tổng thể
- Tệp F3 gồm phần siêu dữ liệu và phần dữ liệu
- Phần siêu dữ liệu: OptionalData(OptData), Column Metadata(ColMetadata), Footer, Postscript
- Phần dữ liệu: gồm các Row Groups(RG), chứa dữ liệu thực tế
- F3 áp dụng bố cục PAX giống như Parquet và ORC
- Tuy nhiên, F3 có nhiều khác biệt cốt lõi so với các định dạng hiện có:
- Siêu dữ liệu loại bỏ chi phí deserialization (khắc phục vấn đề của Parquet/ORC)
- Tách Physical I/O Unit(IOUnit) khỏi row group logic, cho phép điều chỉnh kích thước IOUnit độc lập theo từng loại phương tiện lưu trữ
- Tách phạm vi mã hóa từ điển khỏi row group logic, cho phép xác định phạm vi hiệu quả nhất cho từng cột
- Mỗi IOUnit gồm nhiều Encoding Unit(EncUnit), và EncUnit là đơn vị tối thiểu của mã hóa và giải mã
Cơ chế khả năng tương tác và mở rộng
- F3 công khai API để định nghĩa cách một triển khai giải mã dữ liệu nén bên trong tệp
- Phương thức mã hóa được coi là plugin, có thể cài đặt và nâng cấp tách biệt với thư viện lõi
- Để mọi phiên bản thư viện đều có thể đọc mọi tệp, F3 nhúng phần triển khai bộ giải mã vào bên trong tệp dưới dạng nhị phân WebAssembly(Wasm)
- Nói cách khác, mọi tệp F3 đều chứa cả dữ liệu lẫn mã để đọc dữ liệu đó
- API của F3 không yêu cầu triển khai riêng cho mã native và phiên bản Wasm; cùng một đoạn mã được biên dịch sang cả hai mục tiêu mà không cần chỉnh sửa
- Thiết kế này giúp F3 có tính bền vững cho tương lai, tránh được các vấn đề đã nêu và có thể tiến hóa nhanh hơn các giải pháp hiện có
- Nhà phát triển có thể triển khai các phương thức mã hóa tương lai vào hệ thống production bằng cách đưa mã Wasm vào tệp mà không cần lo nâng cấp phiên bản thư viện trên toàn bộ fleet
- Chi phí lưu trữ của nhị phân Wasm là không đáng kể (mức kilobyte), còn mức suy giảm hiệu năng giải mã Wasm so với triển khai native là tối thiểu (10~30%)
Kết luận
- F3 là định dạng tệp dạng cột thế hệ tiếp theo đồng thời đạt được khả năng tương tác, khả năng mở rộng và hiệu quả
- Thiết kế bố cục tệp hiệu quả giúp giải quyết sự kém hiệu quả của các định dạng hiện có
- API giải mã dựa trên plugin và nhúng Wasm cung cấp cơ chế bảo đảm cho tương lai, cho phép đọc mọi tệp bất kể phiên bản thư viện
- Kết quả đánh giá nguyên mẫu chứng minh hiệu quả của thiết kế bố cục và tính thực tiễn của cơ chế Wasm
- Overhead của Wasm nằm trong phạm vi chấp nhận được: lưu trữ ở mức kilobyte và suy giảm hiệu năng 10~30%
1 bình luận
Ý kiến trên Hacker News
Sau khi xem nhanh, có vẻ định dạng này đã khắc phục được khá nhiều nhược điểm của Parquet nên rất đáng kỳ vọng
Metadata của Parquet dù dựa trên Thrift nhưng chỉ có các chú thích kiểu “nếu có trường này thì bắt buộc cũng phải có trường kia”, chứ không có logic kiểm chứng thực sự, nên tôi nghĩ nếu nhét Thrift sai vào thì reader sẽ hỏng
Metadata của Parquet phải được parse, vì vậy việc cấp phát buffer và cấp phát động để parse metadata lặp đi lặp lại, gây ra quá nhiều heap allocation. Định dạng lần này dùng cách tiếp cận Flatbuffers nên có thể diễn giải trực tiếp các byte Flatbuffer và giải quyết được vấn đề đó
Tôi cảm thấy phần encoding mạnh hơn rất nhiều. Có vẻ như giờ đây đã có thể dùng các encoding nhẹ và có thể kết hợp với nhau, điều mà giới cơ sở dữ liệu đã cổ xúy từ lâu. Các định dạng trước đây như BtrBlocks, FastLanes vốn đã vượt trội hơn Parquet, nên thật tốt khi những ý tưởng hay của chúng được kế thừa
Tôi không thích record-shredding kiểu Dremel của Parquet vì quá phức tạp, nên mừng là lần này nó đã biến mất
Với Parquet, số row trong DataPage thay đổi nên muốn tìm một row cụ thể thì phải quét toàn bộ ColumnChunk, còn định dạng này có thể nhảy thẳng tới DataPage (IOUnit) mong muốn
Họ bỏ các kiểu nén nặng và chỉ giữ lại Delta/Dictionary/RLE. Nén nặng không mang lại lợi ích thực tế đáng kể, lại phiền khi triển khai và kéo theo nhiều phụ thuộc bên ngoài
Nhìn chung đây là một bước tiến lớn. Tôi hy vọng định dạng này sẽ thống trị ngành phân tích dữ liệu
Nếu “nén nặng” là zstd hay brotli, thì nó lại rất hữu ích với các cột chuỗi có ít lặp lại
Nếu thêm trình biên dịch wasm vào thì còn có thể tạo ra nhiều phụ thuộc hơn cả compression “heavy”
Thảo luận trên StackOverflow về việc thêm cột vào file Parquet
Dạo này có vẻ các phương pháp nén đã chốt về zstd rồi?
Parquet thực ra phức tạp một cách đáng ngạc nhiên. Muốn dùng đúng và hiệu quả thì phải nắm rất nhiều chi tiết vừa bất tiện vừa ít được tài liệu hóa, nên không hề dễ
Wes McKinney
Để giải thích cho ai chưa biết Wes McKinney, ông là người tạo ra Pandas, thư viện phân tích dữ liệu dạng bảng được dùng rộng rãi nhất trong Python
Định dạng do ông tạo ra có thể giành được niềm tin của thị trường ngay từ giai đoạn đầu, và vì ông đã gắn bó với vấn đề này trong thời gian dài nên góc nhìn của ông được xem là đặc biệt quan trọng
Andy Pavlo cũng rất đáng được nhắc tới
Với tư cách là một fan, tôi đồng ý về tầm ảnh hưởng của Pandas, nhưng về mặt kỹ thuật thì tôi nghĩ định dạng dữ liệu Arrow đã tác động lớn hơn tới toàn bộ hệ sinh thái dữ liệu (ví dụ như DataFusion)
Wes McKinney cũng là người sáng lập Apache Arrow
Tôi thậm chí còn thấy công việc của ông với Parquet mang lại nhiều cảm giác tin cậy hơn
Trộn dữ liệu với mã là một sai lầm bảo mật kinh điển
Có lẽ nó sẽ không áp dụng cho tương lai của các nhà vật lý
Dữ liệu ở quy mô exabyte được tạo ra từ Large Hadron Collider của CERN trong 20 năm tới sẽ dùng định dạng do chính CERN phát triển
Tài liệu về định dạng dữ liệu của CERN
CERN đã xử lý dữ liệu lớn từ sớm hơn phần lớn mọi người trong lĩnh vực này rất nhiều
Xin mọi người thông cảm vì tôi vẫn chưa hiểu rõ sự khác biệt với kiểu lưu trữ dạng cột
Tôi tò mò tại sao điều này lại mang tính cách mạng, và có câu hỏi rằng: “Có phải điểm mấu chốt là truyền một cơ sở dữ liệu vector embedding nhỏ kèm sandbox không?”
Bài báo cho tôi cảm giác đây có thể là nền tảng mới, và tên dự án cũng toát ra một kiểu hào quang kiểu Pháp (?)
Cá nhân tôi không hiểu phần lớn nội dung, chỉ thấy hình minh họa và màu sắc đẹp, táo bạo. Với tư cách người dễ bị thuyết phục, tôi giơ cả hai ngón cái
Điểm cốt lõi là lớp tương thích
Lợi thế thực sự của lưu trữ dạng cột là có thể tách các schema lồng nhau phức tạp thành các giá trị primitive để lưu
Lợi ích thật sự của lưu trữ hướng cột là có thể quét cực nhanh toàn bộ column trong một lần
select a where b = 'x'sẽ rất nhanhViệc decoder wasm chậm hơn native 10-30% là điều khá đáng thất vọng
Tức là chấp nhận mất 10-30% hiệu năng ngay từ đầu, đồng thời vĩnh viễn từ bỏ cơ hội cải thiện decoder về sau
Các tính năng decoding nâng cao ngoài kiểu “giải mã toàn bộ block rồi lưu vào bộ nhớ” cũng không dùng được
Thật sự tôi không hiểu tại sao lại cố làm như vậy
Nếu tốc độ quan trọng thì wasm không phải câu trả lời, còn nếu tốc độ không quá quan trọng thì cứ dùng các encoding đã được biết đến rộng rãi là được
WASM được cung cấp như phương án dự phòng
Tôi cũng đồng ý phần nào, nhưng câu chuyện phức tạp hơn thế
Tôi chưa hiểu chính xác quan hệ giữa Vortex và F3
Cả hai đều nói về tầm nhìn “cho phép thêm encoding dễ dàng mà không cần tạo ra định dạng mới”
Trong bài giới thiệu có nói dùng implementation encoding của Vortex, nhưng lại ghi rằng hệ thống kiểu là khác nhau
Bối cảnh phát triển dự án khá phức tạp
Khiến tôi bắt đầu mong cả F4 sẽ được công bố vào năm sau
Tôi đã tìm mã nguồn khá lâu, và nó đang được công khai ở đây
Việc đọc dữ liệu sẽ kéo theo nghĩa vụ phải chạy webassembly, nên tôi nghĩ nó không phù hợp với môi trường muốn giảm phụ thuộc hay giảm bloat
wasm rất đơn giản
Nếu có native decoder thì không cần dùng WASM
Có vẻ đây là một trong những file format đầu tiên nhúng mô-đun WebAssembly
Tôi đặc biệt quan tâm ở khía cạnh nén. Theo tôi, nếu thiết kế tốt WASM preprocessor thì tỷ lệ nén có thể cải thiện đáng kể
Bản thân tôi cũng đang làm một file format với ý tưởng này
Alan Kay từng mô tả một hệ thống lưu trữ dựa trên băng từ, có lẽ do một lập trình viên tạo ra vào thập niên 60, là “hệ thống hướng đối tượng đầu tiên”