aistor01

Young-Kyoo Kim·2025년 8월 5일
0

AIStor Access 구조

  • Architecture
  • Configuration (w/Features on/off)
  • Entrypoint
  • Erasure Coding
  • Performance Test
  • Resiliency Test
  • Operations Test
  • Features Test

A1.구성 원칙
AIStor의 전체 구조는 복잡한 계층을 제거하고 직접적인 데이터 접근을 가능하게 하는 '오브젝트 네이티브(Object-Native)' 아키텍처에 기반을 둠 - 게이트웨이가 없는(Gateway-Free) 상태 비저장(Stateless) 아키텍처를 채택

  • 직접 연결 스토리지(Direct-Attached Storage, DAS): 각 서버 노드가 자체 스토리지를 직접 관리하며, 애플리케이션이 스토리지에 직접 접근. 이는 데이터 경로에서 불필요한 단계를 제거하여 지연 시간을 최소화하고 처리량을 극대화

  • 상태 비저장(Stateless) 서버: MinIO 서버 자체는 상태를 저장하지 않음. 모든 정보(데이터와 메타데이터)는 객체로 취급되어 스토리지에 저장되므로, 특정 서버에 대한 종속성 없이 어떤 서버를 통해서든 일관된 데이터 접근이 가능. 이로 인해 확장성과 장애 복구 능력이 크게 향상됨.

  • S3 API 호환성: 업계 표준으로 자리 잡은 Amazon S3 API와 완벽하게 호환. 이를 통해 PyTorch, TensorFlow 등 대부분의 AI/ML 프레임워크 및 데이터 분석 도구와 별도의 수정 없이 원활하게 통합할 수 있음. 최근에는 고성능, 저지연 워크로드를 위한 S3 Express API까지 지원하여 데이터 수집 및 모델 학습 속도를 더욱 가속화.

A2.분산 모드(Distributed Mode)의 작동 원리

  • 서버 풀(Server Pool)과 이레이저 셋(Erasure Set)
    --서버 풀 (Server Pool): 여러 개의 MinIO 서버 노드(예: 4~32개 노드)를 논리적으로 묶은 단위입니다. 이것이 바로 하나의 분산 MinIO 클러스터가 됩니다.
    --이레이저 셋 (Erasure Set): 업로드되는 하나의 객체를 분할하여 저장하는 물리적인 드라이브 그룹입니다. 예를 들어, 16개의 드라이브로 구성된 클러스터에서 하나의 객체는 이 16개 드라이브에 나뉘어 저장됩니다. 이레이저 셋의 크기는 클러스터를 처음 구성할 때 결정됩니다.

  • 분산 이레이저 코딩 (Distributed Erasure Coding): 데이터 내구성과 공간 효율성을 동시에 달성하는 핵심 기술입니다.

1)데이터 분할: 사용자가 하나의 객체(예: my-object.jpg)를 업로드하면, MinIO는 이 객체를 N개의 데이터 블록(Data Block)으로 나눕니다.

2)패리티 블록 생성: 이 데이터 블록들을 기반으로 M개의 패리티 블록(Parity Block)을 계산하여 생성합니다. 패리티 블록은 원본 데이터의 일부가 손실되었을 때 이를 복구하는 데 사용됩니다.

3)블록 분산 저장: 생성된 (N+M)개의 블록(데이터+패리티)은 이레이저 셋 내의 각 드라이브에 하나씩 분산하여 저장됩니다.

4)자가 치유 (Self-Healing): MinIO는 백그라운드에서 지속적으로 드라이브를 스캔하여 손상되거나 유실된 블록을 감지합니다. 만약 최대 M개의 드라이브에 장애가 발생하더라도, 남아있는 블록들을 조합하여 원본 데이터를 완벽하게 복구하고 새로운 드라이브에 다시 기록하여 클러스터의 안정성을 유지합니다.

  • 요청 처리 과정 (Request Lifecycle)
    1)요청 수신: 애플리케이션이 S3 API를 통해 객체 업로드/다운로드 요청을 보냅니다. 요청은 로드 밸런서를 통해 여러 MinIO 서버 중 하나로 전달됩니다.

2)해시 계산: 요청을 받은 MinIO 서버는 객체 이름(경로 포함)을 해시(Hash)하여 이 객체가 이레이저 셋 내의 어느 드라이브들에 저장되어야 하는지 즉시 계산합니다. 별도의 메타데이터 조회 과정이 없어 매우 빠릅니다.

3)데이터 분산/취합:
쓰기(Write): 서버는 객체를 데이터 및 패리티 블록으로 분할한 후, 계산된 위치의 드라이브들에 직접 병렬로 전송하여 기록합니다.

