Когда неидеальные системы хороши: кейс Bluesky
Разработчики часто стремятся к идеальности. Но иногда trade-off в виде отказа от идеального решения может дать значительные преимущества реальной системе.
В статье автор рассказывает, как снижение требований к консистентности уменьшило P99 latency на 96%. Автор работает в Bluesky — аналоге соцсети с короткими сообщениями (сами знаете, какой).
⭐️ Интересные идеи
➡️ Когда пользователь пишет пост в Bluesky, он вставляется fanout-ом в таблицы таймлайнов подписчиков. Таблица таймлайнов большая и шардирована по юзерам (таймлайн пользователя целиком лежит на конкретном шарде). Сами таймлайны периодически подчищаются от старых постов.
➡️ Шардов — несколько сотен, пользователей — 32 миллиона, и в среднем всё работает нормально. Проблемы начинаются, когда пользователи выбиваются из нормы — например, фоловят сотни тысяч человек. Такой пользователь сильно перегружает шард, ухудшая UX для десятков тысяч других пользователей.
➡️ Также возникают сложности, когда у пользователя очень много подписчиков (миллионы). Статистически, fanout на каждую 1000 запросов получает около 10 long-tail-запросов. При 2 миллионах подписчиков результат получается пугающим :)
➡️ Неидеальное решение для случая с большим количеством подписок: сделать таймлайн не совсем консистентным. При большом числе подписок пользователь вряд ли заметит, что лента не совсем хронологична или неполна (возможно, он вообще не будет её открывать). Поэтому инженеры ввели лимит подписок, до которого таймлайн строится корректно. При превышении этого лимита некоторые записи начинают отбрасываться, что ограничивает нагрузку на один шард. Расчёт: min(reasonable_limit / num_follows, 1).
➡️ Неидеальное решение для популярных пользователей: для выбора стратегии обновления таймлайнов важно знать, сколько у пользователя подписчиков. Но такие чтения сильно нагружали базу (при каждом посте популярного пользователя приходилось делать запрос). Инженеры закешировали количество подписчиков популярных аккаунтов в Redis и обновляли его раз в 30 секунд. Точное значение в моменте не критично, а кэш позволил значительно снизить нагрузку на базу.
Приятного чтения!
➖➖➖➖➖➖➖➖➖➖➖
// Понравился пост? Ставь 💛
// И обязательно подпишись на канал, чтобы не пропустить новые статьи
Post #53
375