Оптимизация работы эндпоинта
Часто так бывает, что новые фичи заводятся итерационным путём и сначала в формате "лишь бы оно работало". Со временем, когда руки для следующей итерации высвобождаются, появляется желание подобные фичи порефакторить.
Одну такую фичу я завёз на продакшн около полутора месяцев назад, а на этой неделе наконец-то дошли руки до оптимизации.
Проект ещё только находится на пути к выходу из MVP, но уже имеет несколько активных клиентов, данные которых прилетают к нам на сервера 24/7.
- мне надо было динамически рассчитывать статус текущего состояния некой установки, этих установок может быть несколько;
- в первой итерации статус рассчитывался через python и сохранялся в БД в момент совершения запроса на его получение.
Путь улучшения перфоманса выглядел так:
- я отрефакторил всё вручную и ускорил работу метода с 30 секунд до 12 секунд;
- я сходил в GPT, он отрицательно ускорил метод с 12 секунд до 20 секунд;
- я начал делать фоновый предрасчёт через celery и сократил тем самым работу метода аж до 68мс;
- количество данных в БД увеличилось (за 3 дня насоздавалось свыше 40 тысяч записей со статусами) и работа эндпоинта замедлилась до 40 секунд;
- я начал записывать результат предрасчёта в redis и вновь вернул время работы к значению в районе ~100мс.
Как можно было бы решить это иначе?
Вынести предрасчёт на уровень postgres (в другом месте этого же проекта уже есть view, которая динамически рассчитывает некоторые показатели), но поскольку накручивать триггеры в БД я не очень хочу, а сохранять новые статусы для истории и обновлённой инфографики может быть важно, было принято именно то решение, о котором я написал выше.
Какой вывод я для себя сделал?
Задним умом я понимаю, что не просчитал основной риск: количество записей может стать довольно большим за короткий срок и это отрицательно скажется на общей производительности эндпоинта.