Real-Time Backend

Live Location Tracking

Uber в пиковый час: 5M водителей отправляют GPS каждые 4 секунды. Это 1.25M обновлений в секунду. Каждое нужно принять, сгладить, сохранить в geospatial индекс и доставить всем заинтересованным потребителям. При этом ни одно уведомление не должно задублироваться.

  • **Uber** обрабатывает позиции 5M+ активных водителей через kafka -> location service -> Redis GEO. Kalman filter сглаживает GPS шум, map matching привязывает позицию к дорогам. На экране пассажира машина "едет по дороге", а не прыгает по кварталам.
  • **Google Maps Live Traffic** агрегирует анонимизированные GPS данные с Android устройств с активным картами. При 200M+ ежедневных пользователей в навигации - это крупнейший в мире real-time location pipeline. Данные используются для расчёта пробок с задержкой <2 минуты.
  • **DoorDash** использует geofencing для автоматического статуса "курьер прибыл к ресторану" и "курьер доставил заказ". Алгоритм учитывает GPS неточность: arrival фиксируется при входе в 50м зону и подтверждается через 30 секунд нахождения внутри (hysteresis).
  • **Find My (Apple)** реализует proximity alerts для AirTag через Bluetooth crowd-sourcing: сотни миллионов iPhone пассивно детектируют чужие AirTag и анонимно сообщают их позицию. Это позволяет трекеру работать без GPS и без мобильного соединения самого AirTag.

GPS Streaming: от сигнала к WebSocket

Uber в пиковые часы обрабатывает позиции 5M+ активных водителей одновременно. Каждый смартфон отправляет GPS-обновление каждые 4-5 секунд - это 1M+ обновлений в секунду на входе. Архитектурная задача: принять, обработать и доставить позиции заинтересованным потребителям с минимальной задержкой.

GPS-обновление содержит latitude, longitude, accuracy, bearing, speed и timestamp. Клиент iOS/Android использует `CLLocationManager` или `FusedLocationProviderClient` с accuracy hint: HIGH_ACCURACY (GPS, 1-10 м) vs BALANCED_POWER (cell+WiFi, 50-300 м) vs LOW_POWER (cell, 1-3 км). Uber использует BALANCED_POWER вне активной поездки и HIGH_ACCURACY во время неё.

Kalman filter - стандарт для сглаживания GPS: он учитывает uncertainty каждого измерения (поле accuracy) и плавно фильтрует выбросы. Простой average работает хуже: усредняет реальное движение. Реализация занимает ~50 строк для 2D случая.

Почему Uber использует клиентский timestamp из GPS и серверный timestamp при приёме - оба?

Geofencing: триггеры на пересечение границ

**Geofence** - виртуальная географическая граница. При пересечении генерируется событие ENTER или EXIT. Uber использует geofences для аэропортов (очередь водителей), Google Maps - для уведомлений "пора выходить", Airbnb - для автоматического чекина при приближении к объекту.

Алгоритмы проверки принадлежности точки полигону: Ray Casting (O(n) от числа вершин) для сложных полигонов, Haversine distance для круговых geofences. Redis GEO команды (`GEODIST`, `GEOSEARCH`) используют геохеш для эффективного поиска (O(log n)).

Hysteresis в geofencing предотвращает flapping: если граница пересекается туда-обратно из-за GPS шума, генерируются лишние события. Решение: добавить inner threshold (ENTER при 95% radius) и outer threshold (EXIT при 105% radius) - объект должен выйти за outer перед следующим ENTER.

Что такое geofence hysteresis и зачем она нужна?

Proximity Alerts: уведомления в реальном времени

Proximity alert - уведомление при сближении двух движущихся объектов. Uber: "водитель в 2 минутах". Google Maps: "автобус прибывает через 1 остановку". Задача сложнее geofencing: вместо статичной границы нужно отслеживать динамическое расстояние между двумя движущимися точками.

