Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

TimeSeries 테이블 엔진

실험 기능
ClickHouse Cloud에서 지원되지 않음

시계열, 즉 타임스탬프와 태그(또는 레이블)에 연결된 값 집합을 저장하는 테이블 엔진입니다:

metric_name1[tag1=value1, tag2=value2, ...] = {timestamp1: value1, timestamp2: value2, ...}
metric_name2[...] = ...

구문

CREATE TABLE name [(columns)] ENGINE=TimeSeries
[SETTINGS var1=value1, ...]
[SAMPLES db.samples_table_name | [SAMPLES INNER COLUMNS (...)] [SAMPLES INNER ENGINE engine(arguments)]]
[TAGS db.tags_table_name | [TAGS INNER COLUMNS (...)] [TAGS INNER ENGINE engine(arguments)]]
[METRICS db.metrics_table_name | [METRICS INNER COLUMNS (...)] [METRICS INNER ENGINE engine(arguments)]]

사용법

기본 설정을 그대로 사용해 시작하는 편이 더 쉽습니다 (TimeSeries 테이블은 컬럼 목록을 지정하지 않고도 생성할 수 있습니다):

CREATE TABLE my_table ENGINE=TimeSeries

그러면 이 테이블을 다음 프로토콜과 함께 사용할 수 있습니다(포트는 서버 구성에서 할당해야 합니다):

외부 컬럼

TimeSeries 테이블의 컬럼은 자동으로 생성됩니다. 이러한 컬럼을 외부 컬럼이라고 하며, 데이터는 저장하지 않고 SELECT/INSERT를 위한 인터페이스만 제공합니다. 실제 데이터는 대상 테이블에 저장됩니다. 다음은 외부 컬럼 목록입니다:

Name Type Description
metric_name String 메트릭 이름
tags Map(String, String) 시계열의 tags(labels) 맵
time_series Array(Tuple(DateTime64(3), Float64))가 기본값 시계열에 대한 (timestamp, value) 쌍의 배열입니다. 튜플의 timestamp 및 스칼라 요소 타입은 샘플 INNER COLUMNS 선언에서 유추할 수 있습니다(외부 컬럼 지정 참고).
metric_family String 메트릭 패밀리 이름(메트릭 메타데이터용)
type String 메트릭 유형(예: "counter", "gauge")
unit String 메트릭 단위
help String 메트릭 설명

예시:

INSERT INTO my_table (metric_name, tags, time_series) VALUES
    ('cpu_usage', {'job': 'node_exporter', 'instance': 'host1:9100'},
     [(toDateTime64('2024-01-01 00:00:00', 3), 0.5), (toDateTime64('2024-01-01 00:01:00', 3), 0.7)])

삽입 시 metric_name은 비워 둘 수 있으며, 이는 메트릭 이름이 tags__name__에 지정된다는 의미입니다. 예시는 다음과 같습니다:

INSERT INTO my_table (tags, time_series) VALUES
    ({'__name__': 'cpu_usage', 'job': 'test'},
     [(toDateTime64('2024-01-01 00:00:00', 3), 0.5)])

메트릭 메타데이터를 삽입하려면 metric_family, type, unit, help 컬럼에 값을 삽입합니다:

INSERT INTO my_table (metric_name, tags, time_series, metric_family, type, unit, help) VALUES
    ('http_requests_total', {'method': 'GET'}, [(now64(), 100.0)],
     'http_requests_total', 'counter', 'requests', 'Total HTTP requests')

외부 컬럼 지정

외부 time_series 컬럼은 CREATE TABLE 문에서 명시적으로 나열해 기본 Array(Tuple(DateTime64(3), Float64)) 유형을 재정의할 수 있습니다. ClickHouse는 튜플에서 타임스탬프와 스칼라 유형을 추출해 내부 samples table에 반영합니다:

CREATE TABLE my_table (time_series Array(Tuple(UInt32, Float32))) ENGINE=TimeSeries

