시계열 데이터베이스 (TSDB; Time-series Database)

데이터베이스하면 Oracle이니 MySQL이니 하면서 관계형 데이터베이스(RDB)만을 떠올리던 시절은 이미 한참 전에 지나갔습니다. 이제는 DynamoDB, MongoDB, Redis, Cassandra, Neo4j 같은 Key-Value 스토어, 도큐먼트, 인-메모리, 그래프, Wide-칼럼, 공간 데이터베이스 등 다양한 NoSQL 데이터베이스를 하나의 시스템에 적어도 한 종류 이상을 흔하게 사용하는 시대가 되었습니다.

이런 다양한 종류의 데이터베이스 중에 시시각각 수집된 데이터를 시간 순서에 따라 저장하고 조회하는 기능을 제공하는 시계열 데이터베이스가 있습니다. 예전에는 관계형 DB의 테이블에 저장하고 집계 쿼리를 사용해서 데이터를 뽑았다면, 이제는 특화된 시계열 데이터베이스를 사용해서 효율적인 시계열 데이터 처리를 할 수 있습니다.

IT의 흐름상 빅 데이터의 시대인 만큼, 앞으로 시계열 데이터베이스의 쓰임이 많아질 것 같습니다. AWS에서는 조만간 완전관리형 시계열 데이터베이스 서비스인 Timestream을 제공하기 위해 준비하고 있습니다.

InfluxDB

현재 사용할 수 있는 시계열 데이터베이스 중에서는 InfluxDB가 가장 유명합니다.

InfluxDB는 Go언어로 작성되었고, 2013년에 출시되었습니다.

마침 무스마에서도 프로젝트에 InfluxDB를 사용하게 되었습니다.

이번 기회에 InfluxDB를 가지고 시계열 데이터베이스 세계의 문을 두드려보겠습니다.

설치하기

개인 실습용 로컬 서버에 연결하든, 따로 원격 서버에 연결하든 간에 CLI 클라이언트를 사용하려면 influxdb를 통째로 설치해야 합니다. (클라이언트만 따로 제공하지 않습니다.)

$ brew install influxdb

연결하기

만약 개인 실습용 로컬 서버에 연결하려면 influxdb 서비스를 시작한 뒤에 하시면 됩니다. $ brew services start influxdb

InfluxDB의 기본 Listening Port는 8086입니다. 아무 파라미터도 입력하지 않으면 http://localhost:8086 호스트로 연결합니다.

$ influx \
  -precision 'rfc3339' \
  -host '[호스트]' -port '[포트번호]' \
  -username '[유저네임]' -password '[비밀번호; 비워두면 물어봄]' \
  -database '[데이터베이스 이름]'

이런 식으로 연결합니다.

InfluxDB에서는 명시적인 인용부호 사용을 권장합니다. '...'

파라미터 중에서 -precision 'rfc3339'은 날짜/시간 형식을 지정합니다.
(RFC3339는 ISO8601, 즉 yyyy-MM-ddTHH:mm:ss 형식을 사용한다는 의미입니다.)

용어와 개념

알기 쉽도록 익숙한 RDB의 용어와 비교합니다.

RDB InfluxDB
database database
table measurement
column key
PK or indexed column tag key (only string)
unindexed column field key
SET of index entries series

tag key와 field key

데이터베이스 단위는 똑같이 database에 대응합니다. 테이블 단위는 table 대신 measurement라고 하는데, 시계열 데이터베이스가 시간에 따라 측정되고 수집된 자료를 저장하는 데이터베이스이므로 그에 맞는 이름을 사용한 것 같습니다.

column은 key라고 하는데, 여기서 tag와 field 개념을 구분해야 합니다.

예를 들어, 온습도 데이터가 들어오는 temperature_and_humidity라는 measurement가 있다고 합시다.

tag는 말 그대로 태그입니다. tag key에는 building, room 같은 것들이 있을 수 있습니다.

field key는 key 중에서 tag key를 제외한 나머지 key인데, 주로 측정된 값 데이터가 들어갑니다. 즉 여기서는 temperature, humidity 같은 것들이 있을 수 있습니다.

그리고 모든 measurement에는 time 키가 빌트인으로 들어갑니다.

SQL로 비유하자면 tag 키는 WHERE 절에서 주로 사용되는 인덱스 키로 볼 수 있습니다.

클라이언트 명령

명령어 설명
use [database 이름] 현재 데이터베이스 지정
show measurements measurement(테이블) 목록 보기
show tag keys 모든 measurement의 모든 tag key 목록 보기
show field keys 모든 measurement의 모든 field key 목록 보기
show series 모든 measurement의 서로소인 tag key 튜플의 목록 보기

왠지 MongoDB CLI와 비슷한 느낌입니다.

나머지는 여기를 보시면 됩니다.

질의하기: SELECT

RDB에서 SQL 쓰듯이 하면 됩니다.

주의할 점: tag key는 타입이 string입니다. tag key 값은 항상 '...'로 감싸줘야 합니다.

> SELECT "temperature", "humidity" FROM temperature_and_humidity WHERE "building" = '스카이비즈' AND "room" = '3609'

데이터 쓰기: INSERT

RDB와는 다르게 테이블을 먼저 생성하지 않아도 됩니다. 그리고 스키마도 없습니다.

그냥 measurement 이름과 함께 데이터를 삽입하면 해당 이름의 measurement가 자동으로 생성됩니다.

INSERT 형식은 이렇습니다.

> INSERT [measurement 이름], [태그 이름1]=[태그 값1], [태그 이름2]=[태그 값2] [필드 이름1]=[필드 값1], [필드 이름2]=[필드 값2]

자세히 보시면, 태그 키 목록과 필드 키 목록 사이에는 ,(콤마)가 없습니다.

예를 들면,

> INSERT temperature_and_humidity, building='스카이비즈', room='3609' temperature=22.5, humidity=44.5

time 키

그런데 time 키는 어디있냐구요?

INSERT를 실행하면 자동으로 서버 시간 timestamp가 time 키로 저장됩니다.

만약 명시적으로 time을 지정해서 넣으려면 (추천하는 방법 같지는 않습니다.)

맨 뒤에 timestamp를 지정해줍니다.

> INSERT temperature_and_humidity, building='스카이비즈', room='3609' temperature=22.5, humidity=44.5 1223372036854775806

혹은

> INSERT temperature_and_humidity, building='스카이비즈', room='3609' temperature=22.5, humidity=44.5 2019-07-08T17:45:00.000Z

INSERT 구문과 계열 series(계열)

참고로 INSERT 바로 뒤의 [measurement 이름], [태그 이름1]=[태그 값1], [태그 이름2]=[태그 값2] 즉 measurement 이름과 태그 이름 목록이 합쳐진 것이 바로 series(계열)입니다.

show series를 하면 데이터베이스에 있는 모든 measurements의 series를 볼 수 있습니다.

(계속)

이상으로 InfluxDB의 설치 방법과 기본적인 개념과 동작을 살펴보았습니다.

다음 시간에는 Node.js 플랫폼에서 개발할 때 InfluxDB를 사용하는 방법을 알아보겠습니다.

감사합니다.


References