읽기(Read): 서버는 객체를 구성하는 데이터 블록들만 병렬로 읽어와서 하나로 합친 후 사용자에게 반환합니다. 만약 특정 블록을 읽을 수 없다면(디스크 장애 등), 다른 데이터 블록과 패리티 블록을 이용해 실시간으로 복구하여 반환하므로 서비스 중단이 없습니다.

  • 핵심 구조 (object store)
    S3 API 계층: 모든 외부 통신을 위한 인터페이스. 업계 표준으로 애플리케이션 호환성이 매우 높음.
    ID 및 접근 관리 (IAM): 사용자, 그룹, 정책을 관리하여 데이터 접근을 통제하는 보안 계층.
    MinIO 서버 (코어 로직): 상태 비저장 로직을 실행. 해싱, 이레이저 코딩, 블록 분산, 자가 치유 등 핵심 기능을 수행.
    분산 스토리지 백엔드: 실제 데이터와 메타데이터가 저장되는 물리적 공간. 여러 서버에 걸쳐 있는 드라이브들의 집합

helm 설치
aistor-volume-manager: 노드별 스토리지 관리 및 프로비저닝 자동화
aistor-objectstore-operator: AIStor 클러스터 전체를 관리하고 통제하는 '컨트롤러' 또는 '오퍼레이터'를 배포 -> ObjectStore와 같은 사용자 정의 리소스(CRD)의 생성을 감시하고, 그에 맞는 MinIO 서버 StatefulSet이나 Service 등 실제 리소스를 생성/관리
aistor-objectstore: 차트로 생성된 CR을 기반으로 오퍼레이터가 실제 데이터를 저장하고 처리하는 핵심 서버 Pod들을 만듭니다

  • POD
    Pod 이름 패턴: (ObjectStoreCR이름)(ObjectStore CR 이름)-(zone)-(poolindex)(pool index)-(pod index)
    1)S3 API 엔드포인트: 외부 및 내부의 S3 API 요청을 직접 수신하고 처리합니다.
    2)데이터 저장/관리: 할당된 디스크(Persistent Volume)에 객체 데이터를 저장합니다.
    3)이레이저 코딩: 데이터를 분산하고 패리티를 계산하여 다른 Pod들과 협력합니다.
    4)웹 콘솔 UI: 관리용 웹 UI 기능을 내장하고 있습니다. (기본 포트: 9001)
    특징: StatefulSet으로 관리되므로, 각 Pod는 재시작되어도 이름과 연결된 볼륨이 그대로 유지되어 데이터의 안정성을 보장합니다.
  • Service
    1)헤드리스 서비스 (Headless Service)
    이름 패턴: $(ObjectStore CR 이름)-hl 또는 $(ObjectStore CR 이름)-headless
    --Pod 직접 검색: 이 서비스는 단일 IP를 가지는 대신, 소속된 모든 Pod(my-store-default-0-0 등)들의 IP 주소 목록을 DNS에 직접 등록합니다.
    --Pod 간 통신: MinIO Pod들이 서로를 발견하고 데이터를 분산하거나 복구하는 등 내부 통신을 할 때 사용됩니다. StatefulSet의 Pod들이 고유한 네트워크 주소(pod-name.service-name)를 가질 수 있게 해줍니다.
    --외부 접근용으로는 사용되지 않습니다.
    2)클러스터 IP 서비스 (ClusterIP Service)
    이름 패턴: $(ObjectStore CR 이름) 또는 $(ObjectStore CR 이름)-minio-svc
    --단일 진입점(Single Entry Point): 클러스터 내부에서 유일한 고정 IP 주소를 가집니다. 이 서비스로 들어오는 모든 요청(S3 API, 콘솔 UI)을 현재 실행 중인 MinIO Pod들에게 로드 밸런싱(Round-Robin 방식)하여 분산시킵니다.
    --내부 애플리케이션 연결: 쿠버네티스 클러스터 내의 다른 애플리케이션이 MinIO에 접근할 때 이 서비스의 DNS 이름(예: my-store.mynamespace.svc.cluster.local)을 엔드포인트로 사용합니다.