이는 samples INNER COLUMNS 절에서 timestamp 및 value 컬럼의 유형을 직접 선언하는 것과 동일합니다:

CREATE TABLE my_table ENGINE=TimeSeries
SAMPLES INNER COLUMNS (timestamp UInt32 CODEC(DoubleDelta, ZSTD(1)), value Float32 CODEC(ZSTD(3)))

두 형식을 모두 같은 CREATE TABLE 문에서 사용하는 경우, 선언된 유형이 일치해야 합니다.

대상 테이블

TimeSeries 테이블은 자체 데이터를 갖지 않으며, 모든 데이터는 대상 테이블에 저장됩니다. 이는 materialized view의 동작 방식과 비슷하지만, materialized view는 대상 테이블이 하나인 반면 TimeSeries 테이블에는 samples, tags, 메트릭라는 세 개의 대상 테이블이 있습니다.

대상 테이블은 CREATE TABLE 쿼리에서 명시적으로 지정할 수도 있고 TimeSeries 테이블 엔진이 내부 대상 테이블을 자동으로 생성할 수도 있습니다.

TimeSeries 테이블에 삽입된 행은 변환되고 블록으로 분할된 후, 이 3개의 대상 테이블에 삽입됩니다.

대상 테이블은 다음과 같습니다:

Samples table

samples 테이블에는 특정 식별자에 연결된 시계열이 포함됩니다.

samples 테이블에는 다음 컬럼이 있어야 합니다:

이름 필수? 기본 타입 가능한 타입 설명
id [x] Tuple(UInt64, UUID) 모든 타입 메트릭 이름과 태그 조합을 식별합니다
timestamp [x] DateTime64(3) DateTime64(X) 시점
value [x] Float64 Float32 또는 Float64 timestamp에 연결된 값

엔진이 자체적으로 생성하는 컬럼에는 시계열 압축 코덱이 적용됩니다: timestamp CODEC(DoubleDelta, ZSTD(1))value CODEC(ZSTD(3))입니다. 거의 단조로운 타임스탬프는 일반 코덱으로는 거의 압축되지 않으며, 그렇지 않으면 samples 테이블의 디스크상 크기에서 큰 비중을 차지할 수 있습니다. 컬럼 타입 조정도 참조하십시오.

Tags 테이블

tags 테이블에는 메트릭 이름과 태그의 각 조합별로 계산된 식별자가 포함됩니다.

tags 테이블에는 다음 컬럼이 있어야 합니다:

Name Mandatory? 기본 타입 가능한 타입 설명
id [x] Tuple(UInt64, UUID) any (must match the type of id in the samples table) id는 메트릭 이름과 태그의 조합을 식별합니다. DEFAULT 표현식은 이러한 식별자를 계산하는 방법을 지정합니다
metric_name [x] LowCardinality(String) String or LowCardinality(String) 메트릭 이름
<tag_value_column> [ ] String String or LowCardinality(String) or LowCardinality(Nullable(String)) 특정 태그의 값입니다. 태그 이름과 해당 컬럼 이름은 tags_to_columns 설정에서 지정합니다
tags [x] Map(LowCardinality(String), String) Map(String, String) or Map(LowCardinality(String), String) or Map(LowCardinality(String), LowCardinality(String)) 메트릭 이름을 담는 태그 __name__tags_to_columns 설정에 나열된 이름의 태그를 포함한 모든 태그의 맵입니다. 이전 버전의 ClickHouse에서 생성된 테이블은 이 컬럼에 전용 컬럼이 없는 태그만 저장했으며 메트릭 이름은 저장하지 않았습니다. 읽기 시 두 경우를 모두 처리합니다
min_time [ ] Nullable(DateTime64(3)) DateTime64(X) or Nullable(DateTime64(X)) 해당 id를 가진 시계열의 최소 타임스탬프입니다. store_min_time_and_max_timetrue이면 이 컬럼이 생성됩니다
max_time [ ] Nullable(DateTime64(3)) DateTime64(X) or Nullable(DateTime64(X)) 해당 id를 가진 시계열의 최대 타임스탬프입니다. store_min_time_and_max_timetrue이면 이 컬럼이 생성됩니다

