Upload
andrew-minkin
View
226
Download
8
Embed Size (px)
Citation preview
Собираем GPS-треки от водителей в такси раз в секунду, экономя трафикАндрей Минкин MadDevs
Кто я• Team Lead/Maddevs.io• Nambataxi.kg
• Nambafood.kg
• 10 лет опыта(Sysadmin, Python/Go)
• https://github.com/meshbird/meshbird
• https://github.com/maddevsio/ariadna
Бишкек• 100+ служб такси
• ~1M жителей
Namba taxi• 4 года на рынке
• Не менее 8к заказов в сутки
• 600+ водителей на линии
• 500к+ довольных клиентов
Что такое такси• Клиенты
• Водители
• Операторы
AVG response time• Водители 20 ms
• Операторы 2.5 ms
Предыстория
С чего мы начинали
Обновление местоположения• Водитель: раз в 15 секунд
• Клиент: раз в 15 секунд
А что еще происходит• Какой заказ сейчас выполняет
• Какой заказ будет следующим
• Есть ли открытые тревоги
Первые пробы• Делаем запрос – сохраняем координаты
• Делаем запрос – анимируем машину
Первые проблемы•Машинку колбасит
•Машинка едет по полям, лесам
Решение• OSRM
Пробуем еще• Таймаут – 15 секунд
• Делаем запрос – сохраняем координаты
•Шлем координаты
• Делаем запрос в OSRM – выдаем маршрут в OSRM
• Получаем маршрут – анимируем маркер
Проблемы• Одностороннее движение
Решение• Проверка на 20 метров
Релизнулись
Недочеты• Расчет стоимости – у водителя
• 1 трек в 15 секунд – мало
• Проблемы с GPS у водителя
Проблемы с GPS• Плохой девайс изначально
• GPS модуль умирает со временем
• Ямы и «глушилки»
Новые фичи• Хотим все это на главном экране
Вытекающие задачи• Собирать больше треков водителей
• Показывать ближайшие анимированные машины на главном экране
• Хранить промежуточную стоимость на сервере
• Экономить трафик водителю
• Собирать трек раз в секунду
Расходы водителя за смену в Бишкеке• 550 р бензин
• 200 р еда
• 200 р комиссия
• Средний чек – 100р
Расходы на интернет• 100 р на водителя за смену
• 100 000 р в день.
Что такое трек и как он выглядит• Latitude
• Longitude
• Session
• OrderID
• TripCost
Экономим трафик водителю• Уложить 1 трек в 100 байт
• И чтобы работало быстро
Огласите весь список, пожалуйста• HTTP
•WebSockets
• TCP
• UDP
Минусы http•Много хедеров
• 18 байт оверхеда (GET / HTTP/1.0<CR><LF> <CR><LF>)
• Работает поверх TCP
Минусы websocket• Работают поверх http
• Нужно сделать upgrade
• На установление соединения 2 запроса
• Нестабилен на плохом соединении
Минусы TCP
Минусы TCP• Долго• latency
• Дорого• 20 байт на пакет
Почему UDP•Шлем только датаграммы
• Гарантии не нужны
•Минимализм
Чем сериализировать?• JSON •MsgPack • Protocol Buffers
Размер данных
137
127
42
JSON
MsgPack
Protobuff
Итого• 42 байт пейлоада
• + 20 байт IP хедеров
• = 62 байт на трек
• = 2 мегабайта за смену
• = 6 рублей в деньгах
Хранение
Какие данные хранить?• Сессия водителя
• Номер борта
• ID заказа
• Сумма поездки
• Последнее местоположение
• N последних точек
Что есть• Percona
• Redis
• Elasticsearch
Нужен геоиндекс• KD-tree
• R-tree
Какие требования к геоиндексу• Поиск N ближайших точек
• Сбалансированное дерево
KD-Tree
Минусы KD-tree• Несбалансированное дерево
• Поиск только одной ближайшей точки
R-tree
Что не так с водителями• Плохая связь с интернетом
• Выключил телефон
• Села батарейка
• Выгрузил приложение из памяти
• И еще полдесятка причин
• Нужен Expire
• Нужен LRU для хранения координат
Как хранить• В памяти
• R-tree
• Карта с водителями (ключ сессия)
• Карта с водителями (ключ номер борта)
Какой алгоритм на бэкенде?• Получили пакет по UDP
• Получаем водителя со стораджа
• Если нет – получаем с Redis
• Проверяем, есть ли все нужные данные
• Делаем set в сторадже
Какой алгоритм на бэкенде?• Если есть – обновляем
• Если нет – инициализируем LRU для координат
• Обновляем инфу в R-tree
Варианты для реализации• Python
• Ruby
• Node.js
• Go
Go• Строго типизированный и компилируемый
•Маленький размер docker-контейнеров
•Малый расход ресурсов
•Меньше зоопарк
Как реализовывали• https://github.com/dhconnelly/rtreego
• LRU – навелосипедили
• UDP – stdlib
• https://github.com/golang/protobuf
• HTTP API
HTTP API• Ближайшие водители
• Удалить водителя (по номеру борта или сессии)
• Получить информацию о поездке
• Получить маршрут по водителю
Куда интегрировать• Бэкенд для водителей
• Бэкенд для клиентов
Как оно выглядит• Ядро – Django
• Водители – Twisted
• Клиенты - Django
А архитектурно
Nginx
AppBackend
Core
Core
AppBackend Core
Водители
Nginx
Twisted
Core
CoreTwiste
d Core
Водители
Водитель
Location backend Core
Twisted
Клиенты
Клиент
Location backend Core
App backend
Как эксплуатировать• Логи в stdout
•Метрики в Graphite
• Чеки в Sensu
• Полезный /status
• Боты
Полезный /status• Uptime since
• HTTP Statuses counters
• Total requests
Боты• Эмуляция движения водителя
• Эмуляция работы клиента
Как стало в мобильных приложениях• Получаем местоположение клиента
• Получаем ближайших водителей с маршрутом
• Анимируем каждую машинку
• Обновляем раз в 15 секунд
Сравнение результатов
Самый главный слайд• UDP+Protobuf для экономии трафика
• In-memory
• R-tree для выдачи ближайших водителей
• LRU cache для хранения последних координат
• OSRM для выравнивания треков на дороге
Вопросы• https://github.com/maddevsio
• https://github.com/gen1us2k
• Skype: gen1us2k