공간 셀에 포함됐다는 사실은 실제 반경 안에 있다는 뜻이 아닙니다. 셀은 후보만 줄이고 정확 거리·공개 정책·카테고리 판정을 별도로 적용합니다.
운영자 직접 작성·기술 검토·최종 검토 2026.08.29
문제·요구사항공간 인덱스장애·privacy면접 답변진도 저장
◎30초 핵심 요약
Geohash/H3로 반경을 넉넉히 덮는 후보를 만든 뒤 공개·영업·카테고리 정책과 원본 좌표의 정확 거리를 확인합니다. 도심 후보가 많을 때는 앞에서 자르지 않고 인덱스 해상도를 조정합니다.
CandidateGeohash / H3 cover
Correctnessexact distance + policy
Privacyminimum precision & retention
DESIGN DECISION · 설계 판단
공간 셀의 후보와 실제 반경 안의 장소를 어떻게 구분할 것인가?
예시 일 조회8,000만
계산 결과
예시 피크약 7,408 QPS
계산 결과
예시 POI5,000만 건
설계 가정
최종 선택
cell cover 후보 생성 + 정책 필터 + exact-distance 판정
Geohash/H3 cover로 반경을 넉넉히 덮어 후보를 찾고 공개·영업·카테고리 정책을 적용한 뒤 원본 좌표로 정확 거리를 계산합니다. 도심 후보가 많으면 임의 truncation 대신 해상도나 공간 질의를 조정합니다.
선택 이유
셀 경계를 최종 거리 판정으로 오인하지 않습니다.
정책상 노출할 수 없는 장소를 랭킹 전에 제거합니다.
도시 밀도별 후보 수와 p99를 독립적으로 조절할 수 있습니다.
포기한 대안
cell 안의 모든 장소를 거리 계산 없이 반환
원형 반경과 셀 경계가 달라 범위 밖 장소를 포함하고 인접 셀의 가까운 장소를 놓칠 수 있습니다.
감수한 단점
정확 거리 재계산 CPU와 후보 fan-out 비용이 듭니다.
도심에서는 adaptive resolution과 후보 예산이 필요합니다.
정밀 query 좌표를 로그·cache에서 최소화해야 합니다.
01 · REQUIREMENTS
반경·정책·정확성을 하나의 응답 계약으로 묶는다
# 요구사항
사용자는 “800 m 안의 카페”를 요청하지만, 시스템은 원형 경계·카테고리·영업 상태·노출 권한·순서와 위치 처리 동의를 동시에 결정합니다. 후보가 빨라도 경계 밖 또는 비공개 장소를 반환하면 안 됩니다.
R1반경 검색
좌표·반경·limit 상한을 검증하고 최종 결과의 정확한 거리로 경계를 보장합니다.
R2카테고리·상태
카테고리, 영업 상태, 테넌트·지역 노출 정책을 랭킹보다 먼저 필터합니다.
R3예측 가능한 지연
셀 후보 수와 fanout에 예산을 두고, hot cell에서도 fallback을 제한합니다.
R4위치 최소화
정확 좌표·계정·IP를 장기 로그에서 기본적으로 결합하지 않고 coarse 관측을 사용합니다.
02 · HIGH-LEVEL DESIGN
정본·파생 인덱스·정확성 판정을 분리한다
# 아키텍처
POI 정본은 versioned 변경 이벤트를 내보내고, 여러 후보 인덱스는 이를 재생성할 수 있는 파생 데이터로 유지합니다. 읽기 경로는 cell cover로 시작하지만 최종 응답 직전의 policy와 거리 검증이 진실의 경계입니다.
주변 장소 검색의 write / read path SVG DIAGRAM · candidate ≠ final answer
정확성 경계: cell cover에서의 거짓 양성은 정상입니다. 반경 경계의 누락은 synthetic boundary test로 막고, 반경 밖 결과는 정확 거리 판정에서 제거합니다. 숨김·폐업 상태는 인덱스 lag가 있어도 read-time deny가 우선합니다.
03 · REQUEST FLOW
좌표를 오래 갖지 않고 후보를 좁힌 뒤 정확하게 답한다
# 요청 흐름
1인증·입력 검증
권한, rate limit, 좌표 범위·반경·limit 상한을 확인하고 정밀도 정책을 적용합니다.
2cell cover
Geohash prefix 또는 H3 이웃 셀을 구해 원형을 충분히 덮는 후보 영역을 만듭니다.
3후보 조회
cell + category shard와 cache를 조회해 제한된 POI ID·좌표·version만 가져옵니다.
4정책·정확 거리
공개 상태를 먼저 확인한 뒤 Haversine/PostGIS로 반경 밖 후보를 제거합니다.
5랭킹·최소 응답
거리·품질·영업 상태를 반영하고 카드에 필요한 필드와 coarse 관측만 남깁니다.
04 · INDEX CHOICES
공간 후보, 정본, 복합 검색의 책임을 섞지 않는다
# 대안 비교
셀 조회는 빠르지만 경계와 고밀도 지역에서 오차 후보가 늘어납니다. 후보 생성·정확 거리·복합 검색의 책임을 나눠 속도와 판정 근거를 함께 유지합니다.
선택
장점
제약
적용 판단
Geohash prefix
키-값 shard와 cache key에 단순
경계·이웃 처리, 밀도 불균일
초기 cell cover와 shard key
H3 cell
계층·이웃·coarse 집계에 유리
해상도·경계·라이브러리 운영 필요
도시별 resolution과 분석 tier
Redis GEO
원/상자 후보 탐색을 빠르게 실험
정본·복합 권한·감사에 부족
hot cache 또는 단순 조회 tier
PostGIS
정밀 거리와 SQL 조건 결합
hot read 단독 대응은 쿼리 계획 검증 필요
정본, 정확 fallback, 검증 쿼리
OpenSearch geo
텍스트·속성·geo filter 조합
색인 지연·relevance·shard 비용
발견 검색·복합 필터 tier
거리 우선
설명 가능하고 privacy baseline이 단순
장소 품질을 반영하지 못함
기본 정렬과 relevance 비교 기준
05 · FAILURE MODES
경계·신선도·고밀도 도시의 실패를 따로 복구한다
# 장애 8가지
⌁index lag / version gap
새 POI가 늦게 보이거나 이전 위치가 후보 인덱스에 남습니다.
대응 · outbox 재처리와 version compare로 indexer를 복구하고, 정본 표본과 lag 0을 검증합니다.
≋hot cell stampede
도심의 한 셀에 request와 고밀도 후보가 몰려 cache miss와 fanout이 증폭됩니다.
대응 · single-flight, child cell split, category shard, stale 후보와 per-cell budget을 적용합니다.
◇이웃 cell 누락
커버 계산이 경계의 장소를 빼서 반경 안인데 0건 또는 누락 결과가 납니다.
대응 · boundary golden test와 canary로 검출하고 cover algorithm을 rollback합니다.
×거리/좌표 순서 오류
lat·lng 순서나 단위 오류로 반경 밖 장소가 반환되거나 전체가 사라집니다.
대응 · fail-closed, 좌표 범위 검증, Haversine·PostGIS cross-check로 막습니다.
!정책 tombstone 지연
숨김·폐업 장소가 stale cache나 색인에서 잠시 노출될 수 있습니다.
대응 · read-time deny cache, purge 재시도, revoke-to-hide SLO로 대응합니다.
▣cache / Redis 장애
fallback이 정본에 쏠려 검색 tier까지 timeout이 전파될 수 있습니다.
대응 · circuit breaker, candidate cap, rate limit, 제한된 fallback과 error budget을 둡니다.
↗shard 불균형
일부 도시·카테고리의 후보 수만 커져 tail latency가 왜곡됩니다.
대응 · per-cell QPS·candidate P99로 감지하고 re-shard·replica·resolution을 조정합니다.
$외부 provider quota
Places 보강 호출이 quota·SKU·FieldMask 변경으로 실패하거나 비용이 뛰어오릅니다.
대응 · 최소 FieldMask, quota alarm, provider breaker와 자체 정본 fallback을 사용합니다.
06 · OPERATIONS
privacy·관측·비용은 셀 인덱스 밖의 제품 계약이다
# 운영
◉보안·위치 개인정보
정확 위치는 목적·동의·보존 기간을 분리하고, 기본 trace와 장기 분석에는 coarse region을 씁니다. RBAC·감사 로그·radius/page 상한으로 운영자·스크래핑 위험도 함께 줄입니다.
precise location ≠ default log
⌁관측 가능성
tier별 p99, cache hit, cover cell 수, 후보 before/after filter, index lag, revoke-to-hide, hot cell, fallback ratio를 region·radius bucket 차원에서 봅니다.
nearby_latency_ms{tier}
₩비용 모델
cell 해상도는 인덱스 행·재색인을, 후보 수는 CPU를, 도시 replica는 RAM·egress를 키웁니다. 외부 Places는 FieldMask·SKU·정책 준수를 별도 비용 축으로 계산합니다.
index + cache + compute + provider
면접 모드 · 추가 질문06:00
“5,000만 POI에서 사용자의 1 km 안 카페를 찾아 주세요. Geohash/H3와 PostGIS·Redis·OpenSearch를 어떻게 나누고, 도심 hot cell, 정확한 원형 경계, 폐업 장소, 위치 privacy를 어떤 순서로 설명하겠습니까?”
cell 후보 + exact distance정본과 파생 indexcategory before rankhot cell splitcoarse observability
답변 구조 보기 5단계
공개 POI 반경 검색으로 범위를 고정하고 친구 위치와 경로 시간은 별도 시스템으로 둔다.
셀 cover는 후보 생성, 원본 좌표 거리 함수는 반경 판정, 정책은 노출 허용을 맡는다.
도심 hot cell은 해상도·카테고리 prefilter·지역 shard로 줄이되 임의 truncation을 피한다.
정본 변경은 versioned index와 revoke-to-hide 지표로 추적한다.
경계 좌표 recall, 후보 수, exact-distance p99를 같은 요청 표본으로 검증한다. 이번 선택: 공간 셀로 후보를 줄인 뒤 정확 거리와 정책으로 최종 판정한다. 깨지는 신호: 셀 경계 표본의 recall이 떨어지거나 도심 후보 수가 상한을 반복해서 넘는다. 다음 검증: 도시 밀도별 cell 해상도와 후보 상한을 replay해 누락률·p99·cache hit의 균형을 다시 정한다.