Metrics 테이블

metrics 테이블에는 수집된 메트릭, 해당 메트릭의 타입, 그리고 설명에 대한 정보가 포함됩니다.

metrics 테이블에는 다음 컬럼이 있어야 합니다:

Name Mandatory? Default type Possible types Description
metric_family_name [x] String String or LowCardinality(String) 메트릭 패밀리의 이름
type [x] LowCardinality(String) String or LowCardinality(String) 메트릭 패밀리의 타입으로, "counter", "gauge", "summary", "stateset", "histogram", "gaugehistogram" 중 하나입니다
unit [x] LowCardinality(String) String or LowCardinality(String) 메트릭에 사용되는 단위
help [x] String String or LowCardinality(String) 메트릭 설명

생성

TimeSeries 테이블 엔진으로 테이블을 생성하는 방법은 여러 가지가 있습니다. 가장 간단한 SQL 문은

CREATE TABLE my_table ENGINE=TimeSeries

실제로는 다음과 같은 테이블이 생성됩니다(SHOW CREATE TABLE my_table을 실행하면 이를 확인할 수 있습니다):

CREATE TABLE my_table
(
    `metric_name` String,
    `tags` Map(String, String),
    `time_series` Array(Tuple(DateTime64(3), Float64)),
    `metric_family` String,
    `type` String,
    `unit` String,
    `help` String
)
ENGINE = TimeSeries
SAMPLES INNER COLUMNS
(
    `id` Tuple(UInt64, UUID),
    `timestamp` DateTime64(3) CODEC(DoubleDelta, ZSTD(1)),
    `value` Float64 CODEC(ZSTD(3))
)
SAMPLES INNER ENGINE = MergeTree ORDER BY (id, timestamp) SETTINGS index_granularity = 32768
TAGS INNER COLUMNS
(
    `id` Tuple(UInt64, UUID) DEFAULT tuple(sipHash64(metric_name), reinterpretAsUUID(sipHash128(tags))),
    `metric_name` LowCardinality(String),
    `tags` Map(LowCardinality(String), String),
    `min_time` SimpleAggregateFunction(min, Nullable(DateTime64(3))),
    `max_time` SimpleAggregateFunction(max, Nullable(DateTime64(3)))
)
TAGS INNER ENGINE = AggregatingMergeTree PRIMARY KEY metric_name ORDER BY (metric_name, id) SETTINGS allow_dimensions_outside_sorting_key = 1, index_granularity = 8192
METRICS INNER COLUMNS
(
    `metric_family_name` String,
    `type` LowCardinality(String),
    `unit` LowCardinality(String),
    `help` String
)
METRICS INNER ENGINE = ReplacingMergeTree ORDER BY metric_family_name

따라서 컬럼은 자동으로 생성되었으며, INNER COLUMNS 절에는 각 내부 대상 테이블의 자체 컬럼 정의도 3개 저장됩니다.

내부 대상 테이블의 이름은 .inner_id.samples.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, .inner_id.tags.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, .inner_id.metrics.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 와 같으며, 각 대상 테이블에는 고유한 컬럼 집합이 있습니다:

CREATE TABLE default.`.inner_id.samples.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`
(
    `id` Tuple(UInt64, UUID),
    `timestamp` DateTime64(3) CODEC(DoubleDelta, ZSTD(1)),
    `value` Float64 CODEC(ZSTD(3))
)
ENGINE = MergeTree
ORDER BY (id, timestamp)
SETTINGS index_granularity = 32768
CREATE TABLE default.`.inner_id.tags.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`
(
    `id` Tuple(UInt64, UUID) DEFAULT tuple(sipHash64(metric_name), reinterpretAsUUID(sipHash128(tags))),
    `metric_name` LowCardinality(String),
    `tags` Map(LowCardinality(String), String),
    `min_time` SimpleAggregateFunction(min, Nullable(DateTime64(3))),
    `max_time` SimpleAggregateFunction(max, Nullable(DateTime64(3)))
)
ENGINE = AggregatingMergeTree
PRIMARY KEY metric_name
ORDER BY (metric_name, id)
SETTINGS allow_dimensions_outside_sorting_key = 1, index_granularity = 8192
CREATE TABLE default.`.inner_id.metrics.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`
(
    `metric_family_name` String,
    `type` LowCardinality(String),
    `unit` LowCardinality(String),
    `help` String
)
ENGINE = ReplacingMergeTree
ORDER BY metric_family_name
SETTINGS index_granularity = 8192

