Sprites từ bỏ hệ thống tệp tự chế, chuyển sang Block Device đơn giản hơn
Fly.io thay thế hệ thống tệp JuiceFS tùy biến của nền tảng Sprites bằng Sprites Block Device (SBD) – một thiết kế đơn giản hơn nhiều. Thay vì phải đồng bộ ba lớp dữ liệu riêng biệt, SBD chỉ dùng một daemon và một bucket, giúp độ tin cậy tăng lên đáng kể theo kết quả kiểm thử nội bộ.

Có một nguyên tắc trong xây dựng hạ tầng mà kỹ sư Daniel Botha của Fly.io hay nhắc đến: đừng cố làm mọi thứ phức tạp chỉ vì bạn có thể. Giống như việc tự làm mì spaghetti từ đầu – nghe có vẻ công phu, nhưng rốt cuộc bạn chỉ cần một gói mì mua sẵn vẫn ngon và tiện hơn nhiều. Đó chính là bài học mà nhóm Sprites rút ra sau khi tự viết hệ thống tệp cho riêng mình.
Minh họa: đôi khi giải pháp đơn giản lại hiệu quả hơn
Khi giải pháp "thông minh" trở thành gánh nặng
Khi Sprites ra mắt, đây là một loại hạ tầng mới cho một loại sản phẩm mới. Nhóm phát triển không tìm được hệ thống tệp phù hợp nên đã tự xây dựng. Ban đầu, họ dùng một phiên bản JuiceFS được chỉnh sửa mạnh, chạy backend SQLite viết lại, lưu trữ đúng một tệp: một ảnh đĩa 100 GB định dạng ext4 được mount qua loop device.
Cách làm này hoạt động được. Sprites vận hành trên nền tảng đó, người dùng tạo ra rất nhiều instance, và các checkpoint diễn ra nhanh chóng vì chủ yếu chỉ là sắp xếp lại metadata. Nhưng khi mức sử dụng tăng lên, những vết nứt bắt đầu xuất hiện.
Vấn đề cốt lõi nằm ở chỗ: một hệ thống tệp dựa trên cơ sở dữ liệu metadata có hai thành phần không thể tách rời – các khối dữ liệu (chunk) trong bucket và cơ sở dữ liệu giải thích cách các khối đó ghép lại. Khi hai bên khớp nhau, bạn có tệp. Khi chúng lệch nhau, mọi thứ đổ vỡ.
Ba cuốn sổ, ba nguồn sự thật
Trên nền JuiceFS, mỗi đĩa của một Sprite phải được theo dõi bởi ba lớp riêng biệt:
- Các chunk trong object storage
- Cơ sở dữ liệu metadata cho biết chunk nào tạo nên ảnh đĩa nào
- Cơ sở dữ liệu checkpoint (checkpoints.db) liệt kê từng checkpoint và ảnh đĩa cần mount tương ứng
Mỗi lớp được lưu bền vững một cách độc lập, nghĩa là mỗi lớp có thể đúng trong khi các lớp khác sai. Một kịch bản có thật: một Sprite đột nhiên không khởi động được vì JuiceFS chạy ở chế độ writeback ghi metadata trước rồi mới tải byte lên sau. Nếu máy bị ngắt giữa hai bước, metadata trỏ tới một chunk không tồn tại. Kết quả là hệ thống ext4 phát hiện block hỏng checksum và chuyển sang chế độ chỉ đọc. Chuyển Sprite sang máy khác cũng vô ích, khôi phục checkpoint cũng không giúp gì, bởi các checkpoint là bản sao copy-on-write dùng chung chunk.
Spaghetti mà đi kèm bộ dụng cụ sửa chữa thì kiểu gì cũng để lại dư vị kỳ lạ, dù bạn nấu cách nào.
Bài kiểm tra khắc nghiệt và quyết định thay đổi
Nhóm Fly.io đã xây dựng một harness tự động điều khiển hàng loạt Sprite qua các chu trình ghi, checkpoint, ngủ, đánh thức và khôi phục, kiểm tra từng byte trả về. Họ chạy thử nghiệm trên 400 Sprite JuiceFS với khoảng 5.000 chu trình. Kết quả: không ít Sprite vĩnh viễn mất khả năng checkpoint.
Sau nhiều lần cố gắng hòa giải và thêm công cụ sửa lỗi, nhóm nhận ra vấn đề không nằm ở chi tiết kỹ thuật mà ở bản chất mong manh của thiết kế. Họ quyết định làm lại từ đầu.
SBD: chỉ là một ổ đĩa
Sprites Block Device (SBD) lấy một bucket và trình bày nó với nhân Linux dưới dạng block device thông qua NBD. Sprite định dạng thiết bị đó thành ext4 và mount như bất kỳ ổ đĩa nào trên máy Linux thông thường.
Điểm khác biệt cốt lõi: metadata giờ nằm ngay trong bucket, cùng với các block mà nó mô tả, nên không còn cơ sở dữ liệu riêng cần đồng bộ. Một daemon bên trong Sprite tên là sbd serve đảm nhận việc trả lời các lệnh đọc/ghi block từ nhân, tải các block "bẩn" lên object storage trong nền và flush khi cần đảm bảo dữ liệu đã rời khỏi máy.
Ext4 vẫn làm phần việc quen thuộc của nó. Điều thay đổi là mọi thứ bên dưới trở nên đơn giản hơn nhiều: một daemon và một bucket, thay cho hệ thống tệp, cơ sở dữ liệu và ảnh đĩa phải giữ đồng bộ với nhau.
Checkpoint đơn giản hơn nhưng đáng tin hơn
Dưới SBD, checkpoint là một bản snapshot block của toàn bộ volume, kèm số phiên bản, được ghi trong danh mục checkpoint của chính SBD. Chỉ còn một nguồn sự thật duy nhất.
Khôi phục cũng đơn giản tương tự: mỗi checkpoint biết phiên bản volume mà nó thuộc về, nên quá trình khôi phục chỉ cần unmount hệ thống tệp, tua volume về trạng thái cũ tại chỗ rồi mount lại. Chi phí gần như tương đương một lần khởi động lại.
SBD kiểm tra từng block đọc về từ object storage so với dữ liệu đã ghi. Nếu chính SBD gặp sự cố, toàn bộ Sprite sẽ khởi động lại, bởi một lần khởi động lại sạch là con đường duy nhất để quay về một ổ đĩa đáng tin cậy.
Kiến trúc đơn giản hơn giúp giảm điểm lỗi
Ý nghĩa với người dùng và nhà phát triển
Kết quả kiểm thử nội bộ cho thấy SBD có độ tin cậy cao hơn nhiều bậc so với hệ thống tệp tự chế trước đây. Với các nhà phát triển đang xây dựng ứng dụng trên nền tảng đám mây, câu chuyện của Fly.io là lời nhắc nhở quen thuộc: mỗi lớp trừu tượng tự viết thêm vào đều là một điểm có thể hỏng, và việc giữ cho nhiều nguồn dữ liệu đồng bộ với nhau thường khó hơn nhiều so với việc chỉ dùng một nguồn duy nhất.
SBD sẽ trở thành hệ thống tệp chính thức của Sprites từ nay về sau: ext4, trên block device, trên bucket. Thứ duy nhất theo dõi tệp của bạn là mã hệ thống tệp mà mọi máy Linux đều đã chạy sẵn. Các Sprite được tạo trước ngày 10/6 có thể di chuyển sang thiết kế mới theo hướng dẫn mà Fly.io công bố.