클라이언트의 AIStor 서비스 접근 (S3 API Endpoint):
◦ 클라이언트는 AIStor의 S3 API 서비스 엔드포인트에 요청을 보냅니다.
◦ AIStor는 Kubernetes 환경에 배포될 수 있으며, 이 경우 S3 API 서비스는 NodePort를 통해 노출될 수 있습니다. 클라이언트는 Kubernetes 클러스터 내의 모든 워커 노드의 IP 주소 또는 호스트 이름과 할당된 NodePort를 사용하여 AIStor 서비스에 접근할 수 있습니다.

  1. 인증 및 권한 부여 (Authentication and Authorization):
    ◦ 클라이언트가 API 호출을 수행할 때 인증 정보가 요청에 포함됩니다.
    ◦ 설정된 Identity Manager가 클라이언트를 인증합니다. AIStor는 이 ID 관리 플러그인에 POST 요청을 보내 토큰을 확인하고 클라이언트의 인증 상태를 판단합니다. AIStor는 기본 ID 관리, Active Directory/LDAP, 또는 OpenID Connect를 통한 ID 관리를 지원합니다.
    ◦ 인증이 성공하면, Access Management Plugin (권한 부여 플러그인)이 API 호출의 컨텍스트 및 인증 데이터를 포함한 POST 호출을 받아 권한 부여 여부를 결정합니다. 성공적인 권한 부여 시 200 OK 응답을 반환하며, 거부될 경우 API 호출이 차단됩니다.
  2. 요청의 내부 처리 및 데이터 분산 (Erasure Coding & Object Storage):
    ◦ 인증 및 권한 부여가 완료되면, AIStor는 실제 데이터 저장 또는 인출 작업을 수행합니다. AIStor는 데이터의 중복성 및 가용성을 위해 삭제 코딩(Erasure Coding)을 핵심 메커니즘으로 사용합니다.
    ◦ 데이터 저장 (PUT):
    ▪ AIStor 서버는 저장될 객체를 데이터 샤드(Data Shard)패리티 샤드(Parity Shard)로 분할합니다. 패리티 샤드는 데이터 샤드 재구성(복구)에 사용되는 수학적 표현입니다.
    ▪ 생성된 데이터 및 패리티 샤드는 서버 풀 내의 삭제 세트(Erasure Sets)에 속한 여러 드라이브에 무작위로 분산됩니다. 이는 특정 드라이브가 특정 유형의 샤드만 가지지 않도록 보장합니다.
    ▪ 객체 쓰기 작업을 완료하려면 최소 K개의 삭제 세트 드라이브가 필요하며, 해당 삭제 세트에는 최소 K개의 사용 가능한 온라인 드라이브가 있어야 합니다.
    ▪ 객체는 저장 계층에서 보호하기 위해 서버 측 암호화(SSE)를 지원하며, 이는 AIStor Key Manager 또는 외부 KMS를 통해 SSE-KMS 또는 SSE-S3 암호화를 사용할 수 있습니다.
    ▪ 객체 작업에 대한 상세 정보는 감사 로그에 기록될 수 있습니다.
    ◦ 데이터 인출 (GET):
    ▪ 객체를 읽으려면 최소 K개의 샤드가 필요하며, 삭제 세트에는 읽기 작업을 지원하기 위해 최소 K개의 정상 드라이브가 있어야 합니다.
    ▪ AIStor는 손실되거나 손상된 데이터 샤드를 복구하기 위해 사용 가능한 패리티 샤드를 사용합니다.
    ▪ AIStor의 객체 스캐너(Object Scanner)는 객체 무결성을 확인하고 손상된 객체를 복구하는 작업을 수행합니다. HighwayHash 알고리즘을 사용하여 실시간으로 비트 로트 손상을 감지하고 복구합니다.
    ▪ 객체 버전 관리가 활성화된 버킷의 경우, 읽기 작업은 기본적으로 객체의 "최신" 버전을 검색하지만, 특정 버전 ID를 지정하여 이전 버전을 인출할 수도 있습니다. 버전 관리는 의도치 않은 덮어쓰기나 삭제로부터 보호합니다.
    객체 티어링(Object Tiering)을 통해 객체가 원격 스토리지 계층으로 이동된 경우에도, AIStor는 주 티어에 남아있는 메타데이터를 사용하여 보조 티어에서 객체를 투명하게 검색하여 클라이언트에 제공합니다.
  3. Kubernetes/OpenShift 내부 할당 메커니즘 (Implicit Load Balancing):
    ◦ 소스에는 클라이언트 요청이 서비스 엔드포인트에 도달한 후, 내부적으로 어떤 특정 Pod에 요청이 할당되는지에 대한 자세한 로드 밸런싱 메커니즘은 명시적으로 설명되어 있지 않습니다.
    ◦ 그러나, AIStor는 Kubernetes 또는 OpenShift와 같은 컨테이너 오케스트레이션 플랫폼에 배포되며, 이러한 플랫폼은 서비스 (Service) 추상화를 통해 여러 Pod에 걸쳐 트래픽을 분산하는 내장된 로드 밸런싱 기능을 제공합니다.
    ◦ 예를 들어, Kubernetes 환경에서 AIStor 서버는 여러 servers (Pod)로 구성된 pools로 배포될 수 있으며, minio 서비스는 S3 API 접근을 위해 NodePort를 통해 노출됩니다. OpenShift에서도 minio 서비스가 Routes를 통해 노출됩니다.
    ◦ 이는 플랫폼의 서비스 레이어가 들어오는 요청을 AIStor 클러스터 내의 가용하고 건강한 Pod 중 하나로 자동으로 라우팅하여 처리한다는 것을 의미합니다. 특정 Pod에 요청을 "고정"하는 메커니즘보다는 분산된 방식으로 요청을 처리합니다.
    요약하자면, S3 API 요청은 클라이언트에서 AIStor 서비스 엔드포인트로 전송되고, AIStor의 ID/액세스 관리 시스템을 통해 인증 및 권한 부여를 거친 후, 삭제 코딩을 통해 분산 저장된 데이터 샤드를 이용한 PUT/GET 작업으로 이어집니다. Kubernetes나 OpenShift와 같은 플랫폼의 서비스 추상화는 클라이언트 요청을 AIStor 클러스터의 적절한 백엔드 Pod으로 투명하게 라우팅합니다.

