Kỹ thuật Erasure Coding cho hệ thống phân tán
(transactional.blog)- Erasure Coding là kỹ thuật thỏa hiệp giữa hiệu quả lưu trữ và khả năng chịu lỗi, bằng cách chia dữ liệu thành các mảnh và parity để chịu được sự cố với dung lượng lưu trữ ít hơn so với sao chép toàn bộ
- Mô hình cơ bản là k+m=n, trong đó k là số mảnh dữ liệu cần để khôi phục, m là số mảnh parity đồng thời cũng là số lỗi có thể chịu được, và n là tổng số mảnh
- Trong kho lưu trữ object/blob, thay vì sao chép toàn bộ 3 bản, có thể dùng cấu hình như 10+5 để đặt các mảnh nhỏ lên nhiều máy chủ hơn và giảm dung lượng lưu trữ
- Hệ thống quorum bị giới hạn trong việc tiết kiệm lưu trữ nếu chỉ dùng đa số đơn giản; còn nếu thay đổi thành 3+2, 2+2, 1+2 theo số replica khả dụng như HRaft thì sẽ phát sinh gánh nặng tái mã hóa và provisioning dung lượng
- Khi triển khai thực tế, cần kiểm chứng độ biến động chi phí giải mã tùy theo tổ hợp mảnh phản hồi, cũng như sự khác biệt về metadata và yêu cầu căn chỉnh của Jerasure, ISA-L và liberasurecode
Thỏa hiệp cơ bản giữa hiệu quả lưu trữ và khả năng chịu lỗi
- Có hai cách cực đoan để lưu một tệp trên N máy chủ
- Nếu đặt bản sao đầy đủ của toàn bộ tệp trên mọi máy chủ, thì dù mất N-1 máy chủ vẫn không mất tệp, nhưng chi phí lưu trữ là lớn nhất
- Nếu chia tệp thành N mảnh có kích thước bằng nhau và lưu mỗi máy chủ một mảnh, thì hiệu quả lưu trữ là cao nhất, nhưng khi đọc sẽ cần đủ cả N mảnh
- Erasure Coding điều chỉnh hiệu quả lưu trữ và khả năng chịu lỗi ở giữa hai thái cực đó
- Có thể xây dựng mã phù hợp với mục tiêu “chia tệp thành N mảnh, nhưng vẫn khôi phục được dù M mảnh bị hỏng”
- Nó cung cấp kích thước mảnh nhỏ nhất cần thiết để đạt mục tiêu đó
- Trực giác đơn giản nhất là ví dụ với 3 máy chủ, chỉ cần đọc bất kỳ 2 máy chủ nào để lấy lại toàn bộ tệp
- Chia tệp thành hai mảnh A, B
- Tạo mảnh thứ ba C bằng A ⊕ B
- Nếu đọc được A và B thì ghép lại trực tiếp; nếu đọc được A và C hoặc B và C thì khôi phục mảnh còn thiếu bằng XOR
- Mọi Erasure Code đều tổng quát hóa mẫu này bằng cách tách thành các mảnh dữ liệu và mảnh parity
Mô hình k+m=n và overhead lưu trữ
- Cấu hình Erasure Code được biểu diễn bằng k + m = n
- k: số mảnh dùng để chia dữ liệu, và cần đọc tối thiểu k mảnh để khôi phục giá trị
- m: số mảnh parity được tạo ra, cũng là số lần đọc thất bại hoặc số lỗi có thể chịu được
- n: tổng số mảnh được tạo ra
- Kích thước của mỗi mảnh kết quả là 1/k kích thước tệp gốc
- Erasure Code thường được gọi bằng bộ
k+m- Tên biến không thống nhất giữa các tài liệu
x+ynghĩa là x mảnh dữ liệu và y mảnh parity
- Lý do hấp dẫn với nhà cung cấp lưu trữ là có thể đạt khả năng chịu lỗi với overhead lưu trữ thấp
- Backblaze B2 dùng 17+3, chịu được 3 lỗi với dung lượng lưu trữ gấp 1.18 lần
- OVH Cloud dùng mã 8+4, chịu được 4 lỗi với dung lượng lưu trữ gấp 1.5 lần
- Scaleway dùng mã 6+3, chịu được 3 lỗi với dung lượng lưu trữ gấp 1.5 lần
- Chi phí chính là sự đánh đổi giữa giảm dung lượng lưu trữ và tăng số yêu cầu đọc
- Thay vì đọc bằng kích thước tệp từ một đĩa, hệ thống phải gửi yêu cầu tới k+m đĩa
- Các hệ thống lưu trữ dữ liệu ít được truy cập phù hợp hơn vì gánh nặng IOPS bổ sung tương đối nhỏ, trong khi lợi ích tiết kiệm lưu trữ lại lớn
Phạm vi thuật toán và mã MDS
- “Erasure Coding” không phải một thuật toán cụ thể mà là một họ thuật toán
- Mã Reed-Solomon thường có thể dùng để hiện thực Erasure Code với cấu hình k+m bất kỳ
- Nó cũng có quan hệ tương ứng với RAID
- RAID-0 là Erasure Coding k+0
- RAID-1 là Erasure Coding 1+m
- RAID-4 và RAID-5 là Erasure Coding k+1 hơi khác một chút
- RAID-6 là Erasure Coding k+2
- Phạm vi của bài viết này là Erasure Code MDS (Minimum Distance Separable)
- Mã MDS cung cấp tính chất giống quorum: chịu được mất bất kỳ m mảnh nào
- Các họ Erasure Code khác có thể khôi phục với ít hơn m mảnh trong một số tổ hợp, nhưng ở tổ hợp khác lại có thể cần nhiều hơn m mảnh
- Nếu biết trước mẫu lỗi dự kiến, có thể có lợi khi khôi phục các lỗi thường gặp bằng ít mảnh hơn, còn các lỗi ngoại lệ thì chấp nhận cần nhiều mảnh hơn
- Local Reconstruction Codes và SD Codes của Azure Storage được nêu như ví dụ theo hướng này
Ứng dụng trong object storage và cache
- Ứng dụng trực tiếp nhất là giảm chi phí lưu trữ và tăng độ bền trong các hệ thống có tập replica cố định
- Ví dụ là blob/object storage hoặc lưu trữ NFS
- Dịch vụ metadata ánh xạ đường dẫn tệp tới các máy chủ đang lưu tệp đó
- Thay vì 3 replica mỗi replica giữ toàn bộ tệp, có thể có 15 replica lưu các mảnh tệp Erasure Coded 10+5
- Tổng lượng dữ liệu lưu trữ giảm còn một nửa
- Khả năng chịu lỗi tăng hơn gấp đôi
- Mẫu tổng quát hơn là “thay vì lưu dữ liệu trên X máy chủ, lưu trên X+m replica bằng X+m Erasure Code”
- Ví dụ về hệ thống cache của Marc Brooker áp dụng mẫu này cho cache
- Thay vì dùng consistent hashing để chọn một trong k máy chủ cache, hệ thống dùng mã k+m trên k+m máy chủ cache
- Không cần chờ m phản hồi chậm nhất
- Có thể đồng thời cải thiện dung lượng lưu trữ và tail latency
- Mức tiết kiệm này đi kèm chi phí tăng IOPS/QPS hoặc CPU
- Cần giả định tài nguyên giới hạn của hệ thống là dung lượng lưu trữ và CPU còn dư
- Với hệ thống đã gần chạm giới hạn CPU, đây có thể không phải là ý tưởng tiết kiệm chi phí
Giới hạn của hệ thống quorum và HRaft
- Trong 5 replica, quorum đa số đơn giản yêu cầu tối thiểu 3 cho cả đọc và ghi, nên ở phía đọc nó khá phù hợp với Erasure Code 3+2
- Vì có thể hoàn tất thao tác đọc từ kết quả của bất kỳ 3 replica nào
- Ghi có thể hoàn tất nếu bất kỳ 3 replica nào nhận được dữ liệu, nên với Erasure Code cố định chỉ có thể dùng mã 1+2
- 1+2 tương đương với 3 bản sao đầy đủ của tệp
- Chỉ áp dụng đơn giản như vậy thì không tiết kiệm được lưu trữ
- RS-Paxos cho rằng khi áp dụng Erasure Code cho Paxos, chỉ có lợi khi phần giao nhau của hai quorum lớn hơn 1 replica
- Ví dụ, với 7 replica mà cả đọc lẫn ghi đều cần ít nhất 5, thì có thể chịu được 2 lỗi và áp dụng mã 3+2
- Nói chung, với N replica và mức chịu lỗi mong muốn f, phương án Erasure Coding cố định tốt nhất có thể là (N-2f)+f
- HRaft điều chỉnh cách mã hóa theo số replica khả dụng ngay cả với quorum đa số đơn giản
- Nếu đủ 5 replica khả dụng thì dùng 3+2
- Nếu còn 4 replica khả dụng thì dùng 2+2
- Nếu còn 3 replica khả dụng thì dùng 1+2
- Cách thích nghi này có tiềm năng cải thiện nhưng cũng kèm ràng buộc vận hành
- Mỗi lần ghi sẽ ước lượng một cách lạc quan số replica khả dụng hiện tại
- Nếu một replica bất ngờ không chấp nhận ghi, hệ thống phải tái mã hóa bản ghi và gửi lại cho mọi replica
- Để tránh mất khả dụng do thiếu dung lượng đĩa hay thông lượng, ngay cả khi hoạt động ở cấu hình 1+2 sau hai lần lỗi, vẫn phải provisioning tập replica có thể lưu toàn bộ giá trị
- Nếu lỗi hiếm gặp và được khôi phục nhanh, cơ chế mã hóa thích nghi của HRaft có thể mang lại cải thiện đáng kể
Thư viện và ví dụ sử dụng
- Có thư viện chuẩn trưởng thành Jerasure cho tính toán Erasure Coding
- Trên các bộ xử lý Intel hiện đại, Intelligent Storage Acceleration Library của Intel là thư viện tối ưu hóa SIMD và luôn nằm trong nhóm đầu về benchmark
- Trong Python, có thể truy cập các hiện thực Erasure Coding bằng pyeclib
- Ví dụ sử dụng driver
liberasurecode_rs_vand - Mỗi mảnh có metadata được gắn ở đầu để nhận diện vị trí
- Ngoài ra còn có một vài byte bổ sung
- Ví dụ sử dụng driver
- Kết quả ví dụ của HRaft theo số replica khả dụng như sau
- 3+2, dữ liệu gốc 10000 byte: 5 mảnh, mỗi mảnh 3355 byte, tổng thực tế 16775 byte, hiệu suất 59.61%
- 2+2, dữ liệu gốc 10000 byte: 4 mảnh, mỗi mảnh 5021 byte, tổng thực tế 20084 byte, hiệu suất 49.79%
- 1+2, dữ liệu gốc 10000 byte: 3 mảnh, mỗi mảnh 10021 byte, tổng thực tế 30063 byte, hiệu suất 33.26%
- Mã hóa Erasure 1+2 tương đương với 3 bản sao đầy đủ của dữ liệu, tức giống hệt việc không áp dụng Erasure Encoding
Chi phí giải mã và khác biệt giữa các hiện thực
- Hiệu năng giải mã thay đổi theo số mảnh dữ liệu cần khôi phục
- Giải mã mã 3+2 bằng 3 mảnh dữ liệu gần như là phép tính đơn giản về mặt tính toán
- Để giải mã cùng tệp đó từ 2 mảnh dữ liệu và 1 mảnh parity, cần giải một hệ phương trình tuyến tính bằng Gaussian elimination
- Số mảnh parity cần dùng càng tăng thì lượng tính toán càng lớn
- Khi dùng Erasure Code trong hệ thống quorum, chi phí CPU có thể thay đổi tùy theo chính xác replica nào đã phản hồi
- liberasurecode trừu tượng hóa các thư viện hiện thực Erasure Coding phổ biến, nhưng điều đó không có nghĩa các hiện thực là tương đương nhau
- Hai mã đều là 3+2 không có nghĩa chúng được xây dựng bằng cùng một phép toán học
- liberasurecode không chỉ thêm thao tác đại số tuyến tính mà còn thêm metadata cần cho cấu hình và sử dụng decoder
- Metadata này không thể tắt hoặc chỉnh sửa
- Nếu dùng trực tiếp Jerasure hoặc ISA-L thì có thể chỉ xử lý dữ liệu Erasure Coded
- Tuy nhiên API yêu cầu phải cung cấp mảnh đó là mảnh dữ liệu thứ N hay mảnh parity, nên chỉ số vẫn phải được lưu dưới dạng metadata bằng cách nào đó
- Jerasure và ISA-L cũng khác nhau ở yêu cầu căn chỉnh
- Jerasure áp dụng một hoán vị lên đầu ra đại số tuyến tính như mong đợi
- Jerasure không thể đọc tập con hay siêu tập không được sắp thứ tự của dữ liệu đã mã hóa
- ISA-L không áp dụng hoán vị đó nên có thể giải mã từ tập con hay siêu tập không theo thứ tự
- Các hiện thực khác cũng là lựa chọn đáng cân nhắc
- tahoe-lafs/zfec
- catid/cm256
- catid/longhair
- catid/leopard
- Nếu đây trở thành nút thắt cổ chai, có thể tìm thư viện tối ưu hơn cho từng trường hợp dùng cụ thể, nhưng ISA-L nhìn chung đã đủ tốt
Lựa chọn thuật toán và cấu trúc toán học
- Trong thực tế, có thể coi Erasure Code như một hàm kỳ diệu biến 1 tệp thành n mảnh rồi khôi phục lại, mà vẫn không gây vấn đề trong sử dụng
- Cấu hình n mảnh thường được xây dựng bằng đại số tuyến tính trên Galois Field
- Không nhất thiết phải hiểu toán học này để dùng Erasure Code trong môi trường production
- Phần lớn mã MDS được tính bằng phép nhân ma trận
- Phép cộng được thay bằng XOR
- Phép nhân được thay bằng phép nhân đắt hơn trên GF(256)
- Với các trường hợp đặc biệt chỉ có 1~3 mảnh parity, tồn tại các thuật toán chỉ dùng XOR thay vì Reed-Solomon
- m=1: một mảnh parity duy nhất là XOR của mọi mảnh dữ liệu
- m=2: tương ứng với RAID-6, có nhắc tới Liberation codes, HDP codes, EVENODD, X-Codes
- m=3: có thể dùng STAR coding
- Trong trường hợp tổng quát, thường dùng họ Reed-Solomon
- Có thể dùng cấu trúc ma trận Vandermonde hoặc Cauchy
- Mục tiêu là phần k×k phía trên trở thành ma trận đơn vị để giữ nguyên từng mảnh dữ liệu, đồng thời sau khi xóa bất kỳ m hàng nào vẫn tồn tại ma trận nghịch đảo
- Mã hóa là nhân với ma trận này, còn giải mã là xóa các hàng tương ứng với mảnh đã mất rồi giải hệ phương trình tuyến tính
- Gaussian elimination mà ISA-L sử dụng là cách giải mã đơn giản nhất nhưng cũng chậm nhất
- Với ma trận Cauchy có thể cải thiện thêm, và catid/cm256 dùng hướng này
- Phương pháp nhanh nhất hiện nay có vẻ là cách được hiện thực trong catid/leopard, dùng Fast Fourier Transform cho cả mã hóa lẫn giải mã
Các bước tối ưu hóa hiện thực
- Có nhiều cấp độ để tăng tốc một hiện thực Erasure Code hoạt động với cấu hình k+m bất kỳ
- Bước đầu tiên là hiện thực thuật toán bằng C và dựa vào tự động vector hóa của compiler
- Đây là cách đơn giản nhất và có tính di động cao nhất
- Việc dùng
restrictvà đặt cờ biên dịch theo kiến trúc như-march=nativelà quan trọng
- Bước thứ hai là trừu tượng hóa chi tiết nền tảng bằng thư viện vector hóa hoặc compiler intrinsic
- google/highway
- xtensor-stack/xsimd
std::experimental::simd- GCC vector extension builtins
- Cốt lõi của mã hóa và giải mã là phép nhân và cộng trên Galois Field
- Các thư viện tối ưu được nhắc đến gồm catid/gf256 và James Plank’s Fast Galois Field Arithmetic Library
- Bước thứ ba là tự vector hóa trực tiếp các hàm mã hóa/giải mã cốt lõi
- Dự án PARPAR với fast-gf-multiplication và xor_depends work bàn về tính toán GF(256) tốc độ cao
- Bài viết tóm lược rằng có sự đồng thuận rằng phép nhân GF chỉ dựa trên XOR nhanh hơn phép nhân dựa trên bảng
- Xa hơn nữa, có thể chuyên biệt hóa mã cho từng cấu hình k+m cụ thể
- Tìm ma trận mã hóa tối ưu và lịch XOR phù hợp với đa thức GF cùng ma trận mã hóa cụ thể
- Áp dụng tối ưu cho phép toán, bộ nhớ và cache
- Dùng chương trình để dò lịch lệnh tối ưu cho kiến trúc cụ thể
- Các hiện thực và tài liệu liên quan được nêu gồm yuezato/xorslp_ec, Thesys-lab/tvm-ec, và "Fast Erasure Coding for Data Storage: A Comprehensive Study of the Acceleration Techniques"
Tài liệu để tìm hiểu sâu hơn
- Các tài liệu nhập môn đại số tuyến tính cho Erasure Coding hữu ích gồm
- Nếu muốn đào sâu trên diện rộng, bài viết gợi ý bắt đầu từ James S. Plank’s publications
1 bình luận
Ý kiến trên Hacker News
Tôi ngạc nhiên khi mã fountain không giới hạn tỷ lệ không được nhắc đến. Nếu bạn thích chủ đề này thì Luby Transform Code sẽ rất thú vị: https://en.wikipedia.org/wiki/Luby_transform_code
Bài báo này cũng là một phần tổng quan chi tiết hơn khá hay: https://switzernet.com/people/emin-gabrielyan/060112-capilla...
Mã LT được dùng làm mã ngoài trong mã hóa RaptorQ thời gian tuyến tính được đặc tả trong RFC6330: https://www.rfc-editor.org/rfc/rfc6330
Thứ hai, thuật toán thực ra chia làm hai phần: phần thứ hai, tạo block phục hồi, là tuyến tính, nhưng phần đầu tiên mất thời gian bậc ba theo số lượng thông điệp được gom vào một block. Gần như tương đương với khử Gauss trên ma trận
Có thể cache một phần quá trình mã hóa và giải mã, nhưng theo tôi mã hóa thời gian tuyến tính của RaptorQ về cơ bản chỉ là câu chữ marketing
Trước đây có ai đó từng đề xuất một thuật toán erasure coding khá dễ thương, dựa vào networking đa đường thay vì đĩa quay
Tôi nghĩ họ gọi nó là network coding; ý tưởng là trong một mạng có nhiều đường đi, thay vì đợi toàn bộ file từ máy chủ chính, bạn nhận từ một upstream một erasure code pha trộn hai phần của file, hoặc hai file, để lấy được file nhanh hơn
Tôi đoán đằng sau S3 hay các hệ thống cloud storage khác cũng có nhiều cách làm như vậy, đặc biệt nhiều khả năng là ở các tầng lưu trữ ít được truy cập. Tuy nhiên tôi không thực sự biết hệ thống nội bộ của AWS hay GCP
Nhân tiện, Freenet ít nhất cũng dùng các file được mã hóa bằng FEC, nhờ đó linh hoạt hơn trong việc nhận mảnh nào và giảm khả năng toàn bộ file bị hỏng chỉ vì một mảnh đơn lẻ biến mất
Erasure coding đã tồn tại từ rất lâu rồi. Còn nhớ các file PAR2 trên Usenet không? https://en.wikipedia.org/wiki/Parchive
Nếu quan tâm đến erasure coding, cũng đáng cân nhắc các trường hợp đa chiều lớn hơn. Không chỉ mã hóa trải trên nhiều đĩa, mà còn tính cả các miền lỗi khác như rack, phòng, trung tâm dữ liệu, region
Mục tiêu là chịu được không chỉ lỗi linh kiện chung mà cả lỗi hệ thống lớn hơn hoặc phân vùng mạng. Bài nhập môn hay: https://chameleoncloud.org/blog/2023/12/12/design-considerat...
Nếu cáp quang xuyên đại dương chỉ có 1Tbps, việc chuyển toàn bộ dữ liệu có thể mất hơn 6 tháng
Muốn biết liệu đã có ai dùng Wirehair trong dự án chưa: https://github.com/catid/wirehair
Tôi tò mò liệu nó có được định nghĩa đủ tốt để làm nền tảng dựa trên tiêu chuẩn cho một dự án lưu trữ tệp dung lượng lớn/khôi phục dữ liệu mà tôi đã ấp ủ gần 10 năm hay không. Dù không phải tiêu chuẩn chính thức, tôi cũng muốn biết liệu có thể dùng nó như một tiêu chuẩn phi chính thức không
Trong số các mã xóa khối lớn tôi tìm thấy đến nay, đây là cái duy nhất có cả hiệu năng thuật toán lý tưởng hoặc gần lý tưởng lẫn API tốt. Vì vậy, khác với RaptorQ, nơi các chi tiết nhỏ rò rỉ khắp nơi và làm tăng độ phức tạp cũng như sự cứng nhắc của phần còn lại trong stack, với mục đích của tôi nó là một hộp đen tốt
Tuy nhiên Wirehair không phải là đặc tả mà là một hiện thực hóa của một ý tưởng, và trông cũng giống một bản hiện thực thử nghiệm. Nó có vẻ ổn định, nhưng cho đến khi tôi tự viết thử một hiện thực thứ hai hoặc nó được dùng đủ rộng rãi để những góc cạnh sắc nhọn của thuật toán lộ ra, tôi vẫn lo liệu có thể dễ dàng chuyển sang một đặc tả đáng tin cậy hoặc một hiện thực thứ hai hay không
Tuy nhiên Qualcomm có thể cho rằng nó vướng bằng sáng chế RaptorQ, vì về mặt khái niệm chúng có liên quan. Những bằng sáng chế sớm nhất trong số đó có lẽ sắp hết hạn hoặc đã hết hạn rồi, nhưng tôi chưa kiểm tra các hồ sơ bọc ngoài gần đây. Qualcomm từng đưa ra một số cam kết rằng sẽ không áp dụng bằng sáng chế RaptorQ ngoài lĩnh vực không dây, nhưng tôi không nhớ điều đó có chỉ áp dụng cho các hiện thực tuân thủ hay không
Nếu muốn dùng trong phần lõi của giao thức Bitcoin thì cần đặc tả hóa, nên tôi từng xem xét cần những gì. Tôi và một số nhà phát triển Bitcoin khá quen với lý thuyết số và mã sửa lỗi, nhưng công việc đó không thật sự hấp dẫn lắm. Cấu trúc của Wirehair có khá nhiều chi tiết ứng biến, và với tính cách của chúng tôi thì rất dễ sa vào bẫy trong lúc cố cải thiện nó
Phía Bitcoin có thể lại quan tâm đến việc dùng rộng rãi fountain code, nên nếu chờ thêm một chút thì có khả năng ai đó sẽ viết đặc tả
Tùy vào mục đích sử dụng cụ thể, https://github.com/catid/fecal cũng có thể đáng quan tâm. Nếu số lượng xóa dự kiến rất thấp thì nó có thể nhanh hơn Wirehair
Leopard được nhắc trong bài không phải fountain code, nhưng kích thước block khá lớn. Về mặt đặc tả hóa thì đây là một ưu điểm, vì nó chỉ là một hiện thực rất nhanh của mã Reed-Solomon nhàm chán, nên trong đặc tả có lẽ chỉ cần ghi lại trường và lựa chọn bộ sinh
Đúng vậy. Đây là công nghệ cốt lõi đằng sau pool Erasure Code của Ceph: https://docs.ceph.com/en/latest/rados/operations/erasure-cod...
Tuy nhiên không phải không có cái giá phải trả. Về sau không thể thay đổi các tham số mã hóa là k, m, nên bạn phải chắc rằng các giá trị đó sẽ phù hợp trong thời gian dài, hoặc phải làm lại từ đầu
Vì tính thiếu linh hoạt này, sao chép vẫn là lựa chọn thống trị trong lưu trữ dữ liệu chịu lỗi có độ sẵn sàng cao
Nó chỉ dùng
--forcevà để lại một hệ thống tệp bị hỏngCó lẽ chỉ là kiểu hài hước “phải có mặt ở đó mới thấy buồn cười, và người đó không nên là tôi” thôi
Có đúng là các kết quả được tạo ra trong tình huống lỗi khi chỉ có M trong N cái khả dụng sẽ được mã hóa khác với khi cả N cái đều khả dụng không? Nếu vậy, có lẽ nên có một cờ bit biểu thị “cần mã hóa lại khi N được khôi phục”
Nếu không, sẽ còn lại những tệp không có khả năng phục hồi tốt lắm khi xảy ra mất mát ngẫu nhiên trong tập N
Mọi hệ thống lưu trữ phân tán đều cần một dạng thủ thư nào đó để kiểm tra và dọn dẹp các stripe, đưa chúng ra khỏi trạng thái rủi ro
Tôi cũng nghĩ đến thuật toán phân tán thông tin của Rabin. Nó được mô tả trong bài báo này:
https://dl.acm.org/doi/10.1145/62044.62050
Trên thực tế, có phải nó chỉ thực dụng với các workload chỉ đọc hoặc đọc rất nhiều không?