스토리지
Arkvory는 게시된 모든 파일을 서버의 로컬 디스크에 있는 스토리지 디렉터리에 한 번만, 변경 없이 보관합니다. 이 페이지에서는 무엇이 디스크 공간을 차지하는지, 할당량과 보존 정책으로 이를 어떻게 제한하는지, 삭제된 파일이 어떻게 디스크에서 사라지는지, 디스크가 가득 찼을 때 무엇을 해야 하는지 설명합니다.
콘텐츠가 저장되는 위치
스토리지 디렉터리는 ARKVORY_DATA_DIR로 설정합니다. 설치 프로그램은 다음 위치를 사용합니다:
| 설치 | 스토리지 |
|---|---|
| Windows | C:\ProgramData\ProAnima\Arkvory의 data\ |
| Linux | /opt/proanima-arkvory의 data/ |
| Docker Compose | Docker 볼륨 proanima-arkvory_storage |
그 안에서 blobs/는 완료된 파일을 보관하고, staging/과 parts/는 진행 중인 업로드를 보관하며, storage-id 파일이 디렉터리와 데이터베이스를 연결합니다. 모든 이름, 레이블, 버전, 권한을 담은 카탈로그는 PostgreSQL에 있습니다. 파일과 데이터베이스는 함께 있어야 합니다.
- 하드 링크를 지원하는 로컬 파일 시스템을 사용하세요. 스토리지에는 네트워크 공유를 사용하지 마세요.
- 디렉터리의 파일을 직접 추가, 변경, 삭제하지 마세요. 아래에서 설명하듯이 Arkvory가 파일을 스스로 제거합니다.
- 게시된 파일은 절대 변경되지 않습니다. 새 콘텐츠는 새 ID를 가진 새 파일입니다.
디스크 계획
다음 항목이 스토리지 볼륨의 디스크 공간을 사용합니다:
| 항목 | 설명 |
|---|---|
| 게시된 파일 | 보관하는 모든 버전 |
| 진행 중인 업로드 | 업로드가 끝날 때까지의 파트와 스테이징 파일 |
| 완료된 업로드의 파트 파일 | 임시 파트는 물리적 정리 패스가 제거할 때까지 완료된 파일 옆에 남습니다. 물리적 정리 참조 |
| 삭제된 파일 | 유예 기간이 끝나고 정리 패스가 제거할 때까지 디스크에 남습니다 |
| 미러 복사본 | 미러가 파일을 복사하는 동안 mirror-staging의 파트. 미러 참조 |
스토리지 외에도 PostgreSQL 데이터베이스, 로그, 백업 보관소를 가능하면 각각 별도의 볼륨에 계획하세요. 백업을 참조하세요.
Arkvory는 스토리지 볼륨에 여유 공간의 예비 영역을 유지합니다. 기본값은 1 GiB(ARKVORY_STORAGE_RESERVE_BYTES)입니다. 예비 영역을 사용하게 될 업로드는 HTTP 507과 사유 storage_full로 거부됩니다. 다운로드는 계속 동작합니다. 새 데이터를 위한 공간이 없는 동안 GET /health/ready는 writable: false를 표시합니다.
두 가지 제한은 디스크와 독립적으로 동작합니다:
ARKVORY_CAPACITY_BYTES는 설치의 모든 예약된 콘텐츠를 제한합니다. 기본값은 10 TiB입니다. 이는 디스크 검사가 아니라 논리적 한도입니다. 이 값에 도달하면 업로드는 HTTP 507과 사유catalog_limit으로 실패합니다.ARKVORY_MAX_OBJECT_BYTES는 파일 하나의 크기를 제한합니다.
환경 변수를 참조하세요. Arkvory에는 스토리지나 데이터베이스의 여유 공간에 대한 메트릭이 없습니다. 운영 체제 도구나 노드 익스포터로 볼륨을 관찰하세요.
스토리지 관리 권한
스토리지 설정은 일반 읽기 및 쓰기 권한에 포함되지 않습니다. 서비스 키에는 리포지토리에 대한 명시적 작업이 필요합니다:
| 작업 | 허용 범위 |
|---|---|
storage.read | 정책, 사용량, 정리 설정 조회 |
storage.manage | 정책, 할당량, 정리 설정 변경 및 정리 배치 요청 |
artifact.delete | 삭제 미리 보기, 아티팩트 삭제, 자동 보존 정책 켜기 |
diagnostics.read | 스토리지 이벤트 읽기 |
비밀번호가 있는 계정과 복구 키에는 이러한 권한이 기본으로 없습니다. 콘솔에서 스토리지를 관리하려면:
- 네 가지 작업을 포함하는 리포지토리 정책을 가진 서비스 계정을 만듭니다. 계정 및 액세스를 참조하세요.
- 그 계정을 위한 키를 발급하고 활성화합니다.
- 콘솔에서 서비스 키 또는 자동화 키로 연결을 열고 키를 붙여 넣은 다음 연결를 선택합니다.
- 리포지토리를 열고 리포지토리 카드에서 스토리지 및 정리를 선택합니다.
카탈로그 위에 스토리지 및 자동 정리 패널이 나타납니다. 권한이 없으면 패널은 숨겨진 상태로 유지됩니다.
활성화된 보존 정책은 이를 활성화한 키에 연결됩니다. 자동 실행마다 이 키가 아직 활성 상태이고 만료되지 않았으며 여전히 storage.manage와 artifact.delete를 가지고 있는지 다시 확인합니다. 키를 폐기하거나 권한을 축소하면 삭제가 중단되고 retention.failed 이벤트가 나타납니다. 키를 교체한 후에는 새 키로 정책을 다시 저장하세요.
할당량과 경고 임계값
리포지토리에는 할당량을 설정할 수 있습니다. 할당량이 없으면 전역 한도만 적용됩니다.
| 설정 | 콘솔 필드 | 의미 | 기본값 |
|---|---|---|---|
| 할당량 | 할당량, GiB(비워 두면 리포지토리 제한 없음) | 리포지토리가 사용할 수 있는 최대 공간입니다. API는 1에서 9 007 199 254 740 991까지의 정확한 바이트를 받으며, 제한 없음은 null입니다 | 제한 없음 |
| 경고 임계값 | 경고 임계값(%) | 경고를 발생시키는 할당량의 비율. 1–98 | 80 |
| 심각 임계값 | 위험 임계값(%) | 오류를 발생시키는 비율. 2–99이며 경고 임계값보다 높아야 합니다 | 95 |
할당량에 포함되는 사용량은 아직 디스크에서 제거되지 않은 리포지토리의 모든 파일 크기입니다: 게시된 파일, 완료되지 않은 업로드, 정리를 기다리는 삭제된 파일. 따라서 삭제된 파일도 정리 패스가 제거할 때까지 할당량을 사용합니다.
- 검사. 서버는 업로드가 시작될 때 할당량을 확인합니다. 할당량을 초과하게 될 새 업로드는 HTTP 507과 사유
storage_quota로 실패합니다. 동일한 멱등성 키로 재시도해도 공간이 두 번 예약되지 않습니다. - 낮추기. 현재 사용량보다 낮은 할당량을 설정할 수 있습니다. 실행 중인 업로드는 끝까지 진행할 수 있습니다. 한도를 초과하는 새 업로드는 거부됩니다.
- 자동 확보 없음. 할당량은 삭제를 일으키지 않습니다. 보존 정책은 할당량을 맞추기 위해 추가 빌드를 제거하지 않습니다.
- 상태. 상태는
unlimited,normal,warning,critical,exceeded중 하나입니다. 상태 변경은 스토리지 이벤트로 한 번 기록됩니다. - 모니터링. 서버는 자동 삭제가 꺼져 있어도 매분 최대 20개 리포지토리의 상태를 다시 확인합니다.
이 숫자는 논리적 예약이며 실제 여유 디스크 공간이 아닙니다. 디스크에는 스테이징 파일과 다른 리포지토리도 있으므로 디스크가 가득 찬 상태에서도 리포지토리가 할당량 아래일 수 있습니다.
보존 정책
보존 정책은 오래된 등록된 UPack 빌드를 자동으로 삭제하고 최근 N개를 유지합니다. 다른 파일은 삭제하지 않습니다: 경로 기반 일반 파일, 컨테이너 이미지, Git LFS 객체, npm 패키지는 대상이 아닙니다. 정책이 없으면 아무것도 자동으로 삭제되지 않습니다.
설정
| 설정 | 콘솔 필드 | 의미 | 기본값 |
|---|---|---|---|
| 활성화 | 자동 정리 사용 | 자동 삭제를 켭니다 | 꺼짐 |
| 그룹화 | 최근 N개 계산 기준 | 계산 단위: 패키지 및 채널, 패키지 또는 전체 리포지토리 | 패키지 및 채널 |
| 최근 N개 | 최근 N개 빌드(기본값) | 카운터마다 유지할 빌드 수, 1–100 000 | 10 |
| 채널 | 채널별 재정의: 레이블=N, 한 줄에 하나씩 | 레이블에 대한 자체 N. label=N 형식으로 줄당 하나, 최대 32개. 그룹화가 패키지 및 채널일 때만 사용 | test=10, staging=10, release=10 |
| 최소 기간 | 삭제 전 최소 보관 기간(시간) | 이보다 최신인 빌드는 유지합니다. 시간 단위, 0–87 600 | 24 |
| 보호 레이블 | 보호된 레이블(쉼표로 구분) | 이 레이블 중 하나를 가진 빌드는 절대 삭제되지 않습니다. 최대 32개, 쉼표로 구분 | bse, release |
| 간격 | 정리 간격(분) | 실행 사이의 분, 1–10 080 | 60 |
레이블은 1~64자의 문자, 숫자 또는 _ . : - 문자입니다.
빌드 선택 방식
- 서버는 각 카운터의 빌드를 게시 시간 기준으로 최신순으로 정렬합니다. 이 순서는 버전의 SemVer 순서가 아닙니다.
- 카운터는 그룹화에 따라 달라집니다. 패키지 및 채널 그룹화에서는 빌드가 가지고 있는 구성된 각 채널 레이블마다 패키지(
group/name)별로 따로 계산됩니다. 구성된 레이블이 없는 빌드는 기본 N을 사용하는 패키지의 공유 카운터 하나에 들어갑니다. 패키지 그룹화에서는 각 패키지마다 카운터가 하나씩 있습니다. 전체 리포지토리 그룹화에서는 모든 빌드가 카운터 하나를 공유합니다. 패키지 이름은 대소문자를 구분하지 않지만 레이블은 구분합니다. - 빌드가 속한 어느 카운터에서든 최근 N개 안에 들면 유지됩니다.
- 최소 기간보다 최신인 빌드는 유지됩니다.
- 보호 레이블을 가진 빌드는 유지됩니다. 레이블은 현재 주석에서 오며, 주석이 없으면 업로드에서 옵니다. 보호된 빌드도 순위에 포함되므로 유지되는 수가 N보다 많을 수 있습니다.
다음 중 하나라도 빌드를 필요로 하는 동안에는 빌드가 절대 삭제되지 않습니다:
- 외부 서비스가 빌드에 대한 참조를 가지고 있습니다.
- 현재 또는 기록의 파일 경로가 빌드를 사용합니다.
- 다른 빌드가 현재 또는 기록에서 빌드를 첨부 파일로 나열합니다.
- 스테이지로 승격되어 있습니다. 먼저 스테이지를 제거하세요.
- 컨테이너 이미지, Git LFS 또는 npm 항목이 빌드를 사용합니다.
빌드 삭제는 논리적입니다: 목록에서 사라지고 새 다운로드는 404로 실패합니다. 바이트는 나중에 물리적 정리에서 디스크에서 사라집니다. 패키지 버전은 계속 예약된 상태로 남으므로 같은 버전을 다른 콘텐츠로 다시 게시할 수 없습니다.
정책을 안전하게 활성화
먼저 미리 보고 나서 활성화하세요. 미리 보기는 저장된 정책이 삭제할 대상을 보여 주며 아무것도 삭제하지 않습니다.
- 네 가지 작업을 가진 키로 연결하고 리포지토리의 스토리지 패널을 엽니다.
- 필드를 설정하고 자동 정리 사용를 꺼진 상태로 둡니다. 정책 저장를 선택합니다.
- 저장된 정책 미리 보기를 선택합니다. 목록은 저장된 정책이 한 배치에서 삭제할 최대 100개의 빌드를 보여 줍니다. 후보가 더 남아 있으면 콘솔이 이를 알려 줍니다.
- 목록이 맞으면 자동 정리 사용와 확인 활성화된 정책을 저장하면 자동 삭제를 승인하게 된다는 점을 이해합니다.를 체크한 다음 다시 저장합니다. 이 작업에는
artifact.delete가 필요합니다.
참고:
- 미리 보기는 특정 시점을 보여 줍니다. 정책이 실행될 때 다시 순위를 매기고 의존성을 다시 확인합니다.
- 정책은 리비전과 함께 저장됩니다. 다른 사람이 변경했다면 다시 불러와서 저장하세요.
- 설정 및 사용량 새로 고침는 설정과 사용량을 다시 불러옵니다.
실행 방식
쓰기를 수행하는 API 프로세스(읽기 게이트웨이가 아님)가 60초마다 확인하고 만기가 된 최대 20개의 정책을 처리합니다. 하나의 배치는 최대 100개의 빌드를 삭제합니다. 후보가 남아 있으면 다음 배치가 1분 후에 시작됩니다. 그렇지 않으면 다음 실행은 간격 후에 옵니다. 일정은 데이터베이스에 저장되며 재시작 후에도 유지됩니다.
API 작업 runStoragePolicy로 배치 하나를 직접 실행할 수도 있습니다. 사용량, 미리 보기, 이벤트에는 같은 스토리지 API 참조에 작업이 있습니다.
물리적 정리
아티팩트를 사람이든 정책이든 삭제하면 카탈로그에서만 제거됩니다. 물리적 정리는 API, 워커, 읽기 게이트웨이를 중단하지 않고 백그라운드에서 디스크에서 바이트를 제거합니다. 또한 다음을 수행합니다:
- 완료되지 않고 만료된 업로드를 취소하고 그 파트를 제거합니다.
- 완료된 업로드의 임시 파트를 제거합니다.
삭제할 빌드를 선택하지는 않습니다. 이미 삭제되었거나 취소된 것만 제거합니다.
물리적 정리는 기본적으로 꺼져 있으며 리포지토리별로 설정합니다. 사용하는 모든 리포지토리에서 켜세요. 그 전까지는 삭제된 파일, 만료된 업로드, 완료된 업로드의 파트가 디스크에 남고 할당량이 삭제된 파일을 계산합니다.
설정
리포지토리 패널에서 물리적 정리을 엽니다:
| 설정 | 콘솔 필드 | 의미 | 기본값 | 범위 |
|---|---|---|---|---|
| 활성화 | 백그라운드 정리 사용 | 백그라운드 정리를 켭니다 | 꺼짐 | |
| 유예 기간 | 삭제 후 유예 기간(시간) | 삭제된 파일이 디스크에 남는 시간(시간 단위) | 24 | 0–8760 |
| 배치 | 배치당 파일 수 | 한 배치에서 처리하는 파일 수 | 25 | 1–100 |
| 간격 | 배치 간격(초) | 배치 사이의 초 | 60 | 5–86 400 |
| 지연 | 파일 간 지연(밀리초) | 파일 사이의 일시 중지(밀리초) | 50 | 0–1000 |
설정 적용를 선택하여 적용합니다. 변경은 즉시 적용됩니다. 정리를 끄면 현재 파일 이후에 중지됩니다. 배치 요청은 곧 배치를 요청하며 즉시 삭제하지는 않습니다. 정리 상태 새로 고침를 선택하여 마지막 배치의 결과를 확인합니다.
유예 기간은 휴지통이 아닙니다. 값이 0이면 파일이 삭제된 직후 그리고 어떤 읽기도 파일을 열고 있지 않으면 바로 제거될 수 있습니다. Arkvory는 삭제된 아티팩트를 복원할 수 없습니다.
정리가 수행하는 작업과 건너뛰는 작업
- 취소되었거나 삭제된, 유예 기간이 지난 파일만 제거합니다. 파일을 사용하는 것이 없는지 다시 확인합니다: 참조, 파일 경로 기록, 첨부 파일 기록.
- 열려 있는 다운로드, 쓰이고 있는 업로드, 실행 중인 백업이 필요한 파일은 정리가 해당 파일을 건너뛰게 합니다. 다음 배치가 다시 시도합니다. 마지막 결과는 처리, 건너뜀, 실패한 파일 수와 확보한 바이트 수를 보여 줍니다.
- 할당량과 논리적 용량은 파일이 디스크에서 제거된 후에만 해제됩니다.
- 배치는 배치 크기와 지연으로 제한되어 디스크 부하를 낮춥니다. 엄격한 디스크 처리량을 보장하지 않으며 다른 요청의 지연에 영향이 전혀 없다고 약속할 수 없습니다.
- 정리는 writer API에서 데이터베이스당 한 번 실행됩니다. writer는 5초마다 만기가 된 리포지토리 하나를 확인합니다. 실행 중인 writer가 없으면 아무것도 정리되지 않습니다.
- 게이트웨이와 워커를 포함한 모든 Arkvory 프로세스를 업데이트한 후에만 정리를 활성화하세요. 정리 프로토콜이 없는 오래된 프로세스가 있으면 정리가 작업을 연기합니다.
아티팩트 삭제
게시된 아티팩트 하나를 직접 삭제할 수 있습니다. 리포지토리에 대한 artifact.delete가 필요합니다.
- 아티팩트 세부 정보에서 아티팩트를 열고 아티팩트 삭제을 찾습니다.
- 종속성 확인를 선택합니다. 콘솔은 아티팩트를 아직 사용하는 것을 보여 줍니다. 삭제를 막는 것이 있으면 먼저 그 의존성을 제거해야 합니다.
- 확인을 위해 아티팩트의 ID를 붙여 넣은 다음 이 아티팩트 삭제을 선택합니다.
이 방식으로 삭제하면 객체를 직접 선택하므로 보호 레이블을 확인하지 않습니다. 의존성은 항상 확인합니다. 삭제 후:
- 아티팩트가 목록과 검색에서 사라집니다. 새 다운로드는 404로 실패합니다. 이미 실행 중인 다운로드는 끝까지 진행할 수 있습니다.
- 패키지 버전은 계속 예약된 상태로 남습니다.
- 바이트는 유예 기간 후 물리적 정리가 제거할 때까지 디스크에 남습니다.
- 콘솔이나 API에서 되돌릴 수 없습니다.
많은 아티팩트의 경우 API는 previewRetention과 applyRetention을 제공합니다. 미리 보기는 특정 날짜 이전에 게시된 후보와 그 차단 사유를 나열합니다. Apply는 전달한 ID만 삭제하며 호출당 최대 100개이고 각 ID에 대한 결과를 반환합니다: deleted, already_deleted, protected, changed, not_eligible, not_found. HTTP 상태뿐만 아니라 모든 결과를 확인하세요.
스토리지 진단 및 이벤트
경고, 오류 및 스토리지 이벤트 섹션은 리포지토리에서 일어난 일을 오래된 순으로 페이지당 100개씩 나열합니다. 다음 페이지는 다음 이벤트 불러오기를 선택합니다. 읽기에는 diagnostics.read가 필요합니다. API 작업은 getStorageEvents이며 수준(info, warning, error)별 필터를 지원합니다.
| 이벤트 | 수준 | 의미 |
|---|---|---|
storage.policy_updated | info | 보존 정책이 저장됨 |
retention.completed | info | 배치가 빌드를 삭제함. 이벤트에 개수가 포함됨 |
retention.failed | error | 예를 들어 권한을 부여한 키가 폐기되어 자동 삭제가 중단됨 |
cleanup.configured | info | 정리 설정이 저장됨 |
cleanup.completed | info 또는 error | 정리 배치가 파일을 처리, 건너뜀 또는 실패함. 개수와 확보한 바이트를 나열함 |
capacity.normal, capacity.warning, capacity.critical, capacity.exceeded, capacity.unlimited | info, warning 또는 error | 할당량 상태가 변경됨 |
| HTTP 오류 코드 | warning 또는 error | 이 리포지토리에 대한 관리 키의 요청이 실패함. 이벤트에 요청 ID, 라우트, 상태가 유지됨 |
기록은 제한됩니다: 리포지토리당 1000개, 전체 20 000개 이벤트이며 가장 오래된 것부터 버려집니다. 이는 전달이 보장된 로그가 아니라 최선형(best-effort) 진단입니다. 필요한 것은 제때 내보내고, 장기 증거로는 서버 로그를 사용하세요. 모니터링을 참조하세요.
패널은 사용량도 보여 줍니다: 게시된 바이트, 완료되지 않은 업로드, 정리를 기다리는 바이트, 할당량 대비 총계. API 작업은 getStorageUsage입니다.
디스크가 가득 찼을 때
징후: 업로드가 HTTP 507과 사유 storage_full로 실패하고, GET /health/ready가 writable: false를 표시하거나, 운영 체제가 여유 공간이 없다고 보고합니다. 다운로드는 계속 동작합니다. 클라이언트는 공간을 확보한 후 업로드를 재개할 수 있습니다.
- 원인을 찾습니다. 스토리지 볼륨, 데이터베이스 볼륨, 보관소 볼륨의 여유 공간을 확인합니다. 스토리지 패널의 사용량 수치와 비교합니다. "정리 대기" 수치가 크면 삭제된 데이터가 아직 디스크에 있다는 뜻입니다. "완료되지 않은 업로드" 수치가 크면 버려진 업로드가 있다는 뜻입니다.
- 정리를 실행합니다. 정리가 꺼져 있으면 삭제된 파일이 즉시 제거되는 것을 받아들이는 경우 0과 같은 짧은 유예 기간으로 모든 리포지토리에서 켭니다. 배치 요청을 선택합니다. 완료된 업로드의 임시 파트와 만료된 업로드도 제거합니다. 배치를 기다리고 마지막 결과를 확인합니다. 정리는 사용 중인 파일을 건너뛰므로 반복하세요.
- 필요 없는 것을 삭제합니다. 보존 정책을 적용하거나 아티팩트를 삭제합니다. 이는 정리가 바이트를 제거한 후에만 공간을 확보합니다.
- 공간을 추가합니다. 볼륨이나 디스크를 확장합니다. 보관소나 다른 데이터가 볼륨을 공유하면 다른 곳으로 옮깁니다.
- 복구를 확인합니다. 공간이 확보되면
writable이true로 돌아오고 업로드가 다시 동작합니다.
blobs/, staging/, parts/의 파일을 직접 삭제하지 마세요: 데이터베이스와 디스크 사이의 연결이 끊어집니다. 같은 볼륨의 로그와 데이터베이스에 예비 영역이 너무 작으면 ARKVORY_STORAGE_RESERVE_BYTES를 높이세요.
대신 업로드가 사유 storage_quota 또는 catalog_limit으로 실패하면 디스크가 문제가 아닙니다. 할당량이나 전역 한도를 높이거나 데이터를 삭제하세요.
제한
- 보존 정책은 등록된 UPack 빌드만 처리합니다. 다른 파일은 절대 제거하지 않습니다.
- 보존 순서는 버전 번호가 아니라 게시 시간입니다.
- 스토리지, 할당량, 정리에는 명시적인 서비스 키 작업이 필요합니다. 비밀번호 계정과 복구 키에는 이러한 작업이 없습니다.
- 물리적 정리는 기본적으로 꺼져 있으며 리포지토리별로 설정합니다.
- 삭제된 아티팩트는 복원할 수 없습니다. 백업에서 데이터를 복원하세요. 백업을 참조하세요.
- 미러된 리포지토리는 스토리지 정책을 실행하지 않습니다. 미러를 참조하세요.
- 스토리지는 로컬 파일 시스템이어야 합니다. 네트워크 공유나 여러 스토리지 백엔드는 지원하지 않습니다.