도입 배경

시간에 따라서 달라지는 주가와 같은 데이터를 시계열 데이터(Time Series)라 하는데, 대표적인 시계열 데이터가 바로 주가입니다. 실제로 한국거래소(KRX)에서 하루에 거래되는 2천여 종목의 매매체결 데이터는 하루에만 보통 900만건에서 1,000만건에 달합니다. 이처럼 방대하고 다양한 금융 데이터를 한곳에 효율적으로 저장해 놓아야 향후 매매전략 수립을 위한 백테스트를 한결 편리하게 수행할 수 있을 겁니다.

따라서, MySQL 같은 전통적인 RDBMS나, MongoDB NoSQL가 아닌, 시계열 데이터를 위한 데이터베이스 찾아보았는데, 최근 가장 각광받는 InfluxDB를 도입하기로 했습니다. 구글의 Go 언어로 작성되어 속도가 빠르며, 라이브러리 의존성이 없어 설치가 간편하기 때문이죠.

InfluxDB는 개발사인 InfluxData에서 오픈소스로 제공하는 _TICK Stack_이라 불리는 빅데이터 솔루션의 중심에 있으며, 외부의 데이터를 임포트하거나 다시 익스포트하는 Telegraf, 데이터 시각화를 도와주는 Chronograf, 실시간 데이터 처리를 위한 Kapacitor 등과 유기적으로 연결할 수 있다는 것이 강점으로 손꼽힙니다.

실행 방법

도커가 설치되어 있다는 전제 하에, 컨테이너 내의 InfluxDB 데이터 디렉토리를 컨테이너 밖으로 연결해주는 정도면 충분합니다.

$ docker run --rm -d --net host \
  -v /media/storage/influxdb:/var/lib/influxdb \
  --name influxdb influxdb

각종 테스트를 위한 CLI 접속은 아래와 같이 할 수 있다. 공식 문서를 통해 기본적인 사용법을 배울 수 있습니다.

$ docker exec -it influxdb influx -precision ms

기본 개념

InfluxDB는 Time Series 데이터를 처리하는 시스템이기 때문에, 데이터를 표현하는 방법이 지금까지와는 다릅니다. 한 시점의 데이터를 Line Protocol이라는 형태로 표현하는데,

measurement,tagset fieldset timestamp

예를들어 특정한 시점에 매매가 체결된 주가와 거래량을 Line Protocol로 표현하면 이렇습니다.

intraday,symbol=015760 price=35250,volume=35 1523766210
measurement

measurement는 저장하는 값의 성격을 일컫습니다. 시간대별 주가를 의미하는 intraday가 위 예시에서 사용됐고, 일간 주가를 저장할 경우 interday라는 별도의 measurement를 추가할 겁니다.

tagset, fieldset

사실 InfluxDB의 스키마를 설계할때 고민되는 부분은 tagset와 fieldset중 어느곳에 데이터를 저장해야 할지 결정하는 것인데, 판단기준은 GROUP BY나 정규표현식 연산이 필요한 데이터는 tagset에 넣어야 하고, 함수나 비교연산이 필요한 데이터는 fieldset에 넣어야 한다는 겁니다. 스키마를 설계하기에 앞서 쿼리를 먼저 작성해보는 것이 도움이 될것 같습니다.

한가지 주의할 점은 fieldset과 달리 tagset은 인덱스되므로, 한 tagset의 종류가 UUID 값과 같이 지나치게 다양하거나, tagset의 종류가 너무 많으면 인덱싱에 따른 성능저하, 용량증대와 같은 부작용이 생깁니다.

timestamp

하나의 measurement 내에서는 timestamp의 precision을 사전에 결정해서 일관되게 사용해야 되는데, 나노초에서 시간 단위까지 다양하게 제공되므로 데이터의 발생빈도를 고려해서 적합한 precision을 결정해야 합니다. KRX에서 제공하는 시간대별 주가는 초 단위로까지 기재되어 있으나, 같은 시각에 다수의 매매체결 데이터가 있으므로 밀리초(ms)로 precision을 결정하는 것이 좋습니다.

Line Protocol은 하나의 측정값이 있을때, 시간이 지남에 따라 달라지는 값만 추가적으로 저장하기 위한 방법입니다. measurement, tagset은 한번만 저장되고, 그 뒤로는 timestamp에 따라 fieldset만 연달아 저장되어 용량을 적게 차지하고, 빠른 속도를 얻을 수 있습니다.

Line Protocol에 대한 이해와 스키마 설계에 대한 내용은 InfluxData에서 제공하는 자료를 참고하시면 됩니다.

활용 예시

그동안 적합한 데이터베이스를 결정하지 못해 텍스트 파일로 방치해둔 자료들을 Line Protocol로 컨버전하고, InfluxDB에 임포트 시켰습니다.

$ influx -import -path=2018-04-20.txt -precision ms

$ influx -precision ms

Visit https://enterprise.influxdata.com to register for updates, InfluxDB server management, and monitoring.
Connected to http://localhost:8086 version 1.5.1
InfluxDB shell version: 1.1.1

> use KRX
Using database KRX

> select count(price) from intraday group by time(1d)
name: intraday
time		count
----		-----
1515369600000	9738519
1515456000000	9897141
1515542400000	9638930