삭제 코딩은 분산 스토리지 시스템의 핵심 데이터 보호 방법입니다. 이 블로그 게시물에서는 삭제 코딩이 데이터 보호에 대한 기업 요구 사항을 충족하는 방법과 이를 MinIO에서 구현하는 방법에 대해 설명합니다.
하드웨어 오류, 특히 드라이브 오류는 흔히 발생하므로 데이터 보호는 모든 엔터프라이즈 환경에서 필수적입니다.
전통적으로 하드웨어 내결함성을 제공하기 위해 다양한 유형의 RAID 기술이나 미러링/복제가 사용되었습니다. 미러링 및 복제는 하나 이상의 완전한 중복 데이터 복사본에 의존합니다. 이는 스토리지를 소비하는 비용이 많이 드는 방법입니다. RAID5 및 RAID6과 같은 보다 복잡한 기술은 스토리지 오버헤드를 줄이면서 동일한 내결함성을 제공합니다. RAID는 단일 노드의 데이터 보호를 위한 좋은 솔루션이지만 오류가 발생한 드라이브를 다시 온라인으로 전환하는 데 필요한 재구축 작업에 시간이 많이 걸리기 때문에 확장에 실패합니다.
많은 분산 시스템은 데이터 보호를 위해 3방향 복제를 사용합니다. 즉, 원본 데이터는 3개의 서로 다른 드라이브에 완전히 기록되고 어느 한 드라이브에서든 원본 데이터를 복구하거나 읽을 수 있습니다. 복제는 스토리지 활용도 측면에서 비효율적일 뿐만 아니라 장애 복구 시 운영 측면에서도 비효율적입니다. 드라이브에 오류가 발생하면 시스템은 성능이 저하된 상태에서 읽기 전용 모드로 전환되고 오류가 발생한 드라이브를 교체하기 위해 손상되지 않은 드라이브를 새 드라이브에 완전히 복사합니다.
삭제 코딩은 복원력이 뛰어나고 효율적이기 때문에 분산 스토리지의 데이터 보호에 적용됩니다. 데이터 파일을 데이터 및 패리티 블록으로 분할하고 인코딩된 데이터의 일부를 사용할 수 없는 경우에도 기본 데이터를 복구할 수 있도록 인코딩합니다. 수평으로 확장 가능한 분산 스토리지 시스템은 삭제 코딩을 사용하여 여러 드라이브와 노드에 인코딩된 데이터를 저장함으로써 데이터 보호를 제공합니다. 드라이브나 노드에 장애가 발생하거나 데이터가 손상된 경우 다른 드라이브나 노드에 저장된 블록을 사용하여 원본 데이터를 재구성할 수 있습니다.
삭제 코딩은 노드와 드라이브 전체에 데이터를 스트라이핑함으로써 훨씬 더 나은 효율성으로 다른 기술과 동일한 수의 드라이브 오류를 허용할 수 있습니다. 다양한 삭제 코딩 알고리즘이 있으며 Reed-Solomon과 같은 MDS(Maximum Distance Separable) 코드가 가장 큰 저장 효율성을 달성합니다.
객체 스토리지에서 보호해야 할 데이터의 단위는 객체입니다. 객체는 n개의 드라이브에 저장될 수 있습니다. k가 잠재적인 오류를 나타내는 경우 k < n이고 MDS 코드를 사용하면 시스템은 n - k 드라이브 오류를 허용할 수 있습니다. 즉, k 드라이브가 모든 개체에 액세스하기에 충분하다는 의미입니다.
M바이트 크기의 객체를 고려하면, 코딩된 각 객체의 크기는 M/k(메타데이터 크기 무시)이다. 위에 표시된 N 방향 복제와 비교하여 n = 5 및 k = 3으로 구성된 삭제 코딩을 사용하면 분산 스토리지 시스템은 2개의 드라이브 손실을 허용하는 동시에 스토리지 효율성을 80% 향상시킬 수 있습니다. 예를 들어 10PB의 데이터 복제에는 30PB 이상의 스토리지가 필요한 반면, 객체 스토리지에는 삭제 코딩을 사용하여 동일한 데이터를 안전하게 저장하고 보호하려면 15~20PB가 필요합니다. 삭제 코딩은 패리티 블록에 대한 데이터의 비율을 다르게 구성하여 다양한 스토리지 효율성을 제공할 수 있습니다. MinIO는 사용자 환경의 요구 사항을 결정하는 데 도움이 되는 유용한 삭제 코드 계산기를 유지 관리합니다.
MinIO는 가능한 최고의 성능을 제공하기 위해 어셈블리 코드로 작성된 객체별 인라인 삭제 코딩( 참조 용 공식 MinIO 문서)을 통해 데이터를 보호합니다. MinIO는 Intel AVX512 명령을 사용하여 빠른 삭제 코딩을 위해 여러 노드에서 호스트 CPU 리소스를 최대한 활용합니다. 표준 CPU, 빠른 NVMe 드라이브 및 100Gbps 네트워크는 거의 유선 속도로 삭제 코딩된 개체 쓰기를 지원합니다.
MinIO는 Reed-Solomon 코드를 사용하여 객체를 원하는 중복 수준으로 구성할 수 있는 데이터 및 패리티 블록으로 스트라이프합니다. 즉, 8개의 패리티 구성을 갖춘 16개 드라이브 설정에서 객체는 8개의 데이터 블록과 8개의 패리티 블록으로 스트라이프됩니다. 패리티든 데이터든 최대 7개((n/2)–1)개의 드라이브를 잃어버린 경우에도 나머지 드라이브에서 데이터를 안정적으로 재구성할 수 있습니다. MinIO의 구현은 여러 장치가 분실되거나 사용할 수 없는 경우에도 개체를 읽거나 새 개체를 쓸 수 있도록 보장합니다.
MinIO는 삭제 세트의 크기에 따라 개체를 데이터 및 패리티 블록으로 분할한 다음 각 드라이브에 개체당 하나의 블록만 포함하도록 세트의 드라이브 전체에 데이터 및 패리티 블록을 무작위로 균일하게 배포합니다. 드라이브에는 여러 개체에 대한 데이터 블록과 패리티 블록이 모두 포함될 수 있지만 시스템에 드라이브 수가 충분하다면 단일 개체에는 드라이브당 블록이 하나만 있을 수 있습니다. 버전이 지정된 개체 의 경우 MinIO는 하나의 드라이브에서 중복을 전혀 유지하면서 데이터 및 패리티 스토리지에 대해 동일한 드라이브를 선택합니다.
아래 표에는 구성 가능한 데이터 및 패리티 옵션과 함께 스토리지 사용 비율이 포함된 MinIO의 삭제 코딩 예가 나와 있습니다.
총 드라이브(n) | 데이터 드라이브(d) | 패리티 드라이브(p) | 스토리지 사용량 비율 |
---|---|---|---|
16 | 8 | 8 | 2.00 |
16 | 9 | 7 | 1.79 |
16 | 10 | 6 | 1.60 |
16 | 11 | 5 | 1.45 |
16 | 12 | 4 | 1.34 |
16 | 13 | 삼 | 1.23 |
16 | 14 | 2 | 1.14 |
MinIO의 백엔드 레이아웃은 실제로 매우 간단합니다. 들어오는 모든 객체에는 삭제 세트가 할당됩니다. 삭제 세트는 기본적으로 드라이브 세트이며, 클러스터는 전체 디스크 양에 따라 결정되는 하나 이상의 삭제 세트로 구성됩니다.
MinIO에서 사용되는 형식과 레이아웃을 이해하기 위해 간단한 예를 살펴보겠습니다.
형식은 패리티 드라이브에 대한 데이터의 비율에 관한 것입니다. 즉, 각각 단일 드라이브가 있는 4개의 노드가 있는지 또는 각각 100개의 드라이브가 있는 4개의 노드가 있는지 여부입니다(MinIO는 밀도가 높은 JBOD 구성으로 자주 배포됩니다).
삭제 세트 크기인 16(기본값)을 사용하도록 각각 100개의 드라이브가 있는 4개의 노드를 구성할 수 있습니다. 이는 논리적 레이아웃이며 삭제 코딩 계산 정의의 일부입니다. 16개 드라이브마다 8개의 데이터 드라이브와 8개의 패리티 드라이브로 구성된 하나의 삭제 세트가 있습니다. 이 경우 삭제 세트는 400개의 물리적 드라이브를 기반으로 하며 데이터 드라이브와 패리티 드라이브로 균등하게 나누어지며 최대 175개 드라이브의 손실을 허용할 수 있습니다.
개체와 함께 원자적으로 작성된 MinIO의 XL 메타데이터에는 해당 개체와 관련된 모든 정보가 포함되어 있습니다. MinIO에는 다른 메타데이터가 없습니다. 그 의미는 극적입니다. 모든 것이 객체와 함께 자체적으로 포함되어 있어 모든 것이 단순하고 자체적으로 설명됩니다. XL 메타데이터는 삭제 코드 알고리즘(예: 패리티가 2개인 데이터 2개, 블록 크기 및 체크섬)을 나타냅니다. 데이터 자체와 함께 체크섬을 작성하면 MinIO가 스트리밍 데이터를 지원하면서 메모리를 최적화할 수 있으므로 스트리밍 데이터를 메모리에 보관한 다음 이를 디스크에 쓰고 최종적으로 CRC-32 체크섬을 생성하는 시스템에 비해 확실한 이점을 제공합니다.
큰 물체, 즉. 10MB보다 큰 파일이 MinIO에 기록되면 S3 API는 이를 멀티파트 업로드로 나눕니다. 부품 크기는 클라이언트가 업로드할 때 결정됩니다. S3에서는 각 부분이 최소 5MB(마지막 부분 제외), 5GB 이하여야 합니다. 객체는 S3 사양을 기준으로 최대 10,000개의 부품을 포함할 수 있습니다. 320MB 크기의 객체를 상상해 보세요. 이 개체가 64개 부분으로 분할되면 MinIO는 해당 부분을 파트 1, 파트 2,...최대 파트 64로 드라이브에 기록합니다. 각 부분의 크기는 거의 동일합니다. 예를 들어 멀티파트로 업로드된 320MB 객체는 64개의 5MB 부분으로 분할됩니다.
업로드된 각 부분은 스트라이프 전체에 삭제 코딩되어 있습니다. Part.1은 업로드된 개체의 첫 번째 부분이며 모든 부분은 드라이브 전체에 가로로 스트라이프되어 있습니다. 각 부분은 데이터 블록, 패리티 블록 및 XL 메타데이터로 구성됩니다. MinIO는 쓰기를 순환하므로 시스템이 항상 동일한 드라이브에 데이터를 쓰고 동일한 드라이브에 패리티를 쓰지는 않습니다. 모든 개체는 독립적으로 회전되므로 클러스터의 모든 드라이브를 균일하고 효율적으로 사용할 수 있으며 동시에 데이터 보호도 강화됩니다.
객체를 검색하기 위해 MinIO는 해시 계산을 수행하여 객체가 저장된 위치를 결정하고 해시를 읽고 필요한 삭제 세트 및 드라이브에 액세스합니다. 객체를 읽으면 XL 메타데이터에 설명된 대로 데이터 및 패리티 블록이 있습니다. MinIO에 설정된 기본 삭제는 데이터 12개와 패리티 4개입니다. 즉, MinIO가 12개의 드라이브를 읽을 수 있는 한 객체를 제공할 수 있습니다.
삭제 코딩은 분산 시스템의 데이터 보호에 사용되는 다른 기술에 비해 몇 가지 주요 이점을 제공합니다.
삭제 코딩이 RAID보다 객체 스토리지에 더 적합한 데에는 몇 가지 이유가 있습니다. MinIO 삭제 코딩은 여러 드라이브와 노드에 장애가 발생할 경우 데이터 손실로부터 개체를 보호할 뿐만 아니라 개체 수준에서 보호하고 복구합니다. 한 번에 하나의 개체를 치료하는 능력은 볼륨 수준에서 치료하는 RAID에 비해 극적인 이점입니다. RAID에서는 몇 시간이 걸리던 손상된 개체를 MinIO에서는 몇 초 만에 복원할 수 있습니다. 드라이브에 문제가 발생하여 교체되면 MinIO는 새 드라이브를 인식하고 삭제 세트에 추가한 다음 모든 드라이브에서 개체를 확인합니다. 더 중요한 것은 읽기와 쓰기가 서로 영향을 주지 않아 대규모 성능이 가능하다는 것입니다. 페타바이트 규모의 스토리지에 걸쳐 수천억 개의 개체가 포함된 MinIO 배포가 있습니다.
MinIO의 삭제 코드 구현은 데이터 센터의 운영 효율성을 향상시킵니다. 복제와 달리 드라이브와 노드 전체에서 데이터를 재구축하거나 재동기화하는 데 오랜 시간이 걸리지 않습니다. 사소하게 들릴 수도 있지만 개체를 이동/복사하는 데는 비용이 매우 많이 들 수 있으며, 16TB 드라이브에 장애가 발생하여 데이터 센터 네트워크를 통해 다른 드라이브로 복사되면 스토리지 시스템과 네트워크에 막대한 세금이 부과됩니다.
이 블로그 게시물이 여러분의 호기심을 자극했다면 더 긴 Erasure Coding Primer를 사용할 수 있습니다. 지금 MinIO를 다운로드 하고 삭제 코딩으로 데이터를 보호해 보세요.
여기에도 게시되었습니다.