데이터 PUT (업로드) 과정
1)요청 수신: S3 클라이언트(애플리케이션)가 Ingress 주소(예: http://minio.mydomain.com)로 PUT Object 요청을 보냅니다.
2)라우팅: Ingress는 이 요청을 MinIO의 ClusterIP 서비스로 전달하고, 서비스는 여러 MinIO Pod 중 하나(예: my-store-default-0-1)에게 요청을 분배합니다.
3)이레이저 코딩 (Erasure Coding) - 핵심 단계:
3-1)객체 분할 (Sharding): 요청을 받은 Pod(my-store-default-0-1)는 업로드된 객체를 설정된 데이터 블록(K) 개수만큼 잘게 나눕니다.
3-2)패리티 계산 (Parity Calculation): 나뉜 데이터 블록들을 기반으로 수학적 계산을 통해 패리티 블록(M)을 생성합니다. 패리티 블록은 데이터 복구를 위한 정보입니다. (예: K=8, M=4 -> 8개 데이터 블록, 4개 패리티 블록 생성)
3-3)블록 분산 저장 (Distributed Storage): 생성된 총 (K+M)개의 블록들을 클러스터 내의 모든 Pod들에게 분산하여 저장하도록 지시합니다. 각 Pod는 자신의 디스크에 1개의 블록을 저장합니다. 이 과정은 병렬로 동시에 일어납니다.
4)응답: 모든 블록이 성공적으로 저장되면, 최초 요청을 받았던 Pod가 S3 클라이언트에게 200 OK 성공 응답을 보냅니다

데이터 GET (다운로드) 과정
1)요청 수신 및 라우팅: PUT 과정의 1, 2번과 동일하게 요청이 특정 MinIO Pod(예: my-store-default-0-3)에게 전달됩니다.
2)데이터 블록 취합:
2-1)요청을 받은 Pod는 객체를 구성하는 데이터 블록(K개)을 가지고 있는 다른 Pod들에게 해당 블록을 보내달라고 요청합니다.
2-2)각 Pod는 자신이 가진 데이터 블록을 요청한 Pod에게 병렬로 전송합니다.
3)객체 재구성 및 전송:
3-1)요청을 받은 Pod(my-store-default-0-3)는 수신한 K개의 데이터 블록들을 순서에 맞게 합쳐 원본 객체를 재구성합니다.
3-2)재구성된 완전한 객체를 S3 클라이언트에게 스트리밍 방식으로 전송합니다.
4)장애 발생 시 자동 복구 (Self-Healing):
4-1)만약 GET 요청 시 특정 데이터 블록을 가진 Pod(또는 디스크)에 장애가 발생해 응답이 없다면, 시스템은 즉시 패리티 블록을 가진 다른 Pod에게 요청을 보냅니다.
4-2)남아있는 데이터 블록과 패리티 블록을 조합하여 실시간으로 유실된 데이터 블록을 계산(복구)하고 원본 객체를 재구성하여 사용자에게 전송합니다. 이 과정은 사용자에게 투명하게 이루어지므로, 사용자는 장애를 인지하지 못하고 정상적으로 데이터를 다운로드 받게 됩니다.

감사 로그(Audit Logs):
◦ 객체 작업이 수행된 서버 풀, 삭제 세트, 참여 드라이브에 대한 세부 정보가 감사 로그에 기록될 수 있습니다

