StatsD는 로그 메트릭을 수집하는 영역에서 ProxySQL과 비슷한 용도로 쓰인다. UDPTCP를 통해 countertime과 같은 통계 데이터를 받아, Graphite같은 backend에 전송하는 Proxy다. 따라서 ProxySQL처럼 connection 중계가 아니라 통계적인 데이터 집계 처리 용도의 proxy로서 사용된다.

조금 더 쉽게 설명하면, StatsD는 메소드 호출 빈도와 소요 시간, 서비스 내에서 사용자가 일으키는 conversion(로그인, 장바구니 담기, 결제 등) 수 등을 MongoDB, MySQL, Datadog, zabbix, influxdb와 같은 backend에 적절히 기록한다. Graphite와 가장 케미가 좋다. (StatsD가 지원하는 backend 목록)

StatsD가 주는 메리트

ProxySQL처럼 auto failover와 같은 high availability 지원도 안 되는데 왜 굳이 쓰나? 싶겠지만, 애초에 StatsD를 비롯한 proxy 구조 자체의 이점이 있다. 바로 client-side 지원이다.

만약 InfluxDB로 로그 메트릭을 수집하고자 하더라도, 사용하는 언어에 안정적인 InfluxDB client 라이브러리가 없다면 번거로울 수밖에 없다. 이 경우 StatsD같이 InfluxDB를 backend로 지원하는 프록시 라이브러리를 사용하면 되고, 없더라도 구현하기 비교적 더 쉽다. TCP/UDP 소켓 기반으로 간결하게 통신할 수 있도록 설계되어 있기 때문이다. 그리고 StatsD는 TCP/UDP 프로토콜과 꽤 밀접하게 붙어 있기에, HAProxy같은 소프트웨어 로드 밸런서를 통해 high availability도 보장해줄 수 있다.

추가적으로 StatsD는 통계 데이터 집계 면에서 우수하다. StatsD는 데이터를 모아 두다가 일정 시간마다 집계 처리를 하고, 이들을 한번에 backend로 전송한 후 StatsD의 데이터를 모두 비운다. 이 때문에 로그를 visualize하기 이전에 통계 데이터를 미리 집계해둘 수 있다. 들어오는 데이터를 모두 실시간으로 전송하는 것보다, 잠시동안 모아 뒀다가 집계 작업 후 한번에 전송하는 게 추후의 집계 작업을 위한 컴퓨팅 비용이나 네트워크 비용 면에서 우수하다.

Metric의 형태

조금 추상적인 단어긴 한데, 어떤 데이터가 오가는 형태를 metric이라고 부를 수 있을 것 같다. StatsD도 데이터를 표현하기 위한 포맷이 존재하고, 아래와 같다.

<bucket>:<value>|<type>

예를 들면, gorets:1|c가 될 수 있다. 'gorets'로 명시된 bucket은 namespace 개념이다. 그냥 key라고 생각해도 된다. bucket은 StatsD에서 이야기하는 이름이고, metric name이라고 말할 수도 있다. 구분자(|) 뒤에 'c'로 명시된 type은 StatsD에서 제공하는 타입들 중 하나다.

StatsD는 데이터를 잠시 보관해 뒀다가 일정 시간마다 이들을 backend에 전송한다고 했다. 이와 같은 pipelining을 StatsD에선 flush interval이라 부르며, 기본값은 10초다.

Metric Type

StatsD에는 4개의 metric type(Counting, Timing, Gauges, Sets)이 있다.

Counting(:|c)

'c'로 표현한다. method_check_id_duplicated:1|c처럼 사용할 수 있다. 이는 간단한 카운터로, bucket(metric name)에 value를 더하는 작업이다. 메소드나 API 호출 수 등에 사용할 수 있다. StatsD에선 bucket마다 카운트 값을 누적하고 있다가, flush interval마다 backend에 카운트의 합을 전송하고 StatsD에선 count를 0으로 재설정한다.

Timing(:|ms)

'ms'로 표현한다. api_user_auth:82|ms처럼 사용할 수 있다. 이 경우, metric name인 api_user_auth를 위해 value인 82ms가 소요되었다는 의미이다. API별 소요 시간 등에 사용할 수 있다. StatsD에 이 데이터를 쌓으면, flush interval마다 평균, 표준 편차, 합계, 상한, 하한을 계산하여 backend에 이들을 전송한다.

Gauges(:|g)

'g'로 표현한다. goroutines_a:-8|g처럼 사용할 수 있다. 말 그대로 '게이지'를 표현하기 위해 사용하며, counting에 비해 값을 감소시킬 수 있어서 하드웨어 사용량같은 측정 값이나 스레드 갯수처럼 위아래로 이동할 수 있는 counter 등에 사용할 수 있다.

Sets(:|s)

's'로 표현한다. user:planb|s처럼 사용할 수 있다. flush interval마다 bucket에 전달된 고유한 value의 수를 계산하여 backend로 전송한다. SQL로 따지면 distinct count라고 생각하면 된다. MAU나 DAU 등을 뽑아낼 때 사용할 수 있을 것 같다.

'배경지식' 카테고리의 다른 글

ProxySQL  (1) 2019.02.12
직렬화와 JSON  (0) 2019.02.12
ORM  (0) 2019.02.12
HTTP 메소드  (0) 2019.02.12
HTTP 헤더  (0) 2018.11.02

+ Recent posts