본문으로 바로가기
본문으로 바로가기

avgMergeState

설명

MergeState 조합자는 avg 함수에 적용해 AverageFunction(avg, T) 타입의 부분 집계 상태를 병합하고 새로운 중간 집계 상태를 반환합니다.

사용 예시

MergeState 조합기는 다단계 집계 시나리오에서 특히 유용합니다. 사전 집계된 상태를 결합하고, 이후 처리를 위해 이를 (최종 결과로 확정하지 않고) 상태로 유지해야 할 때 적합합니다. 이를 설명하기 위해, 개별 서버 성능 메트릭을 여러 수준에 걸친 계층적 집계로 변환하는 예시를 살펴보겠습니다: 서버 수준 → 리전 수준 → 데이터센터 수준.

먼저 원시 데이터를 저장할 테이블을 생성합니다:

CREATE TABLE raw_server_metrics
(
    timestamp DateTime DEFAULT now(),
    server_id UInt32,
    region String,
    datacenter String,
    response_time_ms UInt32
)
ENGINE = MergeTree()
ORDER BY (region, server_id, timestamp);

서버 수준 집계 대상 테이블을 생성하고, 해당 테이블에 대한 INSERT 시 트리거처럼 동작하는 증분 materialized view를 정의합니다:

CREATE TABLE server_performance
(
    server_id UInt32,
    region String,
    datacenter String,
    avg_response_time AggregateFunction(avg, UInt32)
)
ENGINE = AggregatingMergeTree()
ORDER BY (region, server_id);

CREATE MATERIALIZED VIEW server_performance_mv
TO server_performance
AS SELECT
    server_id,
    region,
    datacenter,
    avgState(response_time_ms) AS avg_response_time
FROM raw_server_metrics
GROUP BY server_id, region, datacenter;

지역 및 데이터 센터 수준에 대해서도 동일한 작업을 수행합니다:

CREATE TABLE region_performance
(
    region String,
    datacenter String,
    avg_response_time AggregateFunction(avg, UInt32)
)
ENGINE = AggregatingMergeTree()
ORDER BY (datacenter, region);

CREATE MATERIALIZED VIEW region_performance_mv
TO region_performance
AS SELECT
    region,
    datacenter,
    avgMergeState(avg_response_time) AS avg_response_time
FROM server_performance
GROUP BY region, datacenter;

-- datacenter level table and materialized view

CREATE TABLE datacenter_performance
(
    datacenter String,
    avg_response_time AggregateFunction(avg, UInt32)
)
ENGINE = AggregatingMergeTree()
ORDER BY datacenter;

CREATE MATERIALIZED VIEW datacenter_performance_mv
TO datacenter_performance
AS SELECT
      datacenter,
      avgMergeState(avg_response_time) AS avg_response_time
FROM region_performance
GROUP BY datacenter;

이제 소스 테이블에 샘플 원시 데이터를 삽입합니다.

INSERT INTO raw_server_metrics (timestamp, server_id, region, datacenter, response_time_ms) VALUES
    (now(), 101, 'us-east', 'dc1', 120),
    (now(), 101, 'us-east', 'dc1', 130),
    (now(), 102, 'us-east', 'dc1', 115),
    (now(), 201, 'us-west', 'dc1', 95),
    (now(), 202, 'us-west', 'dc1', 105),
    (now(), 301, 'eu-central', 'dc2', 145),
    (now(), 302, 'eu-central', 'dc2', 155);

각 레벨에 대해 세 개의 쿼리를 작성합니다.

SELECT
    server_id,
    region,
    avgMerge(avg_response_time) AS avg_response_ms
FROM server_performance
GROUP BY server_id, region
ORDER BY region, server_id;
┌─server_id─┬─region─────┬─avg_response_ms─┐
│       301 │ eu-central │             145 │
│       302 │ eu-central │             155 │
│       101 │ us-east    │             125 │
│       102 │ us-east    │             115 │
│       201 │ us-west    │              95 │
│       202 │ us-west    │             105 │
└───────────┴────────────┴─────────────────┘

더 많은 데이터를 삽입해 보겠습니다:

INSERT INTO raw_server_metrics (timestamp, server_id, region, datacenter, response_time_ms) VALUES
    (now(), 101, 'us-east', 'dc1', 140),
    (now(), 201, 'us-west', 'dc1', 85),
    (now(), 301, 'eu-central', 'dc2', 135);

데이터센터 수준의 성능을 다시 한 번 확인해 보겠습니다. 전체 집계 체인이 자동으로 업데이트된 점에 주목하십시오.

SELECT
    datacenter,
    avgMerge(avg_response_time) AS avg_response_ms
FROM datacenter_performance
GROUP BY datacenter
ORDER BY datacenter;
┌─datacenter─┬────avg_response_ms─┐
│ dc1        │ 112.85714285714286 │
│ dc2        │                145 │
└────────────┴────────────────────┘

참고