StudyCode
Подписки, посты, лайки — и почему «просто JOIN» умирает на миллионе пользователей. Fan-out, Redis-ленты, курсоры.
Спроектировать ленту новостей как в соцсети: ты подписан на людей, открываешь приложение — видишь их свежие посты, листаешь вниз, ставишь лайки. Звучит просто. Просто — ровно до первого миллиона пользователей. 😅
| Фича | Детали |
|---|---|
| Подписки | user A follows user B (односторонне) |
| Публикация | пост: текст + медиа, до пары тысяч знаков |
| Лента | посты тех, на кого подписан, свежие сверху |
| Лайки | счётчик у поста + «лайкнул ли я» |
Возьмём соцсеть среднего размера:
DAU (дневная аудитория): 10 млн
Открытий ленты на юзера в день: 5
Новых постов в день: 1 млн
Средне подписок на юзера: 200Прикидка нагрузки на чтение ленты:
10 млн × 5 открытий / 86 400 сек ≈ 580 RPS в среднем
пик (вечер) ×3 ≈ 1 700 RPSЗаписи постов: 1 млн / 86 400 ≈ 12 RPS. Соотношение чтение:запись — снова примерно 150:1.
Запомни соотношение 150:1 — вся архитектура ленты строится вокруг вопроса: где выполнять дорогую работу — при записи поста или при чтении ленты?
SELECT p.* FROM posts p JOIN follows f ON f.followee_id = p.author_id WHERE f.follower_id = :me ORDER BY p.created_at DESC LIMIT 20;