기존 테이블을 AS로 지정해 테이블 생성하기

CREATE TABLE new_table AS existing_table 문은 existing_table에서 다음 항목을 복사합니다:

  • SETTINGS
  • 각 kind별 INNER COLUMNS
  • 각 kind별 INNER ENGINE

existing_table에 외부 대상이 있으면 이 문은 허용되지 않습니다. 외부 컬럼 목록은 복사되지 않으며 다시 생성됩니다.

컬럼 유형 조정

INNER COLUMNS 절을 사용하면 내부 대상 테이블의 컬럼 유형을 조정할 수 있습니다. 예를 들어, 타임스탬프를 마이크로초 단위로 저장하고 값을 Float32로 저장하려면 다음을 사용합니다:

CREATE TABLE my_table ENGINE=TimeSeries
SAMPLES INNER COLUMNS (timestamp DateTime64(6) CODEC(DoubleDelta, ZSTD(1)), value Float32 CODEC(ZSTD(3)))

내부 컬럼을 코덱 없이 지정하면 기본 코덱이 사용됩니다:

CREATE TABLE my_table ENGINE=TimeSeries
SAMPLES INNER COLUMNS (timestamp DateTime64(6), value Float32)

id 컬럼

id 컬럼에는 식별자가 들어 있으며, 각 식별자는 메트릭 이름과 태그의 조합을 기준으로 계산됩니다. 식별자를 생성하는 데 사용되는 유형과 DEFAULT 표현식은 TAGS INNER COLUMNS 절을 통해 사용자 지정할 수 있습니다:

CREATE TABLE my_table ENGINE=TimeSeries
TAGS INNER COLUMNS (id UInt64 DEFAULT sipHash64(tags))

id 컬럼은 비교 가능한 널 허용이 아닌 모든 타입일 수 있습니다. samples 및 tags 내부 테이블에 선언된 id 타입은 서로 일치해야 합니다.

id 컬럼에 DEFAULT 표현식이 지정되지 않고 id_generator 설정도 지정되지 않은 경우, id 타입이 UUID, UInt64, UInt128, FixedString(16) 또는 이들 타입 두 개로 이루어진 튜플인 경우에만 ClickHouse가 id 타입에 따라 DEFAULT 표현식을 자동으로 선택합니다. 이러한 튜플에서는 자동으로 선택된 표현식이 첫 번째 구성 요소에서 메트릭 이름의 해시를 계산하고, 두 번째 구성 요소에서 모든 태그의 해시를 계산합니다.

id_generator 설정을 사용하면 INNER COLUMNS 절을 사용하지 않고도 동일하게 사용자 지정할 수 있습니다:

CREATE TABLE my_table ENGINE=TimeSeries
SETTINGS id_generator = 'sipHash64(tags)'

이 설정이 지정되면, 컬럼의 DEFAULT에 다른 표현식이 있더라도 id를 생성하는 데 이 설정이 사용됩니다.

tags 컬럼

tags 컬럼에는 메트릭 이름이 포함된 __name__ 태그를 비롯하여 시계열의 모든 태그가 포함됩니다.

tags_to_columns 설정을 사용하면 특정 태그를 tags 컬럼 내부의 맵에 저장하는 것 외에도 별도의 컬럼에 저장하도록 지정할 수 있습니다:

CREATE TABLE my_table
ENGINE = TimeSeries
SETTINGS tags_to_columns = {'instance': 'instance', 'job': 'job'}

