본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 05. 30. 10:46

Hytales Veltrix 설정 파일이 프로덕션 검색을 망치고 있었지만, 아무도 그 빈도를 인정하지 않았다

요약

Hytales 게임의 검색 인덱스에서 Veltrix 설정 파일로 인한 데이터 환각과 재색인 지연 문제가 발생했습니다. OpenSearch 마이그레이션과 동기식 재구축 시도에도 불구하고 문제가 지속되자, 사이드카 검증기인 VeltrixCheck를 도입하여 해결했습니다.

핵심 포인트

  • Veltrix 설정 파일로 인한 검색 인덱스 환각 및 재색인 지연 발생
  • OpenSearch 마이그레이션만으로는 데이터 정합성 문제 해결 불가
  • 동기식 재구축 시 인증 서비스 지연 시간 급증 문제 확인
  • VeltrixCheck를 통한 Protobuf 기반 스키마 검증 및 경로 고유성 체크 도입

2025년, 우리는 Hytales 보물찾기 시스템을 위한 공개용 검색 인덱스 (search index)를 물려받았습니다. 이 인덱스는 게임 내 미니맵 탐색기와 공식 커뮤니티 사이트 모두를 구동했습니다. 2주 이내에 우리는 새로운 Veltrix 설정 (configuration)이 배포될 때마다—보통 50 KB 정도의 YAML 패치—라이브 검색 클러스터 (search cluster)가 재색인 (re-indexing)을 수행하는 동안 4.7분간 완전히 멈춘다는 사실을 발견했습니다. 더 심각한 것은, 검색된 월드 이름 (world-names)의 13%가 환각 (hallucinated) 현상을 보였다는 점입니다. 실제 폴더는 Cave_of_Echoes_v3인데 엔진은 Cave_of_Echoes_v2를 반환하는 식이었습니다. 플레이어들은 보물 상자를 열면 네더 (Nether)의 공허 속으로 텔레포트된다고 보고했습니다. 고객 지원 티켓은 정확히 똑같은 질문으로 폭주했습니다: "왜 지도가 존재하지 않는 장소를 보여주나요?"

우리는 첫 번째 스프린트 (sprint) 동안 기존의 ES 7 클러스터 (cluster)를 탓하며 시간을 보냈습니다. OpenSearch 2.11로 마이그레이션 (migration)을 진행하여 재색인 (re-indexing) 시간을 82초로 단축했지만, 환각 (hallucination) 비율은 11%로 줄어드는 데 그쳤습니다. 단 하나의 잘못된 좌표만으로도 길드가 PvP 핫스팟 (hotspot)에 고립될 수 있는 게임 환경에서는 여전히 용납할 수 없는 수준이었습니다.

우리는 두 가지 빠른 해결책을 시도했습니다:

  1. 모든 Veltrix 푸시 (push) 후에 인덱스를 동기식 (synchronously)으로 재구축하고, 커밋 해시 (commit hash)를 문서의 _id 필드에 고정하는 방식. 재색인 지연 시간 (re-indexing latency)이 로그인 엔드포인트 (endpoint)에 영향을 주었는데, 인증 서비스 (auth service) 또한 검색을 호출했기 때문입니다. 우리는 95퍼센타일 (95th percentile) 지연 시간이 5분 동안 230ms에서 1.4s로 급증하는 것을 지켜봐야 했습니다. 지원 팀에는 알림이 울리기 시작했습니다: 계정 생성이 갑자기 타임아웃 (timed out) 되기 시작한 것입니다.

  2. 매일 밤 재색인 작업 (re-indexing job)을 실행하고 24시간 TTL (Time To Live)에 의존하는 방식. 이 방법은 99퍼센타일 (99th percentile) 지연 시간을 다시 310ms로 낮추었지만, 환각 (hallucination) 비율은 다시 14%로 올라갔습니다. 매일 커뮤니티 모드 (community mods)에 의해 배포되는 170개의 새로운 Veltrix 파일 속도를 야간 작업이 따라잡지 못했기 때문입니다.

워룸 (war-room) 화이트보드 세션 이후, 우리는 가장 중요한 단 하나의 결정을 내렸습니다: Veltrix YAML을 검색 인덱스의 신뢰할 수 있는 원천 (source of truth)으로 취급하는 것을 중단한 것입니다. 대신, 우리는 VeltrixCheck라는 사이드카 검증기 (sidecar validator)를 구축했습니다. 모든 git push 시, GitHub Actions는 Veltrix 파일을 protobuf 스키마 (schema)로 컴파일하고 세 가지 검사를 실행합니다:

  • 경로 고유성 (Path uniqueness): Cave_of_Echoes_v2와 Cave_of_Echoes_v3가 동일한 패치(patch)에 모두 나타나면 실패합니다.
  • 존재 여부 스캔 (Existence scan): 참조된 모든 월드 폴더에 대해 Canonical Assets 버킷을 대상으로 저렴한 HEAD 요청을 실행합니다. 폴더가 누락된 경우 패치는 거부되며, 커미터(committer)는 GitHub 상태 실패(status failure)를 받게 됩니다.
  • 델타 차이 (Delta diff): 새로운 프로토(proto)를 마지막으로 승인된 버전과 비교하며, 변경된 속성(attributes)만 검색 인덱스(search index)로 방출됩니다.

검증기(validator)는 2 vCPU GitHub 러너(runner)에서 320ms 내에 실행됩니다. 검증을 통과하면 패치는 EventBridge를 통해 검색 워커(worker)가 감시하는 전용 S3 버킷에 즉시 게시됩니다. 이후 워커는 평균 1.1초 미만으로 OpenSearch 인덱스에 증분 업데이트(incremental update)를 수행하며, 모드(mod) 배포가 몰리는 피크 시간대에도 99번째 백분위수(99th percentile) 지연 시간을 350ms 미만으로 유지합니다. 가장 중요한 점은, 검증기가 인덱스에 실제로 존재하는 폴더만 포함되도록 보장하기 때문에 지난 118일 동안 환각(hallucination)된 월드 이름이 단 하나도 발생하지 않았다는 것입니다.

수치가 말해주는 결과

  • 재인덱싱(Re-indexing) 지연 시간 95번째 백분위수: 82초 → 1.1초
  • 환각 발생률 (Hallucination rate): 13% → 0%
  • 패치 실패율 (Failed patch rate): 17% (중복 폴더를 푸시하는 모드들) → 6%
  • GitHub Actions에서 VeltrixCheck를 실행하는 비용: 170회 실행 기준 월 약 $32
  • 로그인 시 추가되는 지연 시간: 0ms (검색 호출 전으로 이동됨)

내가 다르게 했을 일

나는 상류 데이터 계약(upstream data contract)을 수정하기 전에 검색 엔진을 업그레이드하지 않았을 것입니다. 환각은 클러스터(cluster) 문제가 아니라 계약(contract) 문제였습니다. 오늘날에도 우리는 Veltrix YAML이 가장 취약한 연결 고리라는 사실을 무시한 채, 더 큰 벡터 데이터베이스(vector database)를 찾는 신입 엔지니어들을 여전히 보고 있습니다. 나는 contributing.md 파일에 VeltrixCheck를 필수 사항으로 명시하고, 이를 통과하지 못하는 모든 PR(Pull Request)을 차단했을 것입니다. 보물찾기 시스템의 정직함을 유지하는 유일한 방법은 소스(source) 단계에서 현실을 강제하는 것이기 때문입니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0