사전 시계열
개념

시계열

gabury1고친 사람 github-actions[bot]

시계열은 한 대상이 시간에 따라 어떻게 달라졌는지를 보여 줍니다. 같은 것을 거듭 재서 잰 시각과 값을 짝지어 이어 붙인 것입니다. 서버 한 대의 메모리 사용량을 15초마다 잰 기록이 그런 줄 하나입니다. 값 하나만 보아서는 알 수 없는 것을 이 줄에서 읽습니다.

쉽고 빠른 이해

무슨 일을 하는 물건인가 — 같은 대상을 거듭 재서 시간 순으로 이어 둔 값의 줄입니다. 서버 한 대의 메모리 사용량을 15초마다 재서 쌓아 둔 기록이 그런 줄 하나입니다.

왜 이렇게 하나 — 지금 값 하나만 들고는 그 값이 이상한지 아닌지 알 수 없습니다. 어제 이 시각에는 얼마였는지 견줄 것이 있어야 판단이 섭니다.

어떻게 도나

  1. 재는 쪽이 잰 시각과 값을 한 쌍으로 묶어 보냅니다
  2. 저장소가 그 쌍이 어느 줄의 것인지 갈라 끝에 덧붙입니다
  3. 읽는 쪽이 시간 범위를 주고 그 구간의 쌍들을 받아 갑니다

언제 쓰나 — 값이 시간에 따라 어떻게 달라지는지를 볼 때 씁니다. 요청 하나가 왜 실패했는지 같은 사건의 사연은 로그가 받습니다.

대가 — 서버별로 나누고 다시 요청 종류별로 나누면 줄은 대수 × 종류만큼 생깁니다. 저장소를 먼저 무겁게 하는 것은 쌓인 값의 개수가 아니라 이 줄의 개수입니다.

상세

아침마다 몸무게를 재서 공책에 날짜와 함께 적어 둔다고 해 봅시다. 오늘 숫자 하나만 보면 많은지 적은지 알기 어렵지만, 한 달 치를 이어 보면 늘고 있는지 줄고 있는지가 드러납니다.

시계열 한 줄에 담기는 것은 시간이 지나며 달라지는 수치입니다. 사건 하나하나의 사연은 여기 안 담깁니다. 요청 하나가 왜 실패했는지는 로그가 받습니다. 시계열은 그런 요청이 분당 몇 건이었는지를 받습니다.

시각과 값의 한 쌍

시계열을 이루는 알갱이는 잰 시각과 그때의 값을 묶은 한 쌍입니다. 시각은 타임스탬프로 적습니다. 타임스탬프는 어느 순간을 기계가 견줄 수 있는 수로 적어 둔 값입니다.

쌍 하나만으로는 할 수 있는 일이 없습니다. 같은 대상에서 나온 쌍을 시각 순으로 이어 놓아야 시계열이 됩니다.

아래는 서버 한 대의 메모리 사용량을 퍼센트로 15초마다 잰 것입니다.

잰 시각      메모리 사용량(%)
10:00:00     12.5
10:00:15     13.1
10:00:30     13.9
10:00:45     13.4

왼쪽이 잰 시각이고 오른쪽이 그때의 값입니다. 네 쌍이 따로 노는 것이 아니라 한 줄기로 묶여 있다는 것, 그것이 시계열입니다.

한 줄을 가르는 이름과 레이블

줄에는 이름이 붙습니다. 서버가 제대로 돌고 있는지 계속 지켜보는 일이 모니터링입니다. 시계열이 제일 많이 쌓이는 데가 이 모니터링입니다.

모니터링에서 재서 쌓는 수치를 메트릭이라고 부릅니다. 그 메트릭의 이름이 곧 줄 이름입니다.

이름만으로는 줄이 안 갈립니다. 서버 열 대에서 온 요청 수가 「요청 수」라는 같은 이름을 달고 한 줄에 뒤섞입니다. 이름에 레이블을 덧붙여 신원을 만듭니다. 레이블은 대상에 달아 두는 키와 값 한 쌍짜리 이름표입니다.

이름과 레이블 조합이 같으면 같은 줄입니다. 하나라도 다르면 다른 줄입니다. 어느 서버에서 왔는지를 host 로, 어떤 종류의 요청인지를 method 로 가른다고 해 봅시다. 이 둘이 레이블 키입니다.

flowchart TD
    L0["이름만 있을 때 · 요청 수 · 1줄"]
    L0 -->|"host 값 둘로 가르면"| L1G
    subgraph L1G["host 까지 붙인 신원 · 2줄"]
        H1["host=web1"]
        H2["host=web2"]
    end
    L1G -->|"method 값 셋으로 더 가르면"| L2G
    subgraph L2G["method 까지 붙인 신원 · 6줄"]
        M1["web1 · get"]
        M2["web1 · post"]
        M3["web1 · delete"]
        M4["web2 · get"]
        M5["web2 · post"]
        M6["web2 · delete"]
    end

