Trong mạng lưới Filecoin, đơn vị lưu trữ cơ bản nhất được gọi là Sector. Thuật ngữ này tương đồng với khái niệm "sector" trên ổ cứng truyền thống – đơn vị lưu trữ nhỏ nhất có thể truy cập. Để chứng minh dữ liệu được lưu trữ một cách hợp lệ, Filecoin thực hiện một quy trình xử lý phức tạp bao gồm các giai đoạn: P1 (PreCommit 1), P2 (PreCommit 2), C1 (Commit 1) và C2 (Commit 2). Kết quả cuối cùng của quá trình này là tạo ra một bản sao (replica) của dữ liệu ban đầu.
Logic quản lý lưu trữ của Filecoin chủ yếu được triển khai trong module sector-storage. Hệ thống dựa trên sự phối hợp giữa hai thành phần chính: Manager và Worker.
1. Các thành phần hệ thống
- Manager: Đóng vai trò điều phối, quản lý danh sách các Worker và duy trì chỉ mục (index) của toàn bộ các Sector.
- Worker: Các tiến trình thực hiện tính toán nặng (P1/P2/C1/C2). Worker có thể chạy cục bộ (local) hoặc từ xa (remote).
- Scheduler: Bộ điều phối nằm trong Manager, có nhiệm vụ phân bổ các tác vụ (tasks) cho các Worker dựa trên tài nguyên khả dụng (CPU, RAM, GPU).
- Store: Hệ thống lưu trữ vật lý nơi chứa các file của Sector.
2. Cấu trúc và cấu hình Storage
Mỗi Store được định nghĩa qua file cấu hình sectorstore.json. Dưới đây là ví dụ về cấu trúc của nó:
{
"ID": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"Weight": 15,
"CanSeal": true,
"CanStore": false
}
Trong đó:
CanSeal: Cho phép Store này chứa các file tạm trong quá trình niêm phong (Seal).CanStore: Cho phép Store lưu trữ lâu dài kết quả cuối cùng (replica).Weight: Trọng số để hệ thống ưu tiên lựa chọn khi có nhiều Store khả dụng.
Trong mỗi Store, dữ liệu được phân chia vào ba thư mục chính:
- unsealed: Chứa dữ liệu gốc chưa được xử lý.
- cache: Chứa các tầng dữ liệu trung gian và các cây Merkle.
- sealed: Chứa bản sao dữ liệu đã được niêm phong hoàn tất.
3. Quy trình thực thi Seal Task
Các tác vụ trong quá trình niêm phong được định nghĩa theo các trạng thái cụ thể. Dưới đây là cách phân loại các loại tác vụ phổ biến:
type SectorTask string
const (
AddPieceTask SectorTask = "seal/v0/addpiece"
PreCommit1Task SectorTask = "seal/v0/precommit/1"
PreCommit2Task SectorTask = "seal/v0/precommit/2"
Commit1Task SectorTask = "seal/v0/commit/1"
Commit2Task SectorTask = "seal/v0/commit/2"
FinalizeTask SectorTask = "seal/v0/finalize"
FetchTask SectorTask = "seal/v0/fetch"
)
Chi tiết các giai đoạn:
- AddPiece: Dữ liệu thô của khách hàng được nạp vào thư mục
unsealed. - PreCommit 1 (P1): Thực hiện thuật toán SDR (Stacked DRG) để tạo ra 11 lớp dữ liệu (với Sector 32GB). Đây là giai đoạn tốn nhiều thời gian nhất và chiếm dụng dung lượng lớn trong thư mục
cache. - PreCommit 2 (P2): Tính toán Column Hash và xây dựng các cây Merkle (tree_d, tree_c, tree_r_last). Nếu P2 được thực hiện ở một Worker khác với P1, dữ liệu từ P1 sẽ được chuyển qua giao thức HTTP.
- Commit & Finalize: Sau khi tạo bằng chứng (proof) thành công, hệ thống sẽ thực hiện "dọn dẹp". Các dữ liệu trung gian không cần thiết sẽ bị xóa, chỉ giữ lại những dữ liệu cần thiết cho việc chứng minh lâu dài (PoSt).
4. Phân tích dung lượng lưu trữ
Đối với một Sector có kích thước tiêu chuẩn là 32GB, tổng dung lượng cần thiết trong quá trình tính toán là rất lớn, bao gồm:
- Dữ liệu gốc: 32GB.
- Cây Merkle của dữ liệu gốc: 32GB.
- Các lớp dữ liệu P1: 32GB x 11 lớp = 352GB.
- Dữ liệu P2 (Column Hash & tree_c): Khoảng 64GB.
- Bản sao cuối cùng & tree_r_last: ~33GB.
Tổng cộng, hệ thống cần hơn 512GB không gian đệm để xử lý một Sector 32GB.
5. Lưu trữ lâu dài (Persistence)
Sau khi hoàn tất, hệ thống chỉ lưu trữ Replica và tree_r_last. Điểm đáng chú ý là tree_r_last không được lưu trữ toàn bộ. Để tối ưu không gian, các tầng thấp nhất của cây Merkle thường được loại bỏ (pruning).
Với Sector 32GB, tree_r_last được chia thành 8 cây con. Mỗi cây con sau khi loại bỏ 2 tầng dưới cùng chỉ chiếm khoảng 9.13MB. Do đó, tỉ lệ lưu trữ thực tế so với dung lượng gốc chỉ rơi vào khoảng 1.0022 (tức là 32GB dữ liệu gốc sẽ tốn khoảng 32.07GB không gian lưu trữ thực tế trên đĩa).