AIStor 객체 스토어에서 PUT 요청 시 데이터가 어느 erasure set(삭제 세트)에 저장될지 결정하는 메커니즘은 다음과 같습니다.
AIStor는 새로운 쓰기 작업(PUT 요청)을 수행할 때 가장 여유 공간이 많은 서버 풀(Server Pool)에 가중치를 두어 저장 대상을 결정합니다. 각 서버 풀은 하나 이상의 삭제 세트(Erasure Sets)로 구성됩니다.
구체적인 결정 과정은 다음과 같습니다:
1. 풀 선택 (Pool Selection):
◦ AIStor는 새로운 쓰기 작업을 자동으로 새로운 서버 풀들 간에 재분배하지 않습니다.
◦ 대신, AIStor는 가장 여유 공간이 많은 풀에 가중치를 부여하여 새로운 쓰기 작업을 해당 풀로 수행합니다.
◦ 저장 작업이 특정 풀에서 이뤄질 확률은 해당 풀의 여유 공간을 전체 사용 가능한 풀의 여유 공간으로 나눈 값에 따라 결정됩니다. 공식은 다음과 같습니다: FreeSpaceOnPoolA / FreeSpaceOnAllPools.
◦ 예를 들어, 세 개의 풀이 있고 총 10TiB의 여유 공간이 각각 Pool A (3 TiB), Pool B (2 TiB), Pool C (5 TiB)로 분산되어 있다면, 쓰기 작업이 각 풀로 갈 확률은 Pool A: 30%, Pool B: 20%, Pool C: 50%가 됩니다.
◦ 또한, 쓰기 작업(패리티 포함)으로 인해 드라이브 사용량이 99%를 초과하거나, 알려진 여유 아이노드(inode) 수가 1000개 미만으로 떨어지는 풀에는 AIStor가 쓰기 작업을 수행하지 않습니다. decommissioning 중인 풀에도 쓰기 작업을 수행하지 않습니다.
2. 데이터 분할 및 삭제 세트 분산 (Data Partitioning & Erasure Set Distribution):
◦ 다중 풀 클러스터에서는 요청을 수신하는 AIStor 서버 노드가 특정 요청을 어떤 풀로 라우팅할지 결정합니다.
◦ 일단 대상 풀이 식별되면, AIStor 서버는 객체를 데이터 샤드(Data Shard)와 패리티 샤드(Parity Shard)로 분할하고, 이 샤드들을 해당 풀 내의 적절한 삭제 세트들(erasure sets)에 걸쳐 분산합니다. 샤드들은 삭제 세트에 속한 여러 드라이브에 무작위로 분산됩니다.
요약하자면, AIStor는 먼저 가장 여유 공간이 많은 서버 풀을 선택하는 가중치 기반의 로직을 사용하여 PUT 요청의 대상 풀을 결정하고, 그 다음 선택된 풀 내의 삭제 세트들로 데이터를 분할하여 분산 저장합니다

Erasure Sets
◦ AIStor는 각 서버 풀의 드라이브를 동일한 크기의 하나 이상의 Erasure Sets로 그룹화합니다.
◦ 서버 풀 초기화 시 AIStor가 Erasure Sets의 최적 개수와 크기를 결정하며, 이 설정은 초기 설정 후에는 변경할 수 없습니다.
◦ Erasure Sets 스트라이프 크기는 배포에 가능한 최대 패리티를 결정합니다. 예를 들어, 16개 드라이브로 구성된 삭제 세트는 EC:0부터 EC:8까지의 패리티를 지원할 수 있습니다.
◦ AIStor는 Reed-Solomon Erasure Coding을 사용하여 객체를 Erasure Sets 전체에 분산하기 위해 분할합니다

샤드 분산 방식
◦ AIStor는 생성된 데이터 및 패리티 샤드를 Erasure Sets 내의 드라이브 전체에 무작위로 분산합니다. 이 분산 방식은 특정 드라이브가 패리티 샤드만 또는 데이터 샤드만 포함하지 않도록 보장합니다.
◦ 중요: 특정 패리티 설정으로 기록된 객체는 나중에 패리티 값이 변경되어도 자동으로 업데이트되지 않습니다

Quorum 요구사항
◦ 읽기 쿼럼: 객체를 읽으려면 최소 K개의 샤드가 필요하며(K값이 바로 읽기 쿼럼임), Erasure Sets에는 읽기 작업을 지원하기 위해 최소 K개의 정상 드라이브가 있어야 합니다.
▪ 예를 들어, EC:4 패리티로 기록된 객체의 읽기 쿼럼이 K=12일 때, 노드 하나가 오프라인이 되어도 12개의 드라이브가 정상이라면 객체는 읽기 쿼럼을 유지하여 복원 및 읽기가 가능합니다.
▪ 읽기 쿼럼을 상실한 객체는 재구성할 수 없지만, 복제 재동기화(Replication Resynchronization)와 같은 다른 방법을 통해 복구될 수 있습니다 - 재동기화는 버킷 단위로 이루어지며, 소스(원본)와 타겟(대상) 배포가 모두 온라인 상태여야 하고 읽기 및 쓰기 작업을 수행할 수 있어야 합니다
◦ 쓰기 쿼럼: 객체를 쓰려면 최소 K개의 Erasure Sets 드라이브가 필요하며, 쓰기 작업을 지원하기 위해 Erasure Sets에는 최소 K개의 사용 가능한 온라인 드라이브가 있어야 합니다.
▪ 패리티 EC:M이 삭제 세트 크기의 정확히 1/2인 경우, 쓰기 쿼럼은 K+1이 됩니다. 이는 네트워크 문제로 인해 드라이브 절반이 격리되는 '스플릿 브레인' 시나리오를 방지하기 위함입니다

