storgate draft
¶
/usr/local/m2/setting.json
다음 영역에 대해 기술한다.
{
"functions": {
"backend": {
"storgate": {
}
}
}
}
buckets¶
버킷 구성의 역할은 크게 3가지이다.
멀티 백엔드를 통합한다.
클라이언트에게 위치투명성을 제공한다.
파일을 실시간/배치로 가공한다.
"buckets": [
{
...
},
{
...
}
]
meta¶
개별 버킷의 기본설정을 정의한다.
"meta": {
"enable": true,
"name": "mybucket",
"region": "ap-northeast-2",
"expose": true
}
enable (기본: true)
버킷 활성화
name
버킷 이름
region (기본: ap-northeast-2)
버킷 리전
expose
(S3 브라우저등) 외부 인터페이스 노출 여부
Note
onBatch 전용으로 사용되는 버킷이라면 노출될 필요가 없다.
mounts¶
백엔드 엔드포인트를 구성한다.
"mounts": [
{
"mountPoint": "/image1",
"originPath": "mystorage@aws_s3",
},
{
"mountPoint": "/image2",
"originPath": "/mnt/nas/images"
},
{
"mountPoint": /_this_path_is_hidden",
"originPath": "google_storage@aws_s3/skip/this/path",
"expose": false
}
]
mountPoint (기본: null)
버킷에 마운트될 경로. 값이
null
인 경우 루트로 마운트된다.originPath
원본 백엔드
/
로 시작하는 경우 로컬 파일시스템을 가리킨다.aws_s3 에 정의된 버킷의 이름을 사용하면 해당 백엔드로 연결된다. 연결뒤에 건너띌 경로를 지정할 수 있다.
expose (기본: true)
외부 인터페이스 노출 여부
Note
expose
속성이 존재하는 이유는 tasks 의.savePath
설정으로 접근할 수 있는 경로가 여기서 구성한 경로로 한정되기 때문이다. 다시 말해 클라이언트에게 경로를 숨기며 내부적인 저장경로로 사용할 경우 이 속성을false
로 설정한다.
멀티 origin
을 한데 묶을 경우 경로 충돌이 발생할 수 있다.
명시적으로 선언된
mountPoint
경로가 우선한다.mountPoint
경로가 없다면 먼저 선언된origin
이 우선한다.
경로 추상화¶
mounts 기능은 분산된 백엔드 멀티 스토리지를 하나의 경로체계로 통합한다. 따라서 workflows , onBatch 등에서는 프로토콜과 무관하게 일관된 경로체계를 사용한다.
access¶
클라이언트 접근권한을 설정한다.
Note
거부된 접근은 403 Forbidden
으로 응답한다.
get¶
읽기 권한을 설정한다.
"get": {
"enable": true
}
enable (기본: true)
권한 활성화
put¶
쓰기 권한을 설정한다.
"put": {
"enable": true
}
enable (기본: true)
권한 활성화
delete¶
삭제 권한을 설정한다.
"delete": {
"enable": true
}
enable (기본: true)
권한 활성화
events¶
사전 정의된 시점에 발생하는 이벤트 처리를 정의한다.
"events": {
"onBatch": [ ],
"onGet": { },
"onPut": { },
"onDelete": { }
}
시점 |
설명 |
---|---|
|
정해진 시간(주기)마다 일괄처리 |
|
데이터 읽기 시점 |
|
데이터 쓰기 시점 |
|
데이터 삭제 시점 |
모든 이벤트는 filter
, trigger
, webhook
설정을 지원한다.
"on***": {
"enable": false,
"filter": {
"patterns": [ "*.old" , "*.log.gz" ],
"excludes": [ "*.conf", ".git" ],
"filetype": "file",
"recursive": true,
"age": "2d",
"size": "1m"
},
"trigger": {
"workflow": "migrate_tmpimg",
"timing": "post"
},
"webhook": {
"onItemCompleted": "/usr/local/m2/webhook/call.js",
"onItemAborted": "/usr/local/m2/webhook/call_err.js"
}
}
enable (기본: false)
활성화
filter (기본: null)
필터 ( ansible.builtin.find module – Return a list of files based on specific criteria 참고)
Hint
개발 후 릴리스 시점에 정리한다.
trigger
수행될 트리거(=워크플로우)
workflow
워크플로우 이름
timing (기본: post)
시점
pre
워크플로우 선행 후 클라이언트 요청처리post
클라이언트 요청처리 후 워크플로우 수행
Note
사전 콘텐츠 가공 목적이라면
pre
시점보다 URL 함수체인이 권장된다.
webhook
웹훅을 호출한다.
onItemCompleted
개별 처리가 정상완료 될 때마다 호출된다.
onItemAborted
개별 처리가 에러상황으로 중단될 때마다 호출된다.
onBatch¶
mounts 를 대상으로 정해진 시간(주기)마다 약속된 작업을 수행한다. 단일 백엔드를 대상으로 멀티 배치를 수행할 수 있다.
"onBatch": [
{
"enable": false,
"chunkSize": 1000,
"path": "/image/upload",
"traverse": "depth",
"cursor": "continue",
"schedule": "0 1 * * *",
"filter": { ... },
"trigger": { ... },
"webhook": {
"onChunkExtracted": "/usr/local/m2/webhook/begin_chunk.js",
"onChunkCompleted": "/usr/local/m2/webhook/end_chunk.js",
"onItemCompleted": "/usr/local/m2/webhook/kafkapub.js"
}
}
]
chunkSize (기본: 1000)
청크 크기(개수)
Note
기본 값이 1천개인 이유는 AWS S3에서 한번에 리스팅할 수 있는 최대 객체수가 1,000개이기 때문이다. (2024년 12월 기준)
path
경로 추상화 된 디렉토리 (
/
루트)Note
로컬 경로라도 반드시 mounts 구성이 필요하다.
여러 디렉토리를 추출하려면 워크플로우를 멀티로 구성할 것을 권장한다.
traverse (기본: depth)
파일트리 탐색방법 (
depth
또는breadth
)Hint
[개발단계 체크] S3에선 설정이 불가할 수 있다.
cursor (기본: continue)
작업목록(청크) 추출 정책
continue (기본)
이전 청크의 마지막부터 이어서 진행한다.reset
항상 처음부터 진행한다.Warning
reset
정책은 원본이 onComplete 설정에 의해 삭제, 이동된 경우에만 사용한다. 원본이 그대로 존재하는 경우 무한루프가 발생할 수 있다.
schedule
추출 스케쥴. cron 형식
webhook
각 시점마다 약속된 웹훅을 호출한다.
onChunkExtracted (리더만 수행)
chunkSize
만큼 작업목록이 준비된 직후 호출된다.onChunkCompleted (리더만 수행)
chunkSize
단위 작업이 완료된 시점에 호출된다.onItemCompleted
개별 처리가 완료될 때마다 호출된다.
onGet¶
읽기 이벤트를 정의한다.
"onGet": {
"enable": false,
"filter": null,
"trigger": {
"workflow": "migrate_tmpimg",
"timing": "post"
}
}
Hint
[백업용] 현재 개발단계에서 cache
기능은 제외한다.
"cache": {
"enable": false,
"vhost": "foo.com"
}
onPut¶
쓰기 이벤트를 정의한다.
"onPut": {
"enable": true,
"trigger": {
"workflow": "migrate_tmpimg",
"timing": "post"
}
}
enable (기본: false)
활성화
filter (기본: null)
필터
trigger
워크플로우 트리거
workflow
워크플로우 이름
timing (기본: post)
시점
pre
워크플로우 선행 후 클라이언트 요청처리post
클라이언트 요청처리 후 워크플로우 수행
onDelete¶
삭제 이벤트를 정의한다.
"onDelete": {
"enable": true,
"trigger": {
"workflow": "migrate_tmpimg",
"timing": "post"
}
}
workflows¶
워크플로우는 콘텐츠를 가공하는등 수행해야하는 구체적인 작업을 의미한다. 단일 원본에 대해 동시에 여러 작업을 진행할 수 있다.
"workflows": [
{
"name": "migrate_tmpimg",
"enable": true,
"tasks": [ ]
},
{
"name": "remove_old",
"tasks": [ ]
}
]
name
워크플로우 이름
enable (기본: true)
워크플로우 활성화
tasks
워크플로우의 개별 아이템(원본 데이터)당 처리 작업을 정의한다.
tasks¶
단일 원본에 대해 동시에 여러 산출물을 생산하고,저장하는 것까지 담당한다.
"tasks": [
{
"function": "/hyperdims/format/avif/optimize",
"savePath": "/newimg/{{ item.path }}",
"whenExist": "overwrite",
"timeout": 60
},
{
"function": "/hyperdims/format/webp/resize/500",
"savePath": "/{{ item.path | relpath(source_dir) | dirname }}/{{ item.path | basename | rsplit('.', 1)[0] }}_m.{{ item.path | basename | rsplit('.', 1)[-1] }}",
},
{
"function": "/hyperdims/format/webp",
"savePath": "/newimg/#2",
"pathPattern": "/([^/]+)/(.*)"
}
]
function
가공 함수체인. 소스는 events 가 발생한 개별 파일로 지정된다.
savePath
값이 유효하지 않거나
null
이라면 원본 경로에 덮어쓰기한다. Nunjucks 표현이며 사용할 수 원본경로는item
에 바인딩된다.Note
null
은 허가하지 않는다.원본 덮어쓰기라도 명시적으로 {{ item.path }} 로 지정한다.
소속
bucket
의 상대경로만 접근할 수 있다. (참조 - mounts )
변수
설명
예시
item.path
파일의 전체 경로
/dir/sample.jpg
item.filename
파일명
sample.jpg
item.dirname
파일이 위치한 디렉토리 경로
/dir
item.state
파일의 상태
file
item.size
파일의 크기 (bytes)
123456
item.owner
파일의 소유자
root
item.group
파일의 소유 그룹
users
item.mode
파일의 권한 모드
0644
item.mtime
파일의 최종 수정 시간 (UNIX 타임스탬프)
1622555123
item.atime
파일의 마지막 접근 시간 (UNIX 타임스탬프)
1622555200
item.ctime
파일의 생성 시간 (UNIX 타임스탬프)
1622554987
item.inode
파일의 inode 번호
12345
pathPattern
savePath
에서 사용할 정규표현식 패턴.#1
,#2
등으로 소스경로를 참조할 수 있다.Note
pathPattern
은savePath
생성을 위한 Nunjucks 실행 이전에 동작한다.whenExist (기본: overwrite)
savePath
에 파일이 존재할 경우 정책overwrite (기본)
항상 덮어쓴다.skip
덮어쓰지 않는다.diff
파일이 변경되었을 때만 덮어쓴다.
timeout (기본: 60초)
실패 타임아웃
onComplete¶
모든 tasks 이 완료된 상태에서 수행된다.
"onComplete": {
"src": {
"op": "none"
}
}
src
개별 아이템 작업 완료 후 소스 파일에 대한 처리
op (기본: none)
오퍼레이션
none (기본)
아무 작업도 진행하지 않는다.delete
삭제한다.move
약속된 디렉토리로 이동시킨다."src": { "op": "move", "path": "/processed/{{ item.path }}" }
distribution¶
멀티노드 환경에서 workflows 분산처리 설정을 정의한다.
meta¶
"meta" : {
"enable": true
}
enable (기본: true)
활성화.
false
라면 분산없이 모든 노드는 리더로 동작한다.
leader¶
대규모 onBatch 작업들을 관리할 리더를 선출한다.
"leader": {
"url": "file://mnt/nas/images/temp/.{vhost}.m2leader",
"authEndpoint": null
}
url
리더선출에 사용할 락파일의 URL. 락은 고유하게 생성되기 때문에 멀티 가상호스트에 의해 동시수행되어도 충돌하지 않는다. 파일시스템
file://
, S3https://
등을 지원한다.authEndpoint
인증이 필요한 백엔드와 연결할 경우 aws_s3 에 정의된
name
을 지정한다.
leader
선출¶
leader
노드가 없다면 모든 노드는 leader 설정을 기반으로leader
를 선출한다. 단일 노드로 구동되는 환경이라도 동일하다.leader
노드는 지속적으로 임기(기본: 5분)를 연장한다.leader
노드 장애시 임기동안은 작업이 중단된다.임기가 만료된 상태에서
leader
노드가 없다면 1번 단계를 수행한다.
leader
노드 장애¶
리더에 장애가 발생한다면 수행중인 청크는 일시 중단되며, 리더 재선출을 수행한다.
리더 재선출 후 진행 중인 청크는 재개된다.
Note
leader
는 재작업을 최소화하기 위해 실시간으로 완료된 진행상황을 모든 노드와 공유한다.
수행노드 장애¶
수행노드의 장애가 발생하면 리더가 배제시키고 워크플로우를 완수한다.
Warning
최악의 경우 해당 노드가 수행중이던 작업은 1회 더 수행될 수 있다.
throttling¶
CPU 가용량에 충분한경우에만 tasks 를 수행한다.
"throttling": {
"enable": true,
"cpu": {
"deactive": 60,
"reactive": 40
}
}
enable (기본: true)
throttling
을 활성화한다.cpu
평균 CPU 사용량에 따라 동적으로 워크플로우를 수행한다.
Note
평균 cpu 사용량 기준은 전역으로 변경이 가능하다.
deactive (기본: 60, 범위: 0 ~ 100)
평균 CPU 사용량이 설정 값 이상이라면 부하를 낮추기 위해 수행을 잠시 중단한다.
reactive (기본: 40, 범위: 0 ~ 100)
(
deactive
상태에서) 평균 CPU 사용량이 설정 값 미만이라면 다시 수행을 재개한다.Note
reactive
값이deactive
값을 초과하거나 유효 범위가 아니라면deactive
의2/3
수치로 적용된다.
분산처리와 장애복구¶
See also
정상적인 경우 리더에 의해 모든 작업이 관리된다.
workflow는 chunkSize
단위로 작업을 분할하여 수행한다.
리더에 장애가 발생한다면 리더 재선출 후 진행 중인 청크는 재개된다.
leader
는 재작업을 최소화하기 위해 실시간으로 완료된 진행상황을 모든 노드와 공유한다.
Note
리더승계시 마커(marker)의 이해
AWS S3 ListObjects 의 경우
NextMarker
를 모든 청크 단위로 공유한다.NTFS/VFS인 경우 새로운 리더가 동일한 알고리즘으로 해당 지점까지 traverse를 수행한 뒤 재개한다.
설정예제¶
NFS 랜딩존¶
특정 디렉토리를 감지하여 서비스 디렉토리로 이관한다.
설정 예제는 아래와 같다.
"storage": {
"buckets": [
{
"name": "image_landing_bucket",
"expose": true,
# /image_landing 디렉토리만 노출한다.
# /image_service 디렉토리는 노출하지 않는다.
"mounts": [
{
"mountPoint": "/image_landing",
"originPath": "/mnt/nas/upload"
},
{
"mountPoint": "/image_service",
"originPath": "/mnt/nas/image/service",
"expose": false
}
],
# 5분마다 /image_landing 디렉토리를 스캔하여, migrate_tmpimg 워크플로우를 실행한다.
# 배치로 개별 아이템이 처리될 떄마다 CDN에 Purge한다.
"events": {
"onBatch": [
{
"enable": true,
"chunkSize": 1000,
"path": "/image_landing",
"schedule": "*/5 * * * *"
"trigger": {
"workflow": "migrate_tmpimg"
},
"webhook": {
"onItemCompleted": "/usr/local/m2/webhook/purge_cdn.js"
}
}
]
}
# workflow 정의
# /image_landing 디렉토리의 파일을 /image_service 디렉토리로 이관한다.
# 이관후 원본파일은 삭제한다.
"workflows": [
{
"name": "migrate_tmpimg"
"tasks": [
{
"function": null,
"savePath": "/image_service/{{ item.path }}",
"whenExist": "overwrite",
"timeout": 60
}
],
"onComplete": {
"src": {
"op": "delete"
}
}
}
]
}
]
}