Заранее строить в кэше ленту для каждого пользователя. Кэш вида (user_id, [post_id])
Для постов в малопопулярных сабреддитах использовать модель «Fanout on write». При которой id каждого нового поста копируется прямо в кэш ленты всех подписчиков.
Для постов в супер популярных сабреддитах использовать модель «Fanout on read». Добавляем посты из них в ленту пользователя на лету при запросе ленты.
Для малоактивных пользователей ленту в кэше не генерируем
Кэш в данном случае становится отдельной first-class сущностью. По сути это denormalized index. Имеет смысл его сохранять в хранилище, чтобы не пропал при отказе in-memory кэша.
Как быстро доставать посты, которые не попали в кэш?
Если используем RDBMS, то создаем большое количество асинхронных реплик. Master узел БД отвечает только за запись, все чтения по максимуму стараемся перенести на реплики.
Как вариант - использовать распределенное NoSQL решение для хранения постов.
Нужно ли использовать шардирование?
Reddit хранит в разных БД пользователей, посты, линки. Шардирование не используется. При записи в БД паралельно обновляется запись в кэше.