Healing(복구) 과정
◦ 읽기 쿼럼을 유지하는 객체의 경우, AIStor는 손상된 샤드를 복구하기 위해 모든 데이터 또는 패리티 샤드를 사용할 수 있습니다.
◦ AIStor는 GET 또는 HEAD 요청 시 객체 데이터 샤드의 일관성을 자동으로 확인합니다. 손실되거나 손상된 데이터 샤드가 발견되면, AIStor는 사용 가능한 패리티 샤드를 사용하여 객체를 복구한 후 요청한 클라이언트에 제공합니다.
◦ 복구 가능하려면 손실되거나 손상된 데이터 샤드마다 온전한 패리티 샤드가 있어야 합니다.
◦ AIStor의 객체 스캐너는 객체 무결성을 확인하고 손상되거나 손상된 객체를 복구하는 작업을 수행합니다. 기본적으로 스캐너는 비트 로트(bit rot) 손상을 확인하지 않는데, 이는 비용이 많이 드는 작업이기 때문입니다. AIStor는 HighwayHash 알고리즘을 사용하여 비트 로트 손상을 실시간으로 감지하고 복구합니다

패리티와 스토리지 효율성
◦ 배포를 위한 패리티 설정은 데이터 가용성과 총 사용 가능한 스토리지 공간 간의 균형입니다.
◦ 패리티 값을 높이면 드라이브 또는 노드 장애에 대한 복원력이 증가하지만, 사용 가능한 스토리지 공간은 감소합니다.
◦ 반대로 낮은 패리티 값은 최대 스토리지 공간을 제공하지만, 드라이브/노드 장애에 대한 허용 오차는 줄어듭니다.
◦ AIStor Erasure Code Calculator를 사용하여 계획된 클러스터 배포에서 패리티가 스토리지 효율성에 미치는 영향을 평가할 수 있습니다

객체 버전 관리(Object Versioning):
◦ 버전 관리가 활성화된 버킷에서는 쓰기 작업이 기존 객체를 덮어쓰는 대신 해당 객체의 새 버전을 생성합니다.
◦ 기본적으로 읽기 작업은 객체의 "최신(latest)" 버전을 검색합니다.
◦ 클라이언트는 특정 버전 ID(version ID)를 지정하여 특정 객체 버전을 명시적으로 읽거나, 나열하거나, 제거할 수 있습니다.
◦ 버전 관리는 의도하지 않은 덮어쓰기 및 삭제로부터 보호하며, 쓰기 작업을 "실행 취소"하는 기능을 제공합니다

객체 티어링(Object Tiering) 및 투명한 객체 검색:
◦ AIStor는 객체 수명 주기 관리(Object Lifecycle Management) 규칙을 사용하여 객체를 원격 스토리지 계층으로 자동으로 이동(티어링)할 수 있습니다.
◦ 객체가 다른 티어로 이동하더라도, 객체의 메타데이터는 주(primary) 티어에 남아 있고 객체 데이터는 보조(secondary) 티어로 이동합니다.
◦ AIStor가 티어링된 객체를 제공해야 할 때, AIStor는 보조 티어에서 객체를 투명하게 검색하여 클라이언트에 제공합니다. 애플리케이션 측 추가 로직 없이 원격에서 온디맨드 방식으로 데이터를 검색하여 제공합니다