그림에서 이름은 하나인데 host 값 둘로 두 줄이 되고, 거기에 method 값 셋을 더하니 여섯 줄이 됩니다. 둘과 셋을 더하면 다섯이지만 줄은 여섯입니다. 레이블 키를 하나 더 붙이면 줄의 수는 그 키가 갖는 값의 가짓수만큼 곱해집니다.

값의 가짓수가 몇이나 되는지를 카디널리티라고 부릅니다.

이 곱셈이 감당 못 할 만큼 커지면 카디널리티가 터졌다고 말합니다.

레이블에는 값이 몇 가지 안 되는 것만 붙입니다. 사용자 번호나 요청 번호처럼 값이 끝없이 늘어나는 것을 붙이면 줄이 그만큼 늘어납니다. 쌓인 값의 개수가 아니라 줄의 개수 자체가 메모리와 디스크를 잡아먹습니다.

끝에만 덧붙는 기록

시계열은 지난 값을 고쳐 쓰지 않습니다. 새 값이 나오면 줄의 끝에 붙일 뿐입니다. 가운데를 고치는 일이 없으니 저장소는 끝에 붙이는 일만 잘 하도록 만들면 됩니다. 이런 성질에 맞춰 만든 저장소가 시계열 데이터베이스입니다.

지난 값을 안 고치는 데는 까닭이 있습니다. 「언제부터 달라졌나」를 읽으려고 쌓는 기록입니다. 지난 값이 나중에 바뀌면 그 물음에 답할 수 없습니다.

한쪽 끝으로만 자라니 지우는 일도 반대쪽 끝에서 일어납니다. 오래된 구간부터 잘라 내면 용량이 정리됩니다. 얼마나 지난 것까지 들고 있을지 정해 둔 것이 보존 기간입니다.

재는 간격과 성기게 만들기

간격을 좁혀 자주 재면 짧게 튄 변화까지 잡히지만 쌓이는 쌍의 수가 그만큼 늘어납니다. 간격을 넓히면 저장은 줄고 그 사이에 벌어진 일은 기록에 안 남습니다. 이 간격을 수집 주기라고 부릅니다.

두 요구를 한꺼번에 맞추기 어려우니 구간에 따라 다르게 다룹니다. 최근 구간은 촘촘히 두고, 오래된 구간은 여러 쌍을 하나로 요약해 성기게 바꿉니다. 다운샘플링은 이렇게 성기게 바꾸는 일입니다.

요약하고 나면 원래 쌍들은 버립니다. 그래서 오래된 구간에서는 순간적으로 튄 값을 다시 볼 수 없습니다. 최근 것은 자세히 보고 옛것은 흐름만 본다는 거래입니다.

한 줄의 수명을 구간으로 늘어놓으면 이렇게 됩니다.

block-beta
columns 3
  a["잘려 나간 구간"] b["성긴 옛 구간"] c["촘촘한 최근 구간"]
  d["보존 기간 밖"] e["다운샘플링"] f["수집 주기 그대로"]
  g["왼쪽 끝에서 잘려 나가고 오른쪽 끝에 새 값이 붙는다"]:3

새 값은 오른쪽 끝에 붙습니다. 왼쪽 끝은 보존 기간을 넘기면서 잘려 나갑니다. 그 사이의 옛 구간은 다운샘플링으로 성겨진 채 남아 있습니다.

줄을 읽는 두 방향

쌓아 둔 줄에서 답을 얻으려면 여러 값을 하나로 묶어야 합니다. 여러 값을 하나로 묶는 이 일이 집계입니다. 묶는 방향은 둘입니다.

방향 무엇을 묶나 답하는 물음
시간 축으로 한 줄 안의 여러 쌍 이 서버의 5분 평균은 얼마인가
줄 사이로 같은 시각의 여러 줄 서버 전체를 합치면 얼마인가

두 방향은 같은 기록을 서로 다르게 자릅니다. 시간 축으로 묶으면 한 줄이 짧아집니다. 줄 사이로 묶으면 여러 줄이 한 줄로 합쳐집니다.

flowchart TD
    subgraph A["시간 축으로 · host=web1 한 줄의 칸 넷"]
        a1["10:00"]
        a2["10:15"]
        a3["10:30"]
        a4["10:45"]
    end
    A -->|"묶으면"| AR["줄 하나가 칸 하나로 짧아진다"]
    AR -->|"줄마다 이렇게 해 두고"| B
    subgraph B["줄 사이로 · 같은 시각의 줄 셋"]
        b1["host=web1"]
        b2["host=web2"]
        b3["host=web3"]
    end
    B -->|"묶으면"| BR["줄 셋이 줄 하나로 합쳐진다"]

「서버 전체의 5분 평균」은 두 방향을 잇달아 쓴 것입니다. 먼저 줄마다 5분 평균을 내어 저마다 한 칸으로 짧게 만듭니다. 그 다음 같은 시각의 줄들을 하나로 합칩니다.

평균처럼 여럿을 하나로 뭉치는 셈에는 잃는 것이 따라옵니다. 평균만 보면 잠깐 크게 튄 값이 묻힙니다.

