LabHub

자본시장과 결제 · 시세 피드 — 순번과 지연 · 이론

순번이 붙어 있는 이유

LabHub 에서 이어서 보기

한 줄 요약

시세 피드는 순서도 도착도 보장하지 않는 전송 위에 올라가 있고, 그래서 메시지마다 순번이 붙어 있다 — 빠진 것과 늦은 것을 구분하는 유일한 수단이 그 숫자다.

왜 이게 필요했나

시세 데이터는 다른 데이터와 요구 조건이 정반대입니다. 몇 밀리초 늦은 정확한 값보다 지금 도착한 값이 쓸모 있고, 한 종목의 호가는 1초에도 수십 번 바뀝니다. 그래서 거래소 시세는 대개 TCP 가 아니라 UDP 멀티캐스트로 나갑니다. 재전송도 순서 보장도 없는 대신, 한 번 보내면 구독자 전부가 동시에 받습니다.

보장이 없다는 것은 두 가지가 실제로 일어난다는 뜻입니다.

유실   보낸 메시지가 우리에게 오지 않는다재정렬 나중에 보낸 메시지가 먼저 도착한다

받는 쪽에서 이 둘은 똑같이 보입니다. 순번 100 다음에 102 가 오면, 101 이 없어진 것인지 늦게 오는 중인지 그 순간에는 알 수 없습니다. 그래서 도착 순서로 순번을 세는 방식은 늘 부풀어 나옵니다. 실제 데이터에서 도착 순서 기준 갭이 1,138건인데 정말 빠진 것은 204건인 경우를 이 코스의 실습에서 직접 보게 됩니다.

이 차이가 왜 문제인가 하면, 갭을 발견한 피드 핸들러가 하는 일이 재전송 요청이기 때문입니다. 1,138번 요청하면 그 요청 트래픽이 회선을 먹고, 회선이 막히면 지연이 더 커지고, 지연이 커지면 재정렬이 더 늘고, 재정렬이 늘면 갭이 더 보입니다. 자기가 만든 문제를 자기가 키웁니다. 실제로 개장 직후 이 되먹임에 빠져 피드가 몇 분씩 마비되는 사고가 반복됩니다.

어떻게 동작하나

갭은 순번의 집합으로 판정합니다. 도착한 순번을 모아 두고, 기대 범위 안에서 한 번도 오지 않은 것만 빠진 것으로 봅니다. 늦게 온 것은 집합에 들어오므로 저절로 빠집니다. 판정에는 기다리는 시간이 붙습니다 — 보통 수십 밀리초를 기다린 뒤에도 없으면 그때 빠진 것으로 확정합니다.

빠진 것을 메우는 길은 세 가지입니다.

A/B 중재    거래소가 같은 내용을 두 채널로 따로 보낸다.            한쪽 구멍은 대개 다른 쪽에 있다. 요청 없이 메워진다.재전송 요청 빠진 순번을 콕 집어 다시 달라고 한다.            거래소 재전송 버퍼를 넘어가면 못 받는다.스냅샷 복구 현재 호가창 전체를 다시 받는다.            무겁지만 한 번에 끝난다. 구멍이 길면 이쪽이 싸다.

순서가 곧 비용 순서입니다. A/B 중재를 먼저 시도하지 않고 바로 재전송을 요청하는 구현이 흔한데, 실습 데이터에서 A 채널의 구멍 204개 중 180개는 B 채널을 보기만 해도 메워집니다. 요청 자체가 필요 없는 것이 88%입니다.

중복도 정상입니다. A/B 두 채널을 다 받으면 같은 메시지가 두 번 옵니다. 재전송을 받으면 또 옵니다. 순번으로 걸러 내지 않으면 체결량 집계가 두 배가 되고, 그 값으로 거래대금 순위를 만들면 순위가 통째로 뒤집힙니다.

지연은 평균이 아니라 꼬리로 봅니다. 실습 데이터에서 전체 평균은 10,071마이크로초인데 중앙값은 1,049마이크로초입니다. 평균이 중앙값의 열 배라는 것은 소수의 아주 느린 건이 평균을 끌고 갔다는 뜻이고, 그 소수가 정확히 사고 구간입니다. 평균을 감시 지표로 걸어 두면 이 사고는 지표상 아무 일도 아닌 것으로 지나갑니다.

백분위수는 계산 방식까지 못 박아야 합니다. 최근접 순위 방식과 선형보간 방식은 같은 데이터에서 다른 값을 냅니다. 우리 대시보드와 거래소 SLA 문서가 다른 정의를 쓰고 있으면, 같은 회선을 두고 한쪽은 위반이라 하고 한쪽은 아니라고 합니다. 실제로 그런 회의가 열립니다.

현장에서 만나는 모습

한 곳에서 "장 초반에만 호가가 튄다" 는 신고가 있었습니다. 지연 대시보드는 평균만 그리고 있었고 개장 직후에도 12ms 정도로 평온했습니다. 캡처를 떠서 분 단위로 쪼개 보니 09:00 분과 09:08 분 두 구간의 p99 가 380ms 를 넘었고, 그 두 구간에 10ms 초과 건의 95%가 몰려 있었습니다. 나머지 아홉 개 구간은 p99 가 1.6ms 였습니다. 하나의 평균이 두 세계를 섞어 하나의 숫자로 만들고 있었습니다.

지연이 300ms 를 넘긴다는 것은 우리가 보고 있는 호가가 이미 지나간 값이라는 뜻입니다. 그 값으로 지정가를 계산해 주문을 내면 체결이 안 되거나, 반대로 불리한 값에 체결됩니다. p99 가 310ms 라면 100건에 1건은 0.3초 늦은 그림을 보고 주문했다는 말입니다. 이것이 시세 품질이 곧 돈인 이유입니다.

다음 실습에서 할 것

12,000개 순번짜리 A/B 이중화 피드 캡처를 직접 만들고, 도착 순서로 센 갭과 순번 집합으로 센 갭이 얼마나 다른지 확인합니다. B 채널로 메울 수 있는 것과 진짜 구멍을 가르고, 남은 구멍을 재전송과 스냅샷으로 나눕니다. 지연은 최근접 순위 백분위수로 재고 분 단위로 쪼개 꼬리가 몰린 구간을 짚습니다.