System Design Space
Граф знанийНастройки

Обновлено: 10 апреля 2026 г. в 17:55

Google Maps / Proximity Service — геопоиск

средний

Классический кейс геопоиска на карте: поиск точек рядом, пространственный индекс, региональные кэши, ранжирование и жёсткий бюджет задержки.

Геопоиск ломается не на формуле расстояния, а там, где пользователь двигает карту, а самые плотные районы одновременно создают самые тяжёлые всплески нагрузки.

Глава помогает связать геоячейки, региональный кэш, подготовку индекса, путь запроса и обновление POI в одну рабочую архитектуру, где важны и свежесть данных, и стоимость обновлений.

В интервью и архитектурных разборах этот кейс полезен тем, что заставляет объяснить, как искать по радиусу, как переживать горячие зоны и где проходит граница между точностью выдачи и скоростью ответа.

Геоячейки

Главный выбор здесь в том, как покрыть радиус соседними ячейками и не раздувать объём лишнего поиска по карте.

Горячие зоны

Центры городов, аэропорты и вокзалы создают локальные пики, поэтому кэш и разбиение нужно проектировать под перекос, а не под среднюю нагрузку.

Свежесть POI

Статус точки, часы работы и временные ограничения устаревают быстрее, чем сама геометрия, поэтому обновление метаданных нельзя откладывать на редкие батчи.

Региональный кэш

Кэш рядом с пользователем снижает задержку, но его нужно согласовывать с географическим разбиением и режимами деградации.

Источник

System Design Interview

Классический разбор Proximity Service как базового паттерна геопоиска в продуктовых системах.

Открыть обзор

Proximity Service отвечает на вопрос: что находится рядом с заданной точкой для выбранного радиуса и набора фильтров. Для такой системы критичны , работа с и всплески в районах, где внезапно появляется .

Даже если сами точки обновляются не каждую секунду, индекс всё равно должен выдерживать из-за инкрементальных апдейтов и пересборки соседних ячеек. Поэтому крупные инсталляции почти всегда опираются на и дополняют его обычным внутри региона.

Требования

На пользовательском уровне это выглядит как простой , но внутри он живёт под жёстким бюджетом . В крупных городах отдельные районы легко выходят на миллионы , поэтому проектировать нужно и под отзывчивость карты, и под сильный перекос нагрузки.

Функциональные

  • Пользователь двигает карту и сразу получает ближайшие POI в текущей видимой области.
  • Система умеет искать точки в радиусе, по категории и по текстовому запросу.
  • Поддерживаются пагинация и стабильный порядок результатов при сдвиге и масштабировании карты.
  • API подсказок (autocomplete) отделён от API деталей точки.
  • Статус точки, доступность и временные ограничения можно обновлять почти в реальном времени.

Нефункциональные

Задержка: p95 < 200ms

Карта не должна ощутимо тормозить при сдвиге, масштабировании и повторных запросах.

Доступность: 99.99%

Поиск продолжает работать даже при деградации части индекса или кэша.

Свежесть данных: минуты, не часы

Новые, закрытые и временно недоступные точки должны быстро попадать в выдачу.

Масштаб: миллионы запросов в секунду

Геораспределённый трафик идёт с сильным перекосом по районам и времени суток.

Высокоуровневая архитектура

Контур обработки запросов поиска рядом лучше жёстко отделять от подготовки индекса. Пользовательский путь живёт в отдельном контуре выдачи, где важно держать короткий и заранее определить , если кэш не прогрет или радиус неожиданно вырос.

Клиентские приложения

Карта, сдвиг, масштабирование и поиск по соседству

Шлюз геопоиска

Аутентификация, лимиты и маршрутизация по регионам

Контур выдачи

Работа с индексом, фильтрами и ранжированием

Горячий кэш

Redis/Memcached для частых геоячеек и категорий

Хранилище геоиндекса

S2/H3/Geohash и списки идентификаторов по категориям

База метаданных POI

Название, часы работы, рейтинг и бизнес-теги

Запрос идёт в две фазы: сначала система отбирает кандидатов по соседним ячейкам, а затем отдельно ранжирует их по расстоянию, релевантности и бизнес-сигналам.

Интерактивный разбор запроса поиска рядом

Меняйте категорию и радиус, затем проходите путь обработки по шагам.

Координаты примера: 37.7793, -122.4192

Шаг 1 из 5

Шлюз геопоиска: проверка и нормализация запроса

Сервис проверяет параметры запроса и отправляет его в ближайший рабочий регион.

Бюджет задержки: 15-25ms
  • Проверяет API-ключ, лимиты и обязательные параметры.
  • Нормализует lat/lng, радиус и локаль клиента.
  • Маршрутизирует запрос в ближайший регион геопоиска.
{
  "lat": 37.7793,
  "lng": -122.4192,
  "radius_m": 1500,
  "category": "cafe",
  "region": "us-west-1",
  "auth": "ok",
  "quota": "ok"
}

Выбор пространственного индекса

Здесь нет одной универсально лучшей структуры. Обычно это инженерный между точностью покрытия, удобством обновлений и ценой сложной геометрии на больших объёмах.

ПодходКогда особенно полезенКомпромиссы
GeohashБыстрый старт и хранение в простом слое «ключ-значение»Ячейки ведут себя менее ровно, а на границах чаще всплывают артефакты.
S2Глобальные карты и аккуратная работа с геометрией сферыТребует более внимательной реализации и сложнее в отладке.
H3Аналитику плотности, тепловые карты и агрегации по регионамПереход между уровнями детализации нужно настраивать очень аккуратно.
R-tree/QuadTreeТяжёлые пространственные запросы прямо в базе данныхОбновления дороже, особенно когда поток записей заметно растёт.

API и модель данных

Основной API

GET /v1/places/nearby?lat=37.78&lng=-122.41&radius=1500&category=cafe&limit=20

Response:
{
  "items": [
    { "place_id": "p123", "distance_m": 120, "score": 0.91 },
    { "place_id": "p889", "distance_m": 240, "score": 0.88 }
  ],
  "next_page_token": "..."
}

Индекс и метаданные

  • geo_cell_index: cell_id -> place_ids
  • poi: place_id, name, category, coords, rating, business_hours
  • popularity_signals: recent clicks/check-ins/reviews
  • change_log: события для инкрементальной переиндексации

Надёжность и типичные ошибки

Самая неприятная часть этого кейса в том, что нужно одновременно удерживать локальность чтения, приемлемую и понятный режим деградации, если часть геоиндекса или кэша временно недоступна.

Что помогает в эксплуатации

  • Региональное разбиение по диапазонам ячеек и репликация по зонам.
  • Двухуровневый кэш: пограничный слой для горячих зон и сервисный кэш внутри региона.
  • Понятная деградация на более грубую детализацию индекса вместо полного отказа.
  • Инкрементальная переиндексация вместо полного пересчёта всего набора точек.

Типичные ошибки

  • Смотреть только в одну ячейку и забывать про соседние клетки на границе радиуса.
  • Сортировать только по расстоянию и игнорировать рейтинг, релевантность и статус точки.
  • Смешивать рабочий контур выдачи с пакетной подготовкой индекса и метаданных.
  • Делать единый глобальный кэш без регионального разбиения и защиты от лавинообразных промахов.
  • Не удалять дубликаты POI, если данные приходят от нескольких поставщиков.

Инструмент

S2 Geometry

Практический инструмент для пространственной индексации по ячейкам на поверхности сферы.

Открыть сайт

Связанные главы

Чтобы отмечать прохождение, включи трекинг в Настройки