Volume Manager

  • Controller
    -- 3 copy deployment
    -- leader
    -- summary: 컨트롤러는 볼륨 생성, 삭제 및 확장과 같은 CSI 요청을 처리합니다.
    ◦ 노드 서버는 볼륨의 스테이지(Stage), 언스테이지(Unstage), 퍼블리시(Publish), 언퍼블리시(Unpublish) 및 확장(Expand) RPC 요청을 처리합니다.
    ◦ 이는 Persistent Volume Claim(PVC)에 따라 로컬 볼륨을 프로비저닝합니다
    -- 컨트롤러 (Controller): CSI 요청을 수락하여 볼륨 생성, 삭제 및 확장을 처리
    ▪ 볼륨 생성 (Create volume): 적합한 VolumeManagerDrive CRD에서 요청된 저장 공간을 예약한 후 새로운 VolumeManagerVolume CRD를 생성
    ▪ 볼륨 삭제 (Delete volume): 바인딩되지 않은 VolumeManagerVolume CRD에 대해 이전에 예약된 공간을 해제한 후 삭제
    ▪ 볼륨 확장 (Expand volume): VolumeManagerDrive CRD에서 요청된 저장 공간을 예약한 후 기존 VolumeManagerVolume CRD를 확장
    -- CSI 프로비저너 (CSI provisioner): Persistent Volume Claim(PVC)에서 CSI 컨트롤러로 볼륨 생성 및 삭제 요청을 브리지
    -- CSI 리사이저 (CSI resizer): Persistent Volume Claim에서 CSI 컨트롤러로 볼륨 확장 요청을 브리지
  • Node Server
    모든 또는 선택된 Kubernetes 노드에서 node-server라는 이름의 DaemonSet Pod로 실행
    ◦ 각 노드 서버 Pod는 노드에서 독립적으로 실행됩니다.
    ◦ 각 Pod에는 다음 컨테이너가 포함됩니다:
    ▪ 노드 드라이버 레지스트라 (Node driver registrar): CSI RPC 호출을 받기 위해 노드 서버를 kubelet에 등록
    ▪ 노드 서버 (Node server): Stage, unstage, publish, unpublish 및 expand volume RPC 요청을 처리
    ▪ 노드 컨트롤러 (Node controller): VolumeManagerDrive, VolumeManagerVolume, VolumeManagerNode, 및 VolumeManagerInitRequest로부터 CRD 이벤트를 처리
    ▪ 활성 프로브 (Liveness probe): Kubernetes가 노드 서버의 활성 상태를 확인하기 위해 /healthz 엔드포인트를 노출
  • 작동 과정
    -- 사전 조건: Volume Manager CLI 플러그인(kubectl directpv 명령어 - Volume Manager 드라이브와 볼륨을 관리하는 모든 기능을 수행. 여기에는 드라이브 및 볼륨을 추가, 관리, 스케줄링 및 제거하는 작업이 포함)이 설치되어 작동 중이어야 합니다.
    ◦ Kubernetes에 Volume Manager CSI 드라이버(위 controller + node server - kubectl get all -n directpv)가 설치되어 작동 중이어야 합니다.
    1단계: 디스크 탐지 (discover 명령 실행) - kubectl directpv discover
    Volume Manager 노드에서 적합한 드라이브를 탐색하고, 발견된 드라이브 정보를 YAML 파일(기본적으로 drives.yaml)로 저장
    -> 드라이브가 탐지되려면 특정 조건을 만족해야 합니다. 예를 들어, 최소 512MB의 공간이 있어야 하고, 숨겨져 있거나, 읽기 전용이거나, 파티션이 되어 있거나, 다른 장치에 의해 사용 중이거나, 마운트되어 있거나, 스왑 파티션으로 사용 중이거나, CD-ROM이어서는 안 됩니다. discover --all 명령의 마지막 열을 확인하여 특정 드라이브가 제외된 이유를 파악할 수 있습니다
    2단계: 디스크 초기화 (init 명령 실행) - kubectl directpv init drives.yaml 명령을 실행하여 선택된 드라이브를 초기화
    초기화 프로세스는 선택된 드라이브를 XFS 파일 시스템으로 포맷하고, /var/lib/directpv/mnt/ 경로에 마운트합니다.
    ◦ 성공적으로 마운트되면 Volume Manager는 이 드라이브에 볼륨을 스케줄링할 수 있습니다
    ◦ 초기화된 드라이브를 확인하려면 kubectl directpv list drives 명령을 사용할 수 있습니다. 이 명령은 노드, 드라이브 이름, 크기, 사용 가능한 공간, 볼륨 수, 상태 등의 정보를 표시합

Features

  • MinIO 서버 (Server): 분산 클러스터를 구성하는 핵심 실행 파일입니다. 단독 모드(Standalone) 또는 여러 서버가 하나의 네임스페이스를 공유하는 분산 모드(Distributed)로 실행될 수 있으며, AI 워크로드를 위해서는 분산 모드가 필수적입니다.
  • 버킷 (Bucket) 및 객체 (Object): 데이터가 저장되는 기본 단위입니다. 버킷은 객체들을 담는 컨테이너 역할을 하며, 객체는 실제 데이터와 메타데이터로 구성됩니다.
  • 분산 이레이저 코딩 (Distributed Erasure Coding): 데이터를 여러 조각(데이터 및 패리티 블록)으로 나누어 여러 드라이브와 노드에 분산 저장합니다. 이를 통해 하드웨어 장애가 발생하더라도 데이터 손실 없이 자동으로 복구할 수 있어 높은 수준의 데이터 내구성과 가용성을 보장합니다.
  • 비트롯 감지 (Bitrot Detection): 저장된 데이터의 손상(silent data corruption)을 자동으로 감지하고 자가 치유하여 데이터 무결성을 보장하는 기능입니다.
  • ID 및 접근 관리 (IAM): AWS IAM과 호환되는 강력한 사용자 및 접근 관리 기능을 제공합니다. Active Directory/LDAP, Okta, Keycloak 등 외부 ID 공급자와의 연동도 지원하여 엔터프라이즈 환경에 적합한 보안을 제공합니다.
  • AI Hub: Hugging Face와 같은 외부 모델 허브의 프록시 서버 역할을 합니다. 개발자가 필요한 AI 모델을 요청하면, AI Hub가 이를 외부에서 다운로드하여 AIStor 버킷에 캐싱합니다. 이후의 요청은 캐시된 데이터를 사용하므로 모델 로딩 속도가 빨라지고 외부 의존성이 줄어듭니다.
  • 카탈로그 (Catalog): GraphQL API를 통해 저장된 객체의 메타데이터를 효율적으로 쿼리할 수 있는 기능입니다. 대규모 데이터셋에서 특정 조건을 만족하는 데이터를 신속하게 찾아내는 데 유용합니다.
  • 클라우드 네이티브 통합: 컨테이너화 및 쿠버네티스(Kubernetes) 오케스트레이션을 기반으로 설계되었습니다. 이를 통해 프라이빗 및 퍼블릭 클라우드, 엣지 등 다양한 환경에 유연하게 배포하고 자동화된 운영 관리가 가능합니다.