Наивный подход: при каждом обновлении позиции проверять расстояние до всех relевантных объектов. При 1M активных объектов - O(n^2) неприемлемо. Решение: Redis GEOSEARCH (geohash-based) для получения кандидатов в радиусе, затем точная проверка. Геохеш делает пространственный поиск O(log n).

ETA (Estimated Time of Arrival) отличается от расстояния: 500 м по прямой может быть 5 мин (пробка) или 1 мин (пустая дорога). Uber использует routing API с real-time traffic data. Google Maps Platform offers Directions API с departure_time=now для учёта трафика.

Зачем в proximity alert системе используется distributed lock с TTL (ALERT_COOLDOWN)?

Location Accuracy: GPS, клеточные сети и фильтрация

GPS точность варьируется: 1-3 м (идеальные условия, открытое небо), 3-10 м (городская среда), 50-100 м (в помещении, через окно). Потребляет 150-300 мВт. Клеточная триангуляция: 50-300 м, 5-20 мВт. WiFi positioning: 10-50 м в городе, 15 мВт. Google Fused Location Provider объединяет все источники для баланса точность/батарея.

GPS jumps - выбросы до 100+ м за одно обновление из-за multipath (отражения сигнала от зданий). Фильтрация: Kalman filter учитывает accuracy поля и скорость изменения позиции. Простая эвристика: если скорость между двумя точками > 200 км/ч - это jump, игнорировать.

Map matching - привязка GPS трека к дорожной сети. Uber использует Hidden Markov Model: GPS точка с accuracy 10 м может быть на любой из 5 близких дорог, HMM выбирает наиболее вероятную с учётом предыдущей позиции и скорости. Это устраняет артефакты "водитель едет сквозь здания".

Для точного location tracking достаточно брать последнюю GPS координату без обработки

Сырые GPS данные содержат jumps и шум; без Kalman filter и map matching трек выглядит как зигзаг и водители "едут сквозь здания"

Multipath эффект в городах даёт выбросы 50-100 м. GPS accuracy поле показывает uncertainty измерения - при accuracy=50 реальная позиция в пределах 50 м от reported. Kalman filter использует это поле как вес: при плохом accuracy он больше доверяет предыдущему сглаженному значению.

Почему Google Fused Location Provider переключается с GPS на cell+WiFi когда пользователь не двигается?

Итоги

  • **GPS pipeline**: клиентский timestamp (момент измерения) + серверный (момент получения) + Kalman filter + map matching - четыре обязательных компонента для production-качества tracking
  • **Geofencing** работает через Haversine для круговых зон и Ray Casting для полигонов; hysteresis (inner/outer порог) предотвращает event flapping при GPS шуме на границе
  • **Proximity alerts** масштабируются через Redis GEOSEARCH (O(log n) вместо O(n^2)) + distributed lock с TTL для дедупликации уведомлений при горизонтальном масштабировании

Связанные темы

Live location tracking пересекается с несколькими областями realtime-систем:

  • Collaborative Whiteboard — Схожая задача: синхронизация позиций множества движущихся объектов с разными QoS требованиями
  • Pub/Sub Messaging — Redis Pub/Sub или Kafka - транспортный слой для fan-out location updates к подписанным потребителям
  • WebSocket Architecture — Delivery канал для location updates на клиентскую сторону (карта пассажира, fleet management dashboard)

Вопросы для размышления

  • Как бы изменилась архитектура, если бы нужно было отслеживать не 5M водителей, а 500M пешеходов в реальном времени? Какие компоненты станут bottleneck первыми?
  • Uber Map Matching использует Hidden Markov Model для привязки к дорожной сети. Какие альтернативы существуют и в каких случаях они предпочтительнее?
  • Как privacy-preserving location sharing (анонимизация Apple Find My) меняет архитектуру по сравнению с centralized Uber-моделью? Какие функции становятся невозможными?

Связанные уроки

  • db-19-redis
Live Location Tracking

0

1

Войти