그래서 모니터링에서는 평균과 함께 높은 쪽 값을 같이 봅니다. 값들을 크기순으로 줄 세워 위에서 몇 번째에 있는지를 보는 것이 백분위수입니다. 맨 위 몇 개를 뺀 나머지가 전부 그 아래에 들어오는 값을 보면, 평균에 묻혀 있던 큰 값이 드러납니다.

값이 없는 구간과 어긋난 시각

줄에는 빈틈이 생깁니다. 재는 쪽이 잠깐 멈췄거나 값이 오는 길이 끊기면 그 구간에 쌍이 없습니다. 값이 없는 것과 값이 0인 것은 다릅니다. 앞은 모른다는 뜻이고 뒤는 0이라고 쟀다는 뜻입니다.

빈틈을 어떻게 다룰지는 읽는 쪽이 정합니다. 앞 값을 이어 쓰기도 하고, 그 구간을 그래프에서 끊어 비워 두기도 합니다. 어느 쪽을 골랐는지 모르고 보면 같은 그래프를 다르게 읽게 됩니다.

시각이 어긋나는 문제도 있습니다. 재는 기계마다 시계가 조금씩 다르면 같은 순간에 일어난 일이 서로 다른 시각에 꽂힙니다. 여러 기계의 시간과 시계를 한 기준에 맞춰야 시계열이 성립합니다.

두 문제는 칸의 모양이 다릅니다.

flowchart TD
    subgraph A["줄 하나 · 값이 없는 구간"]
        a1["10:00:00"]
        a2["빈 칸"]
        a3["10:00:30"]
        a4["10:00:45"]
    end
    A -->|"둘 다 15초마다 잰 줄이다"| B
    subgraph B["다른 줄 · 시계가 7초 어긋난 기계"]
        b1["10:00:07"]
        b2["10:00:22"]
        b3["10:00:37"]
        b4["10:00:52"]
    end

통계에서 말하는 시계열

시계열이라는 말은 통계와 경제 분석에서도 씁니다. 시각과 값을 짝지어 이어 붙인다는 뜻은 같고 관심이 다릅니다. 모니터링 쪽은 지금 무슨 일이 벌어지는지를 묻습니다. 통계 쪽은 이 줄이 앞으로 어떻게 될지를 묻습니다.

그래서 통계 쪽은 한 줄을 몇 갈래로 갈라 봅니다. 앞서 든 메모리 사용량 줄을 그대로 예로 들어 봅시다.

몇 달에 걸쳐 조금씩 올라가고 있다면 그것이 추세입니다. 길게 봤을 때 어느 쪽으로 가고 있는지를 말합니다.

낮에 올랐다가 밤에 내려가는 것이 날마다 되풀이된다면 그것은 계절성입니다. 하루나 한 주처럼 일정한 주기로 돌아오는 출렁임을 가리킵니다.

추세와 계절성을 걷어 내고 남은 것이 흔들림입니다. 이 흔들림에서 평소와 다른 대목을 찾는 일이 이상 탐지입니다.

flowchart TD
    L["메모리 사용량 한 줄"]
    L --> T["추세 · 길게 봤을 때 가는 쪽"]
    L --> S["계절성 · 주기로 돌아오는 출렁임"]
    L --> R["둘을 걷어 내고 남은 흔들림"]
    R --> D["이상 탐지가 보는 데는 여기다"]

셋이 나란히 늘어선 것이 아닙니다. 추세와 계절성을 먼저 빼고, 그러고도 남은 흔들림 위에서 이상 탐지가 일합니다.

두 쪽은 쓰는 도구가 다르지만 쌓는 모양이 같습니다. 모니터링하려고 쌓아 둔 줄을 예측에 그대로 쓰기도 합니다.

관련 항목

시계열을 이루는 조각

타임스탬프 · 데이터 포인트 · 메트릭 · 레이블 · 샘플 · 단위 · 수집 주기

시계열을 쌓아 두는 저장소

시계열 데이터베이스 · LSM 트리 · SSTable · 컴팩션 · WAL · 파티셔닝 · 샤딩

쌓인 시계열을 덜어 내는 방법

다운샘플링 · 롤업 · 보존 기간 · 델타 인코딩 · 압축 · 축출 · TTL

시계열에서 값을 뽑아내는 연산

집계 · 평균 · 백분위수 · 이동 평균 · 증가율 · 질의 · 시간 범위

시계열이 불어나거나 깨질 때 터지는 문제

카디널리티 · 카디널리티 폭발 · 결측치 · 클록 드리프트 · 단조 시계 · 쓰기 증폭

시계열을 만들어 내보내는 도구

계측 · 텔레메트리 · 수집기 · 풀 모델 · 푸시 · Prometheus · OpenTelemetry

시계열을 사람에게 보여 주는 도구

대시보드 · 시계열 그래프 · 모니터링 · 알림 · 관측성 · 골든 시그널

시계열을 통계로 다루는 분야

시계열 분석 · 추세 · 계절성 · 이상 탐지 · 예측 · 데이터 분석

다른 이름: time series · 타임 시리즈