open atlas
↑ К треку
Разборы System Design SDC · 04 · 08

Локация и реальное время: соберите живой сервис близости + лидерборд

Практический проект: соберите поиск рядом по пространственному индексу (запрос соседних ячеек), канал push в реальном времени по региону и backend лидерборда на отсортированном множестве — затем докажите корректность ранга и близости тестами.

SDC Senior ◷ 240 min
Уровень
ОсновыJuniorMiddleSenior

Прочитать, что нужно запрашивать соседние ячейки и держать ранг в отсортированном множестве — не то же, что собрать сервис, переживающий движущуюся нагрузку. Возьмите три примитива юнита — пространственный индекс, канал push по региону и отсортированное множество — и соберите небольшой, но реальный сервис локации и реального времени, затем докажите два свойства корректности, что вероятнее всего укусят: что близость находит соседа за границей и что ранг игрока верен среди миллионов.

Этот проект делает юнит операционным: вы реализуете запрос близости грубо-потом-точно, фанаут по региону, избегающий вещания, и движок ранга O(log n), затем пишете тесты, ловящие канонические баги — пропущенного соседа за границей и неверный глобальный ранг.

Проект
0 из 8
Цель

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

Требования
Критерии приёмки
  • Эндпоинт find-nearby, который на рандомизированных входах, включая точки у границ, возвращает ровно то же множество, что брутфорс-скан по расстоянию — демонстрируя, что запрос кольца соседей чинит проблему границы ячейки.
  • Измеренный hit-rate кэша на перекошенной нагрузке чтения с однострочной заметкой, почему кэширование по ячейке окупается на read-heavy, медленно меняющихся данных о местах.
  • Рабочее демо реального времени, где пинги движущейся сущности доходят лишь до подписчиков её текущей региональной ячейки (показано логом или счётчиком), с переключением подписки при пересечении границы и недоставкой локации не-другу.
  • Лидерборд, чьи операции обновления, top-k, мой-ранг и окно бегут без полного скана, с ничьями, решёнными детерминированно составным score.
  • Тест, доказывающий, что глобальный ранг при шардинге по диапазону очков равен брутфорс-отсортированному рангу для рандомизированных очков, плюс краткая заметка, как по-шардовые счётчики делают это O(шарды), а не кросс-шардовым сканом.
Senior-стретч
  • Добавьте адаптацию к плотности: переключите горячую переполняющуюся ячейку на более мелкое разрешение (или дробление quadtree) и покажите падение числа кандидатов на запрос, удерживая задержку плотной зоны ограниченной.
  • Добавьте крошечный компонент маршрутизации: постройте малый дорожный граф, сожмите его в иерархию и покажите, что двунаправленный поиск вверх возвращает тот же кратчайший путь, что наивный Dijkstra, раскрывая куда меньше узлов.
  • Добавьте адаптивную частоту пинга в канал реального времени (медленнее при покое сущности, быстрее при движении) и измерьте снижение записей против фиксированного интервала при равной воспринимаемой свежести.
  • Добавьте временны́е лидерборды (дневной / недельный / всё-время) как отдельные отсортированные множества и обсудите, как это уменьшает каждую доску и размазывает нагрузку записи.
Вспомните перед уходом
  1. 01
    Какие три примитива собирает этот проект, и что демонстрирует каждый?
  2. 02
    Как доказать два свойства корректности, и почему именно эти два?
  3. 03
    Почему собирать все три вместе, а не по отдельности?
Итог

Этот проект превращает юнит локации и реального времени в рабочую систему из трёх примитивов. Часть близости реализует поиск грубо-потом-точно по пространственному индексу — достать ячейку плюс кольцо соседей, фильтровать по точному расстоянию и кэшировать по ячейке на read-heavy нагрузке — и доказывается корректной против брутфорс-скана включая точки у границ, тест, вскрывающий баг одной ячейки. Часть реального времени хранит движущиеся сущности с TTL по ключу региональной ячейки, публикует по ячейке по постоянному соединению, переподписывается при пересечении границ и проверяет фильтр дружбы на краю-подписчике, а не вещает. Часть лидерборда использует отсортированное множество для O(log n) обновления, top-k, мой-ранг и окна, с тайбрейкером в составном score, и шардит по диапазону очков, так что глобальный ранг — внутришардовый ранг плюс счёты более высоких шардов — доказывается против брутфорс-сортировки. Сборка всех трёх вместе делает объединяющий урок осязаемым: та же абстракция региональной ячейки — это поисковый индекс, ключ маршрутизации и ось партиционирования, а верная структура всегда следует паттерну доступа.

Что-то непонятно?

Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.

хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.