이 SQL 문은 내부 tags 대상 테이블에 instancejob 컬럼을 추가합니다. instancejob 태그의 값은 해당 컬럼과 tags 컬럼 모두에 저장됩니다.

내부 대상 테이블의 테이블 엔진

기본적으로 내부 대상 테이블에는 다음 테이블 엔진이 사용됩니다.

  • samples 테이블은 MergeTree를 사용합니다;
  • tags 테이블은 AggregatingMergeTree를 사용합니다. 이 테이블에는 동일한 데이터가 여러 번 삽입되는 경우가 많으므로 중복을 제거할 방법이 필요하고, min_timemax_time 컬럼에 대해 집계를 수행해야 하기 때문입니다;
  • 메트릭 테이블은 ReplacingMergeTree를 사용합니다. 이 테이블에도 동일한 데이터가 여러 번 삽입되는 경우가 많으므로 중복을 제거할 방법이 필요하기 때문입니다.

다음과 같이 지정하면 내부 대상 테이블에 다른 테이블 엔진을 사용할 수도 있습니다:

CREATE TABLE my_table ENGINE=TimeSeries
SAMPLES ENGINE=ReplicatedMergeTree
TAGS ENGINE=ReplicatedAggregatingMergeTree
METRICS ENGINE=ReplicatedReplacingMergeTree

tags 테이블은 태그 컬럼(및 tags 맵)을 정렬 키(sorting key) 밖에 유지하는데, 이는 AggregatingMergeTree에서 기본적으로 허용하지 않습니다(allow_dimensions_outside_sorting_key 참조). 여기서 이것이 안전한 이유는 해당 컬럼들이 정렬 키의 일부인 id에 함수적으로 종속되어 있으므로, 백그라운드 머지로 함께 축약되는 모든 행이 동일한 값을 공유하기 때문입니다. 위와 같이 내부 tags 테이블이 생성되거나 해당 엔진이 인라인으로 지정되면 TimeSeries는 여기에 allow_dimensions_outside_sorting_key = 1을 자동으로 설정합니다. 수동으로 생성한 외부 집계 tags 테이블은 직접 설정해야 합니다.

외부 대상 테이블

수동으로 생성한 테이블을 TimeSeries 테이블에서 사용하게 할 수 있습니다:

CREATE TABLE samples_for_my_table
(
    `id` UUID,
    `timestamp` DateTime64(3),
    `value` Float64
)
ENGINE = MergeTree
ORDER BY (id, timestamp);

CREATE TABLE tags_for_my_table ...

CREATE TABLE metrics_for_my_table ...

CREATE TABLE my_table ENGINE=TimeSeries SAMPLES samples_for_my_table TAGS tags_for_my_table METRICS metrics_for_my_table;

외부 테이블의 컬럼 타입(id, timestamp, value, 그리고 tags_to_columns에 나열된 <tag_value_column>들)은 TimeSeries 테이블이 내부적으로 생성하는 타입과 일치해야 합니다(타입 제약 조건은 Samples table, Tags 테이블, Metrics 테이블을 참조하십시오). 타입 불일치는 CREATE 시점에 보고됩니다.

외부 Tags 대상의 id 생성기 표현식은 INSERT 시점에 다음 순서대로 결정됩니다: 먼저 id_generator 설정(설정된 경우), 다음으로 외부 테이블의 id 컬럼에 선언된 DEFAULT(있는 경우), 마지막으로 id 타입에서 파생된 표준 생성기입니다. 따라서 이 설정은 외부 테이블에 선언된 DEFAULT를 재정의합니다 — 자세한 내용은 The id column을 참조하십시오.

설정 변경

CREATE 이후에는 다음 2개의 설정을 변경할 수 있습니다:

  • id_generator
  • filter_by_min_time_and_max_time
ALTER TABLE my_table MODIFY SETTING id_generator = 'sipHash64(tags)';
ALTER TABLE my_table MODIFY SETTING filter_by_min_time_and_max_time = 0;

