좌표·반경·limit 상한을 검증하고 최종 결과의 정확한 거리로 경계를 보장합니다.
주변 장소 검색
시스템 설계
주변 검색은 지도 위의 점을 단순히 모으는 문제가 아닙니다. 셀 인덱스로 후보를 충분히 작게 만든 뒤에도, 정확한 거리·공개 정책·카테고리·순위를 순서대로 판정하고 위치 자체는 가장 적게 다뤄야 합니다.
Geohash 또는 H3 셀은 후보를 찾는 출발점입니다. 실제 응답은 카테고리·공개 정책 → 정확 거리 → 랭킹으로 좁히며, 도심 hot cell은 resolution·shard·cache 동시성으로 따로 다룹니다. 정확 위치는 정본과 짧은 처리 경로에만 두고, 관측 데이터는 coarse bucket으로 낮춥니다.
반경·정책·정확성을 하나의 응답 계약으로 묶는다
사용자는 “800 m 안의 카페”를 요청하지만, 시스템은 원형 경계·카테고리·영업 상태·노출 권한·순서와 위치 처리 동의를 동시에 결정합니다. 후보가 빨라도 경계 밖 또는 비공개 장소를 반환하면 안 됩니다.
카테고리, 영업 상태, 테넌트·지역 노출 정책을 랭킹보다 먼저 필터합니다.
셀 후보 수와 fanout에 예산을 두고, hot cell에서도 fallback을 제한합니다.
정확 좌표·계정·IP를 장기 로그에서 기본적으로 결합하지 않고 coarse 관측을 사용합니다.
정본·파생 인덱스·정확성 판정을 분리한다
POI 정본은 versioned 변경 이벤트를 내보내고, 여러 후보 인덱스는 이를 재생성할 수 있는 파생 데이터로 유지합니다. 읽기 경로는 cell cover로 시작하지만 최종 응답 직전의 policy와 거리 검증이 진실의 경계입니다.
좌표를 오래 갖지 않고 후보를 좁힌 뒤 정확하게 답한다
권한, rate limit, 좌표 범위·반경·limit 상한을 확인하고 정밀도 정책을 적용합니다.
Geohash prefix 또는 H3 이웃 셀을 구해 원형을 충분히 덮는 후보 영역을 만듭니다.
cell + category shard와 cache를 조회해 제한된 POI ID·좌표·version만 가져옵니다.
공개 상태를 먼저 확인한 뒤 Haversine/PostGIS로 반경 밖 후보를 제거합니다.
거리·품질·영업 상태를 반영하고 카드에 필요한 필드와 coarse 관측만 남깁니다.
공간 후보, 정본, 복합 검색의 책임을 섞지 않는다
하나의 엔진이 모든 요구를 만족하지 않습니다. 선택 기준은 “무엇이 빠른가”보다 정확 거리, 카테고리·텍스트 필터, index lag, 감사와 운영 복구를 어디에서 책임질지입니다.
| 선택 | 장점 | 제약 | 적용 판단 |
|---|---|---|---|
| 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 비교 기준 |
경계·신선도·고밀도 도시의 실패를 따로 복구한다
새 POI가 늦게 보이거나 이전 위치가 후보 인덱스에 남습니다.
도심의 한 셀에 request와 고밀도 후보가 몰려 cache miss와 fanout이 증폭됩니다.
커버 계산이 경계의 장소를 빼서 반경 안인데 0건 또는 누락 결과가 납니다.
lat·lng 순서나 단위 오류로 반경 밖 장소가 반환되거나 전체가 사라집니다.
숨김·폐업 장소가 stale cache나 색인에서 잠시 노출될 수 있습니다.
fallback이 정본에 쏠려 검색 tier까지 timeout이 전파될 수 있습니다.
일부 도시·카테고리의 후보 수만 커져 tail latency가 왜곡됩니다.
Places 보강 호출이 quota·SKU·FieldMask 변경으로 실패하거나 비용이 뛰어오릅니다.
privacy·관측·비용은 셀 인덱스 밖의 제품 계약이다
정확 위치는 목적·동의·보존 기간을 분리하고, 기본 trace와 장기 분석에는 coarse region을 씁니다. RBAC·감사 로그·radius/page 상한으로 운영자·스크래핑 위험도 함께 줄입니다.
tier별 p99, cache hit, cover cell 수, 후보 before/after filter, index lag, revoke-to-hide, hot cell, fallback ratio를 region·radius bucket 차원에서 봅니다.
cell 해상도는 인덱스 행·재색인을, 후보 수는 CPU를, 도시 replica는 RAM·egress를 키웁니다. 외부 Places는 FieldMask·SKU·정책 준수를 별도 비용 축으로 계산합니다.
공식·1차 출처와 설계 가정
- Google Places — Nearby Search (New): 원형 위치 제한, 장소 type, FieldMask와 반환 계약.
- Google Places — Policies and attributions: Places 콘텐츠 캐싱·저장 예외와 attribution 정책.
- Redis — GEOSEARCH: 원/상자 내부 member 조회, 단위와 복잡도.
- PostGIS — ST_DWithin: geography 거리의 미터 단위와 index를 활용하는 거리 판정.
- OpenSearch — Geographic queries: geo_point, geodistance, bounding box와 geoshape query.
- H3 — Indexing functions: 위도·경도를 선택한 해상도의 셀로 바꾸는 `latLngToCell`.
- 이 페이지의 DAU·QPS·SLO·TTL·샤드/랭킹 기준은 학습용 설계 가정입니다. 실제 제품은 POI 밀도, 부하·장애 실험, privacy 법률과 공급자 계약을 재검토해야 합니다.
작성·검토·참고 자료
참고 자료
- Google Maps Platform — Nearby Search (New): type, 원형 `locationRestriction`, `rankPreference`, POST/FieldMask 계약의 공식 문서.
- Google Maps Platform — Policies and attributions for Places API: Places 콘텐츠의 캐싱·저장 예외와 attribution·privacy policy 요구사항.
- Redis — GEOSEARCH: 원 또는 상자 내부 member를 조회하는 명령, 단위와 복잡도 공식 문서.
- PostGIS — ST_DWithin: geometry/geography 거리 판정과 geography 미터 단위, spatial index 후보 사용에 대한 공식 문서.
- OpenSearch — Geographic and xy queries: `geo_point`, geo bounding box, geodistance, geoshape 등 geographic query 공식 문서.
- H3 — Indexing functions: `latLngToCell`로 좌표를 지정 해상도 셀로 변환하는 H3 공식 문서. 이 글의 DAU·QPS·SLO, TTL, 샤드 기준, 랭킹 식, fallback 순서와 retention 기간은 공개 벤치마크가 아니라 학습용 **설계 가정/제안**이다. 실제 서비스는 POI 밀도·법률·동의 UX·공급자 계약·부하와 장애 실험으로 이를 재검증해야 한다.
사실 오류·출처 정정은 문의·정정 페이지로 알려 주세요.