자동 컴팩션
자동 컴팩션 (Automatic compaction)
Druid에서 세그먼트 크기를 최적화하기 위해 데이터를 자동으로 재인덱싱하는 컴팩션 시스템을 다룹니다. 권장 방식인 compaction supervisor 사용법과 대안인 Coordinator duty 방식을 모두 설명해요.
출처: 문서
본문
Apache Druid에서 컴팩션(compaction)은 Druid 데이터소스에서 데이터를 읽어 같은 데이터소스에 다시 쓰는 특별한 유형의 수집 태스크입니다. 일반적인 유스케이스는 수집 후 세그먼트 크기를 최적화해 쿼리 성능을 높이는 것이에요. 자동 컴팩션(auto-compaction)은 Druid 자신이 발행한 컴팩션 태스크를 자동으로 실행하는 시스템을 말합니다. 자동 컴팩션 외에도 Overlord API를 사용해 수동 컴팩션을 수행할 수 있어요.
참고: 자동 컴팩션은 세그먼트 세분성(segment granularity)이
ALL인 데이터소스는 건너뜁니다.
Druid에서 자동 컴팩션을 실행하는 방법은 두 가지가 있습니다.
- Overlord의 컴팩션 supervisor (권장) — 더 나은 반응성, MSQ 태스크 엔진 지원, supervisor 프레임워크를 통한 더 쉬운 관리를 제공합니다. Auto-compaction using compaction supervisors를 참고하세요.
- Coordinator duty — 컴팩션을 Coordinator duty로 실행하는 대안적인 방식입니다. Auto-compaction using Coordinator duties를 참고하세요.
모범 사례로, 모든 Druid 데이터소스에 자동 컴팩션을 설정해야 합니다. 더 많은 시스템 리소스를 할당하고 싶은 경우에는 컴팩션 태스크를 수동으로 실행할 수 있어요. 예를 들어 기존 데이터소스를 처음으로 컴팩션할 때 여러 컴팩션 태스크를 병렬로 실행하기로 선택할 수 있습니다. 자세한 내용과 유스케이스는 Compaction을 참고하세요.
이 문서는 Druid 클러스터에 자동 컴팩션을 설정하는 방법을 안내합니다. 일반적인 유스케이스의 예시는 Examples 섹션을 참고하세요.
자동 컴팩션 문법
Druid를 재시작하지 않고도 자동 컴팩션을 동적으로 구성할 수 있어요. 자동 컴팩션 시스템은 다음 문법을 사용합니다.
{
"dataSource": <task_datasource>,
"ioConfig": <IO config>,
"dimensionsSpec": <custom dimensionsSpec>,
"transformSpec": <custom transformSpec>,
"metricsSpec": <custom metricsSpec>,
"tuningConfig": <parallel indexing task tuningConfig>,
"granularitySpec": <compaction task granularitySpec>,
"skipOffsetFromLatest": <time period to avoid compaction>,
"taskPriority": <compaction task priority>,
"taskContext": <task context>
}
자동 컴팩션 구성의 대부분 필드는 일반적인 Druid 수집 스펙과 대응됩니다. 다음 속성들은 자동 컴팩션에만 적용됩니다.
skipOffsetFromLatesttaskPrioritytaskContext
자동 컴팩션 시스템은 수동 컴팩션 태스크 위에 관리 계층을 제공하므로, 자동 컴팩션 구성에는 일반적인 Druid 수집 스펙에 있는 태스크별 속성이 포함되지 않습니다. 다음 속성들은 자동 컴팩션 시스템이 자동으로 설정합니다.
- type:
compact로 설정됨. - id: 태스크 유형, 데이터소스 이름, 간격, 타임스탬프로 생성됨. 태스크 ID에는
auto가 접두어로 붙습니다. - context: 사용자가 제공한
taskContext에 따라 설정됨.
컴팩션 태스크는 일반적으로 하위 태스크(subtask)를 시작하기 전에 관련 세그먼트를 모두 가져옵니다. 단, 다음 속성들이 모두 null이 아닌 값으로 설정된 경우는 예외예요. 자동 컴팩션이 실행하는 컴팩트 태스크의 성능을 최대화하고 디스크 사용량을 최소화하려면 이 값들을 null이 아닌 값으로 설정하는 것을 강력히 권장합니다.
granularitySpec—segmentGranularity,queryGranularity,rollup각각에 대해 null이 아닌 값 필요dimensionsSpecmetricsSpec
자동 컴팩션 구성의 각 스펙에 대한 자세한 내용은 Automatic compaction dynamic configuration을 참고하세요.
컴팩션 supervisor로 자동 컴팩션 수행
참고: 세그먼트 세분성(coarsening), 오래된 행 삭제, 데이터가 오래됨에 따른 압축 변경 같은 고급 시간 기반 데이터 수명주기 관리는 Cascading reindexing을 참고하세요.
자동 컴팩션을 실행하는 권장 방법은 Overlord의 컴팩션 supervisor를 사용하는 것입니다. 컴팩션 supervisor는 다음 이점을 제공합니다.
- supervisor 프레임워크로 자동 컴팩션의 상태(state/status) 같은 정보 얻기
- 데이터소스의 컴팩션을 더 쉽게 일시 중지·재개
- 네이티브 컴팩션 엔진 또는 MSQ 태스크 엔진 둘 다 사용 가능
- 반응성이 더 좋아 컴팩션 슬롯이 생기자마자 태스크 제출
- 추적된 컴팩션 태스크 상태로 간격을 반복해서 재컴팩션하는 것을 방지
- 메타데이터 저장소에 전체 컴팩션 상태 대신 컴팩트 지문(fingerprint)을 저장하도록 구성 가능
- Most fragmented first 정책을 통한 경미한(minor) 컴팩션 지원
컴팩션 supervisor를 사용하려면 자동 컴팩션 구성을 supervisor 스펙으로 제출하세요. type을 autocompact로 설정하고 스펙에 자동 컴팩션 구성을 포함합니다.
자동 컴팩션 태스크를 제출하려면 웹 콘솔이나 supervisor API를 통해 supervisor 스펙을 제출할 수 있어요.
웹 콘솔로 컴팩션 supervisor 관리
MSQ 태스크 엔진 자동 컴팩션용 supervisor 스펙을 제출하려면 다음 단계를 수행하세요.
- 웹 콘솔에서 Supervisors 탭으로 이동합니다.
- ... > Submit JSON supervisor를 클릭합니다.
- 대화상자에 다음을 포함합니다.
"type": "autocompact"로 supervisor 스펙의 타입을 설정spec필드에 컴팩션 구성을 추가
{
"type": "autocompact",
"spec": {
"dataSource": YOUR_DATASOURCE,
"tuningConfig": {...},
"granularitySpec": {...},
"engine": <native|msq>,
...
}
- supervisor를 제출합니다.
자동 컴팩션 태스크를 중지하려면 UI나 API를 통해 supervisor를 일시 중지(suspend)하거나 종료(terminate)하세요.
supervisor API로 컴팩션 supervisor 관리
자동 컴팩션을 supervisor 태스크로 제출하는 것은 스트리밍 수집용 supervisor 태스크와 같은 엔드포인트를 사용합니다.
다음 예시는 wikipedia 데이터소스의 자동 컴팩션을 구성합니다.
curl --location --request POST 'http://localhost:8081/druid/indexer/v1/supervisor' \
--header 'Content-Type: application/json' \
--data-raw '{
"type": "autocompact", // required
"suspended": false, // optional
"spec": { // required
"dataSource": "wikipedia", // required
"tuningConfig": {...}, // optional
"granularitySpec": {...}, // optional
"engine": <native|msq>, // optional
...
}
}'
spec.engine을 생략하면 Druid는 기본 컴팩션 엔진을 사용합니다. 컴팩션 동적 구성에서 engine을 설정해 기본 컴팩션 엔진을 제어할 수 있어요. spec.engine과 컴팩션 동적 구성의 engine을 모두 생략하면 Druid는 네이티브 엔진을 기본으로 사용합니다.
자동 컴팩션 태스크를 중지하려면 UI나 API를 통해 supervisor를 일시 중지하거나 종료하세요.
자동 컴팩션에 MSQ 사용
자동 컴팩션이 컴팩션 supervisor를 사용하도록 구성하면 MSQ 태스크 엔진을 컴팩션 엔진으로 사용할 수 있습니다. 자동 컴팩션에 MSQ 태스크 엔진을 사용하려면 다음 요구 사항이 충족되는지 확인하세요.
- Overlord에서 증가분 세그먼트 메타데이터 캐싱(incremental segment metadata caching)을 활성화한다.
- 컴팩션 supervisor를 사용하는 자동 컴팩션을 활성화한다.
- 컴팩션 동적 구성에서
engine을msq로 설정해 모든 컴팩션 supervisor의 기본 컴팩션 엔진으로 MSQ 태스크 엔진을 사용한다. - 또는 관련 데이터소스의 컴팩션 supervisor에서
spec.engine을msq로 설정해 기본 엔진을 오버라이드할 수 있어요. - 컴팩션 태스크 슬롯이 최소 2개 있거나
spec.taskContext.maxNumTasks를 2 이상으로 설정한다. MSQ 태스크 엔진은 실행에 최소 2개의 태스크(컨트롤러 태스크 1개와 워커 태스크 1개)를 요구합니다.
데이터소스를 자동 컴팩션용으로 구성할 때 spec.taskContext.maxNumTasks 파라미터로 최대 태스크 수를 설정하는 등 MSQ 태스크 엔진 컨텍스트 파라미터를 spec.taskContext에서 사용할 수 있어요. 일부 MSQ 태스크 엔진 컨텍스트 파라미터는 자동 컴팩션 파라미터와 겹칩니다. 이런 설정이 겹치면 둘 중 하나만 설정하세요.
MSQ 태스크 엔진 제한 사항
자동 컴팩션에 MSQ 태스크 엔진을 사용할 때 다음 제한 사항을 기억하세요.
metricSpec필드는 특정 집계자에 대해서만 지원됩니다. 자세한 내용은 Supported aggregators를 참고하세요.- 동적(dynamic) 및 범위 기반(range-based) 파티셔닝만 지원됩니다.
metricSpec이 비어 있지 않고 null이 아닐 때만rollup을true로 설정하세요.- 문자열 차원에 대해서만 파티셔닝할 수 있습니다. 다만 다중 값(multi-valued) 문자열 차원은 지원되지 않아요.
DynamicPartitionsSpec에서maxTotalRows구성은 지원되지 않습니다.maxRowsPerSegment를 사용하세요.- 세그먼트는 첫 번째 컬럼이
__time이 되도록만 정렬할 수 있습니다.
지원되는 집계자 (Supported aggregators)
MSQ 태스크 엔진을 사용하는 자동 컴팩션은 다음 속성을 만족하는 집계자만 지원합니다.
- 합병 가능성(Mergeability): 부분 집계를 결합할 수 있어야 함
- 멱등성(Idempotency): 컬럼의 이전에 집계된 값에 집계자를 반복 실행해도 같은 결과를 생성해야 함
이는 다음 longSum 집계자로 예시됩니다.
{"name": "added", "type": "longSum", "fieldName": "added"}
여기서 longSum이 부분 결과를 결합할 수 있어 합병 가능성을 만족하고, 입력과 출력 컬럼이 같아(added) 멱등성을 보장합니다.
다음은 요구 조건 중 하나라도 만족하지 않아 지원되지 않는 집계자의 예시입니다.
added컬럼이sum_added컬럼으로 롤업되어 입력added컬럼을 버리면서, 이후 실행에서added컬럼을 찾지 못해 멱등성을 위반하는longSum집계자:
{"name": "sum_added", "type": "longSum", "fieldName": "added"}
- 부분 집계를 결합하는 데 사용할 수 없고 아래
HLLSketchBuild집계자에 필요한HLLSketchMerge같은 병합 집계자가 필요한 부분 sketch — 합병 가능성을 위반:
{"name": "added", "type": "HLLSketchBuild", "fieldName": "added"}
- 부분 집계를 결합하는 데 사용할 수 없고 다른 count 컬럼으로 롤업되어 입력 컬럼을 버리면서, 합병 가능성과 멱등성을 모두 위반하는 Count 집계자:
{"type": "count", "name": "count"}
Coordinator duty로 자동 컴팩션 수행
컴팩션 supervisor의 대안으로, Coordinator duty를 사용해 자동 컴팩션을 실행할 수 있어요. Coordinator 인덱싱 주기 druid.coordinator.period.indexingPeriod가 컴팩션 태스크의 빈도를 제어합니다. 기본 인덱싱 주기는 30분이며, 즉 자동 컴팩션이 활성화된 시점부터 최대 30분 안에 Coordinator가 컴팩션할 세그먼트를 처음 확인한다는 뜻이에요. 이 시간 주기는 사용되지 않는 세그먼트와 오래된 pending 세그먼트의 정리 같은 다른 Coordinator duty에도 영향을 줍니다. indexingPeriod를 건드리지 않고 자동 컴팩션 시간 주기를 구성하려면 Set frequency of compaction runs를 참고하세요.
자동 컴팩션이 호출될 때마다 Coordinator는 컴팩션할 자격이 있는 세그먼트를 결정하기 위해 세그먼트 검색을 시작합니다. 컴팩션할 자격이 있는 세그먼트가 있으면 Coordinator는 사용 가능한 워커 용량에 따라 컴팩션 태스크를 발행합니다. 컴팩션 태스크가 인덱싱 주기보다 오래 걸리면 Coordinator는 세그먼트 검색 주기를 재개하기 전에 그 태스크가 끝나기를 기다립니다.
데이터소스에 대한 Coordinator 기반 자동 컴팩션은 웹 콘솔이나 API로 프로그래밍 방식으로 구성할 수 있어요. 이 과정은 웹 콘솔의 Tasks 뷰나 Tasks API에서 제출할 수 있는 수동 컴팩션 태스크와는 다릅니다.
Coordinator 기반 자동 컴팩션을 사용하려면 다음 구성 요구 사항이 충족되어야 합니다.
- 컴팩션 동적 구성을 업데이트하고 다음을 설정한다.
useSupervisors를false로 설정engine을native로 설정 (Coordinator에서는 MSQ 태스크 엔진이 컴팩션 엔진으로 지원되지 않으므로 네이티브 엔진을 사용)
웹 콘솔로 자동 컴팩션 관리
웹 콘솔을 사용해 다음과 같이 데이터소스의 자동 컴팩션을 활성화할 수 있어요.
- 최상위 내비게이션에서 Datasources를 클릭합니다.
- Compaction 컬럼에서 컴팩션할 데이터소스의 편집 아이콘을 클릭합니다.
- Compaction config 대화상자에서 자동 컴팩션 설정을 구성합니다. 이 대화상자는 폼 뷰와 JSON 뷰를 제공해요. 폼을 편집하면 JSON 스펙이 업데이트되고, JSON을 편집하면 (존재하는 경우) 폼 필드가 업데이트됩니다. JSON에 없는 폼 필드는 기본값을 나타냅니다. 폼에 표시되지 않는 자동 컴팩션 설정을 위해 JSON에 추가 속성을 추가할 수 있어요. 지원되는 자동 컴팩션 설정은 Configure automatic compaction을 참고하세요.
- Submit을 클릭합니다.
- Datasources 뷰를 새로고침합니다. 데이터소스의 Compaction 컬럼이 "Not enabled"에서 "Awaiting first run"으로 바뀝니다.
자동 컴팩션이 활성화된 데이터소스의 컴팩션 구성 대화상자 스크린샷은 위에서 확인할 수 있어요.
데이터소스의 자동 컴팩션을 비활성화하려면 컴팩션 구성 대화상자에서 Delete를 클릭하세요. Druid는 자동 컴팩션 구성을 유지하지 않습니다.
Coordinator API로 자동 컴팩션 관리
자동 컴팩션을 구성하려면 Automatic compaction API를 사용하세요. 데이터소스의 자동 컴팩션을 활성화하려면 원하는 자동 컴팩션 설정으로 JSON 객체를 만드세요. 자동 컴팩션 스펙의 문법은 Configure automatic compaction을 참고하세요. 그 JSON 객체를 /druid/coordinator/v1/config/compaction에 POST 요청의 페이로드로 보냅니다.
다음 예시는 wikipedia 데이터소스의 자동 컴팩션을 구성합니다.
curl --location --request POST 'http://localhost:8081/druid/coordinator/v1/config/compaction' \
--header 'Content-Type: application/json' \
--data-raw '{
"dataSource": "wikipedia",
"granularitySpec": {
"segmentGranularity": "DAY"
}
}'
데이터소스의 자동 컴팩션을 비활성화하려면 /druid/coordinator/v1/config/compaction/{dataSource}에 DELETE 요청을 보내세요. {dataSource}를 자동 컴팩션을 비활성화하려는 데이터소스의 이름으로 교체합니다. 예를 들어:
curl --location --request DELETE 'http://localhost:8081/druid/coordinator/v1/config/compaction/wikipedia'
컴팩션 빈도 변경
Coordinator가 인덱싱 주기보다 더 자주 컴팩션을 확인하도록 하려면 컴팩션 duty를 처리하는 별도의 그룹을 만드세요. coordinator/runtime.properties 파일에서 duty 그룹의 시간 주기를 설정합니다. 다음 예시는 compaction이라는 duty 그룹을 만들고 자동 컴팩션 주기를 1분으로 설정하는 방법을 보여줘요.
druid.coordinator.dutyGroups=["compaction"]
druid.coordinator.compaction.duties=["compactSegments"]
druid.coordinator.compaction.period=PT60S
Coordinator duty 자동 컴팩션 통계 보기
Coordinator가 자동 컴팩션을 시작한 후에는 이미 컴팩션된 바이트·세그먼트·간격 수와 컴팩션 대기 중인 것들을 포함해 데이터소스의 컴팩션 통계를 볼 수 있어요. Coordinator는 세그먼트 검색 정책에 따라 컴팩션 자격이 없는 총 바이트·세그먼트·간격 수도 보고합니다.
웹 콘솔에서 Datasources 뷰가 자동 컴팩션 통계를 표시합니다. Tasks 뷰는 자동 컴팩션 시스템이 트리거한 컴팩션 태스크의 태스크 정보를 보여줍니다.
API로 통계를 얻으려면 /druid/coordinator/v1/compaction/status에 GET 요청을 보내세요. 특정 데이터소스로 결과를 필터링하려면 데이터소스 이름을 쿼리 파라미터로 전달합니다. 예: /druid/coordinator/v1/compaction/status?dataSource=wikipedia.
수집과의 충돌 피하기
컴팩션 태스크는 수집과 간섭하면 중단될 수 있습니다. 예를 들어 수집 태스크가 컴팩션용으로 잠긴 시간 간격의 세그먼트에 데이터를 써야 할 때 이런 일이 발생합니다. 컴팩션이 진행되지 못하게 하는 연속적인 실패가 있다면 다음 전략 중 하나를 고려하세요.
- 데이터소스와 수집 태스크에서 동시 append 및 replace 태스크(concurrent append and replace)를 활성화한다.
skipOffsetFromLatest를 설정해 수집과 컴팩션 사이의 충돌 가능성을 줄인다. 자세한 내용은 Skip compaction for latest segments를 참고하세요.- 수집 태스크 대비 컴팩션 태스크의 우선순위 값을 높인다. 고급 사용자에게만 권장됩니다. 이 방법은 수집 작업이 실패하거나 지연될 수 있어요. 컴팩션 태스크의 우선순위를 바꾸려면 자동 컴팩션 구성에서
taskPriority를 원하는 우선순위 값으로 설정하세요. 태스크 유형별 우선순위 값에 대한 자세한 내용은 Lock priority를 참고하세요.
동시 append 및 replace 활성화
동시 append 및 replace(concurrent append and replace)를 사용하면 새 데이터가 컴팩션 중에도 해당 간격에 추가되는 동안 데이터소스 간격의 기존 데이터를 안전하게 교체할 수 있습니다.
이를 위해 데이터소스가 동시 append 및 replace 태스크를 허용하도록 업데이트해야 합니다.
- API를 사용한다면 호출에
"useConcurrentLocks": truetaskContext 속성을 포함하세요. - UI를 사용한다면 데이터소스의 컴팩션 구성에서 Use concurrent locks를 활성화하세요.
또한 데이터소스의 수집 작업도 "useConcurrentLocks": true 태스크 컨텍스트를 포함하도록 업데이트해야 해요. 방법은 Concurrent append and replace를 참고하세요.
최신 세그먼트 컴팩션 건너뛰기
Coordinator는 세그먼트를 최신 것부터 오래된 것 순으로 컴팩션합니다. 자동 컴팩션 구성에서 가장 최근 세그먼트의 종료 시간을 기준으로 컴팩션하지 말아야 할 시간 주기를 설정할 수 있어요. 이 값을 skipOffsetFromLatest에 할당하세요. 이 오프셋은 현재 시간이 아니라 최신 세그먼트 시간을 기준으로 한다는 점을 유의하세요. 예를 들어 가장 최근 세그먼트의 종료 시간으로부터 5일 전의 세그먼트를 건너뛰려면 "skipOffsetFromLatest": "P5D"를 할당합니다.
skipOffsetFromLatest를 설정할 때는 스트림이 늦게 도착하는(late arriving) 데이터를 얼마나 자주 받을 것으로 예상하는지 고려하세요. 스트림이 가끔만 늦게 도착하는 데이터를 받는다면, skipOffsetFromLatest 윈도우 밖으로 데이터가 수집되더라도 자동 컴팩션 시스템이 데이터를 견고하게 컴팩션합니다. 대부분의 실시간 스트리밍 수집 유스케이스에서는 skipOffsetFromLatest를 몇 시간이나 하루로 설정하는 것이 합리적입니다.
예시 (Examples)
다음 예시들은 자동 컴팩션이 Druid 성능을 개선할 수 있는 잠재적 유스케이스를 보여줍니다. 자세한 내용은 Compaction strategies를 참고하세요. 이 섹션의 예시는 기본 데이터를 변경하지 않습니다.
세그먼트 세분성 변경
wikistream 데이터소스에 HOUR 세그먼트 세분성으로 데이터를 수집하도록 스트림을 구성했다고 가정해요. Druid 세그먼트가 권장 세그먼트 크기인 세그먼트당 5백만 행보다 작다는 것을 발견했다면, 최근 일주일의 데이터는 스트림이 그 기간 내에 데이터를 꾸준히 받으므로 컴팩션하지 않고 남겨두면서 세그먼트를 DAY 세분성으로 자동 컴팩션하고 싶을 거예요.
다음 자동 컴팩션 구성은 최근 일주일의 데이터는 컴팩션하지 않은 채 기존 HOUR 세그먼트를 DAY 세그먼트로 컴팩션합니다.
{
"dataSource": "wikistream",
"granularitySpec": {
"segmentGranularity": "DAY"
},
"skipOffsetFromLatest": "P1W"
}
파티셔닝 스킴 업데이트
wikipedia 데이터소스에 대해, 데이터를 쿼리할 때의 계산 시간을 희생하지 않으면서 정기적으로 데이터를 수집할 때 세그먼트 접근을 최적화하고 싶다고 가정해요. 배치 append 수집 스펙은 쓰기 시간 연산을 최적화하기 위해 동적 파티셔닝을 사용하고, 스트림 수집 파티셔닝은 스트림 서비스가 구성합니다. 쿼리에서 자주 접근하는 차원을 바탕으로 channel, countryName, namespace 차원에 대해 다중 차원 범위 파티셔닝(multi-dimension range partitioning)을 사용한 적절한 읽기 시간 파티셔닝으로 데이터를 재구성하는 자동 컴팩션을 구현하고 싶습니다.
다음 자동 컴팩션 구성은 wikipedia 세그먼트를 다중 차원 범위 파티셔닝을 사용하도록 업데이트합니다.
{
"dataSource": "wikipedia",
"tuningConfig": {
"partitionsSpec": {
"type": "range",
"partitionDimensions": [
"channel",
"countryName",
"namespace"
],
"targetRowsPerSegment": 5000000
}
}
}
더 알아보기
자세한 내용은 다음 문서들을 참고하세요.
- Compaction — Druid 컴팩션 개요
- Manual compaction — 컴팩션 태스크를 수동으로 수행하는 방법
- Segment optimization — Druid 세그먼트 크기 평가·최적화 가이드
- Coordinator process — Coordinator가 컴팩션 태스크를 계획하는 방법
더 알아보기 (Learn more)
- 자동 컴팩션을 API로 설정하는 방법은 automatic-compaction API 문서를 참고하세요.
- 컴팩션의 전반적인 개념은 compaction 문서에서 확인해 보세요.