ADR-0060: 분 가격 수집을 전용 KIS 키로 분리한다 — 공유 호출 예산은 켜지 않는다¶
- 상태: 제안됨
- 날짜: 2026-10-08
- 관련: ADR-0055(KIS 공유 호출 예산 — 이 ADR 이 대체하지 않는다) · ALPHA-1247 · ALPHA-1248 · ALPHA-1252
맥락¶
KIS 호출 한도는 한 계좌에 초당 18건이다. 분 가격 수집 워커(price-worker)는 iNAV 워커, 업종지수 워커, 장중 수급,
장 마감 배치와 KIS 키 하나를 나눠 쓰면서 한 번에 한 건씩 호출했다.
- 지금 구성(매분 469종목)의 한 분 수집 소요는 장중 중앙값으로 58.8초다. 한 분 창을 겨우 채운다.
- 대상 ETF 를 넓히면 매분 803종목을 받아야 한다. 한 키에 한 건씩 보내는 방식은 매분 약 500종목이 한계다.
ADR-0055는 한 키를 나눠 쓰는 호출자들의 합산 발신을 공유 호출 예산으로 통제하자고 제안했다. ETF 커버리지 확장의 선행 조건으로 나온 제안이다. 이후 두 번째 KIS 키를 확보했고, 2026-10-08 시험에서 두 키의 한도가 합쳐지지 않는다는 것을 확인해 방향을 바꿨다.
실측 (2026-10-08)¶
- 한도는 계좌별로 따로다. 2번 키로 초당 15~18건을 40초 넘게 보내는 동안, 1번 키로 수집하던 운영 워커의 HTTP 500 은 창마다 0~2건으로 평소(0~3건)와 같았고 한 분 수집 소요도 평소와 같았다. 한도가 묶여 있었다면 두 키의 합이 초당 25~28건이라 거절이 크게 늘었을 것이다. 두 키는 계좌가 다르다.
- 2번 키 단독: 초당 16건과 17건은 10초 동안 거절 0건이었다. 18건은 180건 중 1건이 거절됐다. 동시에 보낸 요청은 19건까지 통과했고 20건에서 1건이 거절됐다.
- 1% 안팎의 드문 거절이 속도와 무관하게 섞여 나온다. 원인은 모른다.
- 유량 거절은 HTTP 500 으로 온다. 동시 26건 중 2건이 HTTP 500 에
EGW00201을 실어 왔다.
결정¶
- 분 가격 워커만 2번 키 전용으로 둔다. 이 워커 말고는 2번 키를 쓰지 않는다. iNAV 워커, 업종지수 워커, 장중 수급,
장 마감 배치(가격·NAV·프로필·수급), 수동 백필은 1번 키에 남는다. 다만
price-worker태스크 정의로 지난 날짜를 수동으로 돌리면 그 호출은 2번 키로 나간다. - 분 가격 워커는 동시 호출 4, 호출 간격 0.0625초(초당 16건)로 수집한다.
- 초당 16건은 실측에서 거절이 없던 구간이다.
- 동시 호출 4는 장중 응답이 느린 분(128~180ms)에도 초당 16건을 유지하기 위한 수다.
- 계산으로는 469종목이 약 29초, 803종목이 약 50초다. 관측에서 빠듯하면 호출 간격을 초당 17건(약 47초)으로 올린다.
- 토큰 캐시도 키별로 나눈다. 캐시에 든 토큰이 다른 키의 것이면 새로 발급해 덮어쓴다. 한 캐시를 두 키가 쓰면 서로 덮어쓰며 발급을 반복하고 발급 한도에 걸린다.
- Terraform 변수 하나(
minute_price_dedicated_kis_enabled)로 켜고 끈다. 켜면 워커의 키·토큰 캐시가 2번으로 바뀌고 전용 키 설정, 동시 호출 4, 호출 간격 0.0625초가 실린다. 끄면 1번 키에 한 건씩 보내는 방식으로 돌아간다. 분 가격 소스가 toss 인 환경에서는 KIS 를 쓰지 않으므로 켜도 바뀌는 것이 없다. - 공유 호출 예산은 켜지 않는다. 전용 키 변수와
call_budget_enabled를 같이 켜면 plan 이 거부된다. 둘 다 켜지면 2번 키로 나가는 분 가격 호출이 1번 키의 예산을 쓴다. - 워커 코드는 전용 키 설정(
dedicated_app_key)이 켜져 있을 때만 공유 호출 예산 없이 동시 호출을 허용한다. 전용 키 설정과 공유 호출 예산이 둘 다 꺼져 있으면 종전대로 한 번에 한 건이다.
분 가격 워커를 옮기는 이유는 바꿀 곳이 가장 적어서다. 이 워커만 자기 전용 환경변수로 키를 받는다. 나머지 레인은 여러 태스크가 같은 시크릿 참조를 공유한다.
대안¶
- 공유 호출 예산을 켠다(ADR-0055) — 한 키의 한도를 호출자끼리 나누는 길이다. 두 키의 한도가 따로임을 확인한 뒤에는 레인을 키로 가르는 쪽을 택했다. 레인을 키로 가르면 조정할 상대가 없다.
- 다른 레인을 2번 키로 옮긴다 — 분 가격 워커 말고는 여러 태스크가 같은 시크릿 참조를 공유하고 있어 바꿀 곳이 더 많다.
- 아래는 하지 않기로 한 것이다.
- 멀티시세 감시 — 멀티시세는 현재가 스냅샷이라 분봉(시가·고가·저가·종가·거래량)을 주지 않는다. 지금 분 수집과 판정은 분봉을 기준으로 한다.
- 구성종목 수집 주기 변경 — 전용 키의 초당 16건이면 803종목을 매분 받을 수 있어(계산 약 50초) 수집 구조를 바꿀 필요가 없어졌다.
- 한 워커가 두 키를 섞어 쓰는 것.
결과¶
- 대상 ETF 를 넓힌 뒤에는 키 전환만 되돌릴 수 없다. 되돌리면 1번 키에 한 건씩 보내는 방식이고, 그 방식은 매분 약 500종목이 한계다. 목록도 같이 줄여야 한다.
- 배포는 분 세션이 없는 시간에만 한다. 워커 둘이 같은 키로 동시에 호출하면 합산 발신이 계좌 한도를 넘을 수 있다
(초당 16건이 둘이면 32건). 배포 방식(새 태스크를 먼저 띄우고 옛 태스크를 내린다)은 바꾸지 않았다. 새 워커는 세션 fence 를
얻기 전에는 호출하지 않으므로 정상 교체에서는 겹치지 않는다고 판단했다. 코드를 읽고 내린 판단이고, 겹침을 실제로 만들어
재 보지는 않았다. 장중에
price-worker태스크 정의로 수동 실행을 같이 돌리는 것도 같은 이유로 피한다. - 2번 시크릿은 Terraform 밖에서 등록했다. Terraform 은 이름(
<name>/kis/oauth-2)으로 조회만 한다. 변수를 켠 환경에 그 시크릿이 없으면 plan 이 실패한다. 2번 토큰 캐시(SSM 파라미터)도 Terraform 이 만들지 않고 워커가 쓴다. - 유량 거절은
err_http_500으로 본다. 창 요약 로그의kis_EGW00201은 본문으로 오는 거절만 센다. HTTP 500 으로 오는 거절은 운반 계층이 재시도할 뿐 이 수에 잡히지 않는다. - 실패했을 때의 동작
| 상황 | 동작 | 대응 |
|---|---|---|
| 2번 키의 드문 유량 거절(HTTP 500) | 그 호출만 1초 뒤 재시도한다(이후 2초, 4초) | 없음(기존 동작) |
| 유량 거절이 이어짐 | 호출마다 재시도를 다 쓰고 실패한다. 종목당 약 7초가 들어 그 분의 수집이 크게 늦어진다. "5종목 연속이면 중단" 판정은 본문으로 오는 거절만 세므로 HTTP 500 으로 오는 거절에는 걸리지 않는다 | 호출 간격을 늘린다 |
| HTTP 500 이 60초에 20건 이상 | 워커가 연결 재사용을 스스로 끈다. 호출당 시간이 늘어난다 | 원인을 본 뒤 워커를 재시작한다 |
| 2번 시크릿 읽기 권한 누락 | 워커가 기동하지 못한다 | Terraform 변수를 끈다 |
| 2번 토큰 캐시 권한 누락 | 워커는 뜬다. 캐시를 읽고 쓰지 못해 기동할 때마다 토큰을 새로 발급한다(쓰기 실패는 경고 로그) | 태스크 역할 정책에 2번 캐시를 넣는다 |
| 2번 키 자체의 장애 | 분 가격 수집이 선다 | Terraform 변수를 끈다 |
- 전환 뒤 관측 기준(3~5거래일): 한 분 수집 소요 중앙 35초 이하, 55초 초과 5% 이하, HTTP 500 이 호출의 1% 이하
(
err_http_500 ÷ attempts),keep_alive_off없음. - iNAV 워커의 호출 간격 단축(0.5초 → 0.25초)은 이 전환 뒤에 올린다. 전환 전에 올리면 분 가격이 남아 있는 1번 키의 설정상 발신 합이 수급 시간대에 초당 20.5건이 된다.
- 한 분 수집 소요(약 29초, 약 50초)는 계산값이다. 전환 뒤 관측으로 확인한다.
ADR-0055 와의 관계¶
- 대체하지 않는다. 분 가격 레인만 다른 길을 택한 것이다. 공유 호출 예산의 코드와 스키마는 그대로 있고, 기본값도 꺼짐이다.
- ADR-0055 의 "기본 비활성" 문단은 "
call_budget_enabled=false이고 분봉 동시 요청은 1이다. 꺼져 있으면 terraform 은 동시 요청 변수를 싣지 않는다"고 적는다. 전용 키 변수를 켠 환경에서는 공유 호출 예산이 꺼진 채로 동시 요청 4가 실린다. 전용 키 변수가 꺼진 환경에서는 그 문단이 그대로 맞다.