PV 생성과정 : PVC 생성 시 PV 할당 과정
Volume Manager는 Persistent Volume Claim (PVC)이 생성될 때 다음 과정을 거쳐 Persistent Volume (PV)을 할당합니다:
• 볼륨 바인딩 모드 WaitForFirstConsumer:
◦ Volume Manager의 기본 스토리지 클래스인 directpv-min-io는 WaitForFirstConsumer 볼륨 바인딩 모드를 사용합니다.
◦ 이 모드는 PVC가 생성되자마자 PV를 즉시 프로비저닝하는 대신, 해당 PVC를 사용하는 Pod가 생성될 때까지 볼륨 바인딩 및 프로비저닝을 지연시킵니다.
◦ 이는 Pod의 스케줄링 제약 조건(예: 리소스 요구사항, 노드 셀렉터, Pod 선호도 및 비선호도, 테인트 및 톨러레이션)과 일치하는 PV를 Volume Manager가 선택하거나 프로비저닝하도록 합니다.
◦ 결과적으로, 볼륨을 사용하는 Pod는 해당 볼륨이 스케줄링된 노드에 스케줄링되어 고성능 데이터 접근을 보장합니다.
• 드라이브 선택 알고리즘:
◦ Volume Manager CSI 컨트롤러는 CreateVolume 요청에 대해 적합한 드라이브를 다음 순서로 선택합니다:
1. 파일 시스템 타입 유효성 검사: 요청된 파일 시스템 타입이 XFS인지 확인합니다. Volume Manager는 XFS 파일 시스템만 지원합니다.
2. 액세스 계층(Access-tier) 유효성 검사: 요청에 액세스 계층이 지정된 경우 이를 확인합니다.
3. 기존 볼륨 확인: Volume ManagerDrive CRD 객체에 요청된 볼륨이 이미 존재하는지 확인합니다. 존재한다면, 해당 볼륨을 포함하는 첫 번째 드라이브를 스케줄링합니다.
4. 새 드라이브 검토: 요청된 볼륨을 포함하는 드라이브가 없다면, Volume Manager는 각 드라이브를 다음 기준으로 검토합니다:
• 요청된 용량.
• 요청된 액세스 계층 (있는 경우).
• 토폴로지 제약 조건 (있는 경우).
5. 최적 드라이브 선택: 이 과정에서 여러 드라이브가 일치하는 경우, Volume Manager는 가장 많은 여유 공간을 가진 드라이브를 선택합니다. 만약 여러 드라이브가 동일한 최대 여유 공간을 가지고 있다면, 그 중 하나를 무작위로 스케줄링합니다.
6. 드라이브 정보 업데이트: 선택된 드라이브는 요청된 볼륨 정보로 업데이트됩니다.
◦ 일치하는 드라이브가 없으면 Volume Manager는 오류를 반환하며, Kubernetes는 요청을 재시도합니다.
◦ 두 개 이상의 병렬 요청이 동일한 드라이브를 스케줄링하려고 시도하는 경우, 한 요청만 성공하고 나머지 요청은 실패하며 재시도됩니다.
• 사용자 정의 드라이브 라벨 활용:
◦ Volume Manager는 node selectors, pod affinity and anti-affinity, taints and tolerations 외에, 사용자 정의 드라이브 라벨을 사용하여 특정 드라이브에 볼륨을 스케줄링할 수 있도록 합니다.
◦ kubectl directpv label drives 명령으로 드라이브에 라벨을 설정하고, 이 라벨을 포함하는 사용자 정의 스토리지 클래스를 생성하여 볼륨 프로비저닝 시 특정 유형의 드라이브를 선택하도록 할 수 있습니다.
이 과정을 통해 Volume Manager는 요청된 Persistent Volume Claim에 따라 적절한 Persistent Volume을 동적으로 할당하게 됩니다.

0개의 댓글