id_generator는 데이터가 이미 Tags 테이블에 있는 상태에서 변경하면 동일한 메트릭+태그 조합에 대해 서로 다른 ID가 생성될 수 있습니다. 기존 행은 이전 ID를 유지하고, 새 행은 새 생성기를 사용합니다.

다른 설정은 CREATE 시점에 내부 테이블의 스키마에 반영되므로 ALTER ... MODIFY SETTING으로는 변경할 수 없습니다.

설정

다음은 TimeSeries 테이블을 정의할 때 지정할 수 있는 설정 목록입니다.

이름 유형 기본값 설명
id_generator 표현식 id 유형에 따라 다름 태그로부터 시계열의 식별자(지문)를 계산하는 표현식입니다. 설정하지 않으면 id 컬럼의 기본 표현식이 사용됩니다. id 컬럼의 기본 표현식도 설정되지 않은 경우 표현식이 자동으로 선택됩니다
tags_to_columns tags 테이블에서 어떤 태그를 별도의 컬럼으로 저장할지 지정하는 맵입니다. 구문: {'tag1': 'column1', 'tag2' : column2, ...}
use_all_tags_column_to_generate_id Bool false 더 이상 사용되지 않는 설정이며 아무 작업도 수행하지 않습니다
store_min_time_and_max_time Bool true true로 설정하면 테이블은 각 시계열에 대해 min_timemax_time을 저장합니다
aggregate_min_time_and_max_time Bool true 내부 대상 tags 테이블을 생성할 때, 이 플래그를 사용하면 min_time 컬럼의 유형으로 단순한 Nullable(DateTime64(3)) 대신 SimpleAggregateFunction(min, Nullable(DateTime64(3)))를 사용합니다. max_time 컬럼도 동일합니다
filter_by_min_time_and_max_time Bool true true로 설정하면 테이블은 시계열을 필터링할 때 min_timemax_time 컬럼을 사용합니다
samples_index_granularity UInt64 32768 내부 samples 테이블의 index_granularity를 설정합니다. 명시적으로 설정하면 엔진 선언의 index_granularity를 재정의합니다. 외부 samples 테이블 및 MergeTree가 아닌 엔진에서는 무시됩니다
tags_index_granularity UInt64 8192 내부 tags 테이블의 index_granularity를 설정합니다. 명시적으로 설정하면 엔진 선언의 index_granularity를 재정의합니다. 외부 tags 테이블 및 MergeTree가 아닌 엔진에서는 무시됩니다
recent_samples_ttl_seconds UInt64 345600 추가 recent samples 대상 테이블의 보존 기간입니다. 삽입되는 모든 샘플은 이 테이블에도 기록됩니다. 내부 recent samples 테이블에는 항상 이 설정에서 파생된 TTL toDateTime(timestamp) + toIntervalSecond(recent_samples_ttl_seconds)이 적용됩니다(엔진 선언의 TTL을 재정의함). 외부 recent samples 테이블은 최소한 이 설정값만큼의 초 동안 데이터를 보존해야 합니다. 시간 범위가 TTL 윈도우에 포함되는 쿼리는 기본 samples 테이블보다 recent samples 테이블을 우선합니다(쿼리 수준 설정 time_series_prefer_recent_samples_table 참조). 기본값은 4일이며, 유효 값은 CREATE 시 테이블 정의에 고정됩니다. recent samples 테이블을 비활성화하려면 0으로 설정하십시오
recent_samples_partition_by 표현식 toStartOfInterval(toDateTime(timestamp), toIntervalHour(5)) 내부 recent samples 테이블의 파티션 키입니다. 예: toStartOfHour(timestamp). recent_samples_ttl_seconds가 0이 아니어야 합니다
recent_samples_index_granularity UInt64 8192 내부 recent samples 테이블의 index_granularity를 설정합니다. recent_samples_ttl_seconds가 0이 아니어야 합니다

함수

다음은 TimeSeries 테이블을 인수로 지원하는 함수 목록입니다.

Navigation