이 기능은 비공개 프리뷰 기능이며, 향후 릴리스에서 하위 호환되지 않는 방식으로 변경될 수 있습니다.
enable_time_series_table 설정을 사용하여
TimeSeries 테이블 엔진 사용을 활성화하십시오.
set enable_time_series_table = 1 명령을 입력하십시오.TimeSeries 테이블 엔진은 ClickHouse Cloud에서 비공개 프리뷰 기능으로 제공됩니다.
비공개 프리뷰에 참여하는 서비스에는 이미 enable_time_series_table 설정이
구성되어 있습니다. 그 외의 ClickHouse Cloud 서비스에는 이 구성이
적용되어 있지 않으며, 해당 서비스에서는 사용자가 직접 이 엔진을
활성화할 수 없습니다.구문
SAMPLES 키워드에는 DATA라는 별칭이 있고, METRIC FAMILIES 키워드에는 METRICS라는 별칭이 있으며, 둘 다 이전 버전과의 호환성을 위해 유지됩니다.
4 이전 버전의 테이블 정의는 METRICS로 작성되므로, 이전 버전의 서버에서도 이를 읽을 수 있습니다.사용법
기본 설정을 그대로 사용해 시작하는 편이 더 쉽습니다 (TimeSeries 테이블은 컬럼 목록을 지정하지 않고도 생성할 수 있습니다):
외부 컬럼
TimeSeries 테이블의 컬럼은 자동으로 생성됩니다. 이러한 컬럼을 외부 컬럼이라고 하며, 데이터는 저장하지 않고 SELECT/INSERT를 위한 인터페이스만 제공합니다. 실제 데이터는 대상 테이블에 저장됩니다. 다음은 외부 컬럼 목록입니다:
예시:
metric_name은 비워 둘 수 있으며, 이는 메트릭 이름이 tags의 __name__에 지정된다는 의미입니다. 예시는 다음과 같습니다:
metric_family, type, unit, help 컬럼에 값을 삽입합니다:
외부 컬럼 지정
외부samples 컬럼은 CREATE TABLE 문에서 명시적으로 나열해 기본 Array(Tuple(DateTime64(3), Float64)) 유형을 재정의할 수 있습니다(이전 이름인 time_series도 허용됩니다). ClickHouse는 튜플에서 타임스탬프와 스칼라 유형을 추출해 내부 samples table에 반영합니다:
INNER COLUMNS 절에서 timestamp 및 value 컬럼의 유형을 직접 선언하는 것과 동일합니다:
CREATE TABLE 문에서 사용하는 경우, 선언된 유형이 일치해야 합니다.
target table
TimeSeries 테이블은 자체 데이터를 갖지 않으며, 모든 데이터는 target table에 저장됩니다.
이는 materialized view의 동작 방식과 비슷하지만,
materialized view는 target table이 하나인 반면
TimeSeries 테이블에는 samples, tags, 메트릭 패밀리라는 세 개의 필수 target table이 있고,
기본적으로 활성화되어 있는 선택적 최근 샘플 target table이 있습니다
(recent_samples_ttl_seconds 설정 참조).
target table은 CREATE TABLE 쿼리에서 명시적으로 지정할 수도 있고
TimeSeries 테이블 엔진이 내부 target table을 자동으로 생성할 수도 있습니다.
TimeSeries 테이블에 삽입된 행은 변환되고 블록으로 분할된 후, 이 target table들에 삽입됩니다.
target table은 다음과 같습니다:
Samples table
samples 테이블에는 특정 식별자에 연결된 시계열이 포함됩니다. samples 테이블에는 다음 컬럼이 있어야 합니다:
엔진이 자체적으로 생성하는 컬럼에는 시계열 압축 코덱이 적용됩니다:
timestamp CODEC(Delta, T64, ZSTD(3)) 및 value CODEC(ALP, ZSTD(3))입니다. 거의 단조로운 타임스탬프는 일반 코덱으로는 거의
압축되지 않으며, 그렇지 않으면 samples 테이블의 디스크상 크기에서 큰 비중을 차지할 수 있습니다.
엔진은 내부 samples 테이블과 최근 샘플 테이블에 대해 enable_alp_codec 설정 없이도 ALP를 활성화합니다.
컬럼 타입 조정도 참조하십시오.
최근 샘플 테이블
최근 샘플 테이블은 선택 사항이며 기본적으로 활성화되어 있습니다(recent_samples_ttl_seconds 설정 참조. 이 값을 0으로 설정하면 테이블이 비활성화됩니다). 이 테이블에는 해당 설정에서 정의한 TTL보다 최신인 샘플의 복사본이 포함되며, samples 테이블과 동일한 컬럼을 가져야 합니다. 생성된timestamp 컬럼은 CODEC(Delta, T64, ZSTD(3))을 사용하고,
생성된 value 컬럼은 CODEC(ALP, ZSTD(3))을 사용합니다.
삽입되는 모든 샘플은 samples 테이블과 최근 샘플 테이블 모두에 기록됩니다.
시간 범위가 TTL 윈도우 내에 있는 쿼리는 최근 샘플 테이블이 훨씬 작으므로 기본 samples 테이블 대신 최근 샘플 테이블에서 읽습니다(쿼리 수준 설정 time_series_prefer_recent_samples_table으로 이 동작을 비활성화할 수 있습니다).
내부 최근 샘플 테이블의 TTL은 항상 recent_samples_ttl_seconds 설정을 기반으로 결정됩니다.
Tags 테이블
tags 테이블에는 메트릭 이름과 태그의 각 조합별로 계산된 식별자가 포함됩니다. tags 테이블에는 다음 컬럼이 있어야 합니다:
version 5 이상에서
MergeTree 엔진 계열을 사용하는 새 내부 tags 테이블에는 tags에 대한 역텍스트 인덱스가 있습니다:
INDEX tags_idx tags TYPE text(tokenizer = 'keyValuePairs'). 키와 값을 함께 조회하여 PromQL의
{job="api"}와 같은 정확한 레이블 일치를 가속합니다. 빈 문자열과의 비교도
누락된 레이블과 일치하며 이 인덱스를 사용하지 않습니다.
TAGS INNER COLUMNS에 명시적으로 선언된 인덱스는 기본 인덱스를 대체합니다. 기존 테이블과 외부
tags 테이블은 기존 인덱스를 유지합니다. 이 기능을 활성화하려면 해당 tags target table에 인덱스를 추가하고 구체화하십시오.
메트릭 패밀리 테이블
metric families 테이블에는 수집 중인 메트릭 패밀리, 해당 메트릭 패밀리의 타입, 그리고 설명에 대한 정보가 포함됩니다. 메트릭 패밀리는 동일한 이름(__name__ 태그)과 동일한 타입을 가진 메트릭 그룹입니다. 예를 들어 histogram은 여러 메트릭으로 구성된 메트릭 패밀리입니다.
metric families 테이블에는 다음 컬럼이 있어야 합니다:
생성
TimeSeries 테이블 엔진을 사용하여 테이블을 생성하는 방법은 여러 가지가 있습니다.
가장 간단한 SQL 문은
SHOW CREATE TABLE my_table을 실행하여 확인할 수 있습니다):
INNER COLUMNS 절에 자체 컬럼 정의가 저장된 4개의 내부 대상 테이블도 생성됩니다. recent_samples_ttl_seconds 설정은 기본값과 함께 SETTINGS 절에 기록됩니다. 이 설정은 최근 샘플 테이블의 TTL을 정의하므로, 실제 값은 생성 시점에 고정됩니다.
또한 최신 스키마 버전이 version 설정에 고정됩니다(스키마 버전 관리 참조).
내부 대상 테이블의 이름은 .inner_id.samples.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx,
.inner_id.recentsamples.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, .inner_id.tags.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx,
.inner_id.metricfamilies.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
이며 각 대상 테이블에는 고유한 열 집합이 있습니다:
기존 테이블을 AS로 사용해 테이블 생성
문CREATE TABLE new_table AS existing_table은 existing_table과 동일하게 구성된 TimeSeries 테이블을 생성합니다.
existing_table은 TimeSeries 테이블이어야 합니다. existing_table의 외부 대상은 복사되지 않으므로 문에서
해당 대상을 직접 선언해야 합니다.
이 문은 existing_table에서 다음 항목을 복사합니다.
version을 제외한SETTINGS절: 새 테이블에는 항상 최신 버전이 적용됩니다. 문에 직접 작성한 설정은 이름을 기준으로 복사된 설정과 병합되므로, 직접 작성한 설정이 복사된 설정에 우선하며name = DEFAULT는 복사된 설정을 기본값으로 재설정합니다.- 각 내부 테이블의
INNER COLUMNS및INNER ENGINE절. 사용자 정의 컬럼(예: 추가 컬럼, 코덱 또는 DEFAULT 표현식이 있는 컬럼)과 사용자 정의 엔진 부분(예: 인수가 있는 엔진, 사용자 정의 정렬 키 또는 엔진 설정)은 유지됩니다. 나머지 컬럼과 엔진 부분은 새 테이블의 설정에 맞게 조정되므로, 예를 들어 문에 작성한tags_to_columns,aggregate_min_time_and_max_time또는tags_index_granularity가 적용됩니다.
id, 타임스탬프 및 값 컬럼의 타입과 내부 엔진의 복제 유형(MergeTree,
ReplicatedMergeTree 또는 SharedMergeTree)도 문에서 직접 선언하지 않는 한 existing_table에서 가져옵니다.
외부 컬럼 목록은 다시 생성되며 복사되지 않습니다.
이전 버전의 ClickHouse에서 생성한 테이블도 existing_table로 사용할 수 있습니다. 새 테이블에는 현재
구조(예: 현재 id 타입 및 기본 식별자 표현식)가 적용됩니다.
컬럼 유형 조정
INNER COLUMNS 절을 사용하면 내부 대상 테이블의 컬럼 유형을 조정할 수 있습니다. 예를 들어, 타임스탬프를 마이크로초 단위로 저장하고 값을 Float32로 저장하려면 다음을 사용합니다:
id 컬럼
id 컬럼에는 식별자가 들어 있으며, 각 식별자는 메트릭 이름과 태그의 조합을 기준으로 계산됩니다.
식별자를 생성하는 데 사용되는 유형과 DEFAULT 표현식은 TAGS INNER COLUMNS 절을 통해 사용자 지정할 수 있습니다:
id 컬럼은 비교 가능한 널 허용이 아닌 모든 타입일 수 있습니다. samples 및 tags 내부 테이블에 선언된 id 타입은 서로 일치해야 합니다.
id 컬럼에 DEFAULT 표현식이 지정되지 않고 id_generator 설정도 지정되지 않은 경우, id 타입이 UUID, UInt64, UInt128, FixedString(16), LowCardinality로 래핑된 동일한 타입 또는 이들 타입 두 개로 이루어진 튜플인 경우에만 ClickHouse가 id 타입에 따라 DEFAULT 표현식을 자동으로 선택합니다. 이러한 튜플에서는 자동으로 선택된 표현식이 첫 번째 구성 요소에서 메트릭 이름의 해시를 계산하고, 두 번째 구성 요소에서 모든 태그의 해시를 계산합니다.
Tuple(UInt64, LowCardinality(UUID))와 같은 LowCardinality 식별자 타입은 식별자가 딕셔너리 인코딩된 상태로 유지합니다. samples 테이블은 모든 행에 전체 식별자를 반복해 저장하는 대신 블록별로 작은 딕셔너리와 딕셔너리 인덱스를 저장하므로 쿼리가 읽는 데이터 양이 줄어듭니다.
id_generator 설정을 사용하면 INNER COLUMNS 절을 사용하지 않고도 동일하게 사용자 지정할 수 있습니다:
DEFAULT에 다른 표현식이 있더라도 id를 생성하는 데 이 설정이 사용됩니다.
id 컬럼의 타입은 INNER COLUMNS 절 대신 id_type 설정으로 지정할 수도 있습니다:
id_generator 설정이 지정되면 CREATE 시점에 id_type 설정이 자동으로 기록되므로,
정의에는 해당 표현식이 작성된 대상 타입이 그대로 유지됩니다.
tags 컬럼
tags 컬럼에는 메트릭 이름이 포함된 __name__ 태그를 비롯하여 시계열의 모든 태그가 포함됩니다.
tags_to_columns 설정을 사용하면 특정 태그를 tags 컬럼 내부의 맵에 저장하는 것 외에도 별도의 컬럼에 저장하도록
지정할 수 있습니다:
instance 및 job 컬럼을 추가합니다.
instance 및 job 태그의 값은 해당 컬럼과 tags 컬럼 모두에 저장됩니다.
이전 버전의 ClickHouse에서 생성된 테이블의
tags 컬럼에는 전용 컬럼에 저장되지 않는 태그만 포함되며 메트릭 이름은 포함되지 않습니다. all_tags 컬럼은 삽입 시
메트릭 이름을 제외한 모든 태그로 채워지는 일시적 컬럼입니다.내부 대상 테이블의 테이블 엔진
기본적으로 내부 대상 테이블에는 다음 테이블 엔진이 사용됩니다.- samples 테이블은 MergeTree를 사용합니다;
- 최근 샘플 테이블은 5시간 버킷으로 파티션된 MergeTree를 사용하며(recent_samples_partition_by 설정 참조), recent_samples_ttl_seconds 설정에서 파생된
TTL과 활성화된ttl_only_drop_parts를 사용하므로 만료된 파트 전체가 삭제됩니다; - tags 테이블은 AggregatingMergeTree를 사용합니다. 이 테이블에는 동일한 데이터가 여러 번 삽입되는 경우가 많으므로
중복을 제거할 방법이 필요하고,
min_time및max_time컬럼에 대해 집계를 수행해야 하기 때문입니다; - 메트릭 패밀리 테이블은 ReplacingMergeTree를 사용합니다. 이 테이블에도 동일한 데이터가 여러 번 삽입되는 경우가 많으므로 중복을 제거할 방법이 필요하기 때문입니다.
default_table_engine 쿼리 수준 설정을 따릅니다.
default_table_engine = ReplicatedMergeTree 또는 SharedMergeTree를 사용하면 내부 테이블은 해당
Replicated 또는 Shared 엔진을 사용합니다. default_table_engine = None(또는 다른 값)을 사용하면 내부 테이블의 엔진을
명시적으로 지정해야 합니다.
모든 내부 테이블은 동일한 복제 유형을 사용해야 합니다. 하나가 복제되었거나 공유된 경우, 다른 내부
테이블도 복제되거나 공유되어야 합니다. 그렇지 않으면 레플리카 간에 내용이 달라집니다. 예를 들어,
SAMPLES INNER ENGINE = ReplicatedMergeTree(...)를 선언하려면 다른 내부 엔진도 복제되어야 합니다.
명시적으로 선언하거나 default_table_engine = ReplicatedMergeTree로 생성해야 합니다.
다음과 같이 지정하면 내부 대상 테이블에 다른 테이블 엔진을 사용할 수도 있습니다:
tags 맵)을 정렬 키(sorting key) 밖에 유지하는데,
이는 AggregatingMergeTree에서 기본적으로 허용하지 않습니다(allow_dimensions_outside_sorting_key 참조).
여기서 이것이 안전한 이유는 해당 컬럼들이 정렬 키의 일부인 id에 함수적으로 종속되어 있으므로, 백그라운드 머지로 함께 축약되는 모든
행이 동일한 값을 공유하기 때문입니다. 위와 같이 내부 tags 테이블이 생성되거나 해당 엔진이 인라인으로 지정되면 TimeSeries는 여기에
allow_dimensions_outside_sorting_key = 1을 자동으로 설정합니다. 수동으로 생성한 외부 집계 tags 테이블은 직접 설정해야 합니다.
외부 대상 테이블
수동으로 생성한 테이블을TimeSeries 테이블에서 사용하게 할 수 있습니다:
RECENT SAMPLES my_recent_samples_table 절)으로도 사용할 수 있습니다.
이러한 테이블은 외부 Samples 테이블과 동일한 컬럼을 가져야 하며, 최소
recent_samples_ttl_seconds초 동안 데이터를 보존해야 합니다. 이는 사용자의 책임입니다.
외부 테이블의 컬럼 타입(id, timestamp, value, 그리고 tags_to_columns에 나열된 <tag_value_column>들)은 TimeSeries 테이블이 내부적으로 생성하는 타입과 일치해야 합니다(타입 제약 조건은 Samples table, Tags 테이블, 메트릭 패밀리 테이블을 참조하십시오). 타입 불일치는 CREATE 시점에 보고됩니다.
외부 Tags 테이블의 id 컬럼 타입과 식별자를 생성하는 표현식은 CREATE 시점에 id_type 및 id_generator 설정에 기록됩니다(version 2부터). 따라서 TimeSeries 테이블의 정의가 이를 유지합니다. 예를 들어 CREATE TABLE ... AS my_table은 외부 대상 테이블을 읽지 않고 my_table의 정의에서 id 타입을 읽습니다. id_generator 설정이 지정되지 않은 경우, 외부 테이블의 id 컬럼에 선언된 DEFAULT(있는 경우)로 설정되며, 없으면 id 타입에서 파생된 정규 생성기로 설정됩니다. 기록된 표현식은 이후 외부 테이블의 DEFAULT가 변경되더라도 id 생성에 사용됩니다 — 자세한 내용은 The id column을 참조하십시오.
설정 변경
CREATE 이후에는 다음 2개의 설정을 변경할 수 있습니다:
id_generatorfilter_by_min_time_and_max_time
id_generator는 데이터가 이미 Tags 테이블에 있는 상태에서 변경하면 동일한 메트릭+태그 조합에 대해 서로 다른 ID가 생성될 수 있습니다. 기존 행은 이전 ID를 유지하고, 새 행은 새 생성기를 사용합니다.
다른 설정은 ALTER ... MODIFY SETTING으로 변경할 수 없습니다. 대부분은 CREATE 시점에 내부 테이블의 스키마에 반영되며, version 설정은 CREATE 시점에 자동으로 고정되어 스키마 자체를 식별합니다(스키마 버전 관리 참조).
설정
다음은TimeSeries 테이블을 정의할 때 지정할 수 있는 설정 목록입니다.
스키마 버전 관리
TimeSeries 테이블 엔진과 PromQL 실행 계층은 활발히 개발이 진행 중입니다.
대상 테이블의 집합과 그 구조는 ClickHouse 버전에 따라 달라질 수 있습니다.
이러한 변경을 감지할 수 있도록, 모든 TimeSeries 테이블은 자신의 버전을 version 설정에 저장합니다.
버전은 테이블이 생성될 때 CREATE 쿼리에 자동으로 고정되며(그 값은 서버가 알고 있는 최신 버전, 현재는 5입니다),
테이블 메타데이터에 유지되고 ALTER로 변경할 수 없습니다. 이 설정이 도입되기 전에 생성된 테이블은 버전 0으로 간주됩니다.
일반적으로 이 설정은 CREATE TABLE 쿼리에서 생략하면 되며, 그러면 테이블은 최신 버전을 갖게 됩니다.
서버가 해당 버전을 지원한다면 version을 명시적으로 지정할 수도 있습니다. 이 경우 테이블은 해당 버전의 방식대로 정의됩니다(버전 이력 참고).
CREATE TABLE ... AS other_table은 다른 테이블의 버전을 복사하지 않습니다. 기존 테이블을 AS로 사용하여 테이블 생성을 참고하십시오.
서버는 일정 범위의 버전을 지원하며, 최소 버전은 SELECT로 읽는 경우, INSERT 또는 Prometheus remote-write 프로토콜로 쓰는 경우,
PromQL을 평가하는 경우(prometheusQuery,
prometheusQueryRange,
timeSeriesSelector 테이블 함수,
promql 방언, Prometheus HTTP 쿼리 API)에 따라 각각 다를 수 있습니다:
TimeSeries테이블의 버전이 PromQL을 사용하기에 너무 오래된 경우, 해당 테이블에 대한 PromQL 쿼리는 거부됩니다. 이때 발생하는 예외는 테이블을 다시 생성하도록 안내합니다. 즉, 새TimeSeries테이블을 생성하고INSERT ... SELECT쿼리로 데이터를 복사한 뒤, 기존 테이블을 새 테이블으로 대체하십시오.- 버전이 쓰기를 지원하기에 너무 오래된 경우,
INSERT쿼리와 Prometheus remote-write 프로토콜은 거부되지만SELECT쿼리는 계속 동작합니다. - 버전이 서버에서 아예 지원되지 않을 정도로 오래된 경우, 해당 테이블에 대한 모든 쿼리(
SHOW CREATE TABLE,DETACH,DROP제외)가 거부됩니다.
버전 이력
함수
다음은TimeSeries 테이블을 인수로 지원하는 함수 목록입니다.