Раздел 11. Группы и фан-аут
Fan-out on write против fan-out on read; маленькие группы против огромных каналов; почему рассылка на миллион — отдельная задача.
До сих пор у сообщения был один получатель (пусть и с несколькими устройствами). В группах и каналах получателей много — и одно сообщение надо размножить на всех. Звучит просто, но именно здесь ломаются наивные решения, когда речь заходит про каналы-миллионники.
Само размножение одного сообщения на многих называют fan-out (можно переводить как «веер» или «рассылка многим»).
Две стратегии: размножать при отправке или собирать при чтении
Есть ровно два способа доставить сообщение в группу, и это главная развилка раздела.
Размножать при отправке (по-английски fan-out on write). Как только сообщение пришло в группу, мы сразу кладём его копию в ящик каждого получателя — в момент отправки.
- Плюс: чтение дешёвое. У каждого участника его сообщения уже лежат готовые в личном ящике, открыл чат — всё на месте, мгновенно.
- Минус: запись дорогая. Одно сообщение порождает столько записей, сколько получателей. Для группы на 1000 — тысяча записей на каждое сообщение. Для канала на 10 млн — десять миллионов записей за один пост. Это неподъёмно.
Собирать при чтении (fan-out on read). Храним сообщение один раз — в общем «ящике» группы. Когда участник открывает чат, он сам идёт и читает из этого общего места.
- Плюс: запись дешёвая — одна запись на сообщение, сколько бы ни было получателей.
- Минус: чтение дороже — при открытии надо собрать сообщения из общего места, и если читателей миллионы, это нагрузка на чтение.
Аналогия: «при отправке» — почтальон заранее разносит копию письма в каждый почтовый ящик. «При чтении» — повесили одно объявление на доску, и все приходят прочитать его сами.
Как сочетать: гибрид по размеру
В реальности берут оба подхода и переключаются по размеру:
- Маленькие и средние группы → размножать при отправке. Получателей немного, размножить дёшево, зато чтение мгновенное и работает ровно как личная переписка.
- Огромные каналы (десятки тысяч — миллионы) → собирать при чтении. Размножать пост на миллион ящиков при каждой отправке невозможно, поэтому храним его один раз, а подписчики подтягивают сами.
Это та же дилемма, что в лентах соцсетей: для обычных людей — рассылка при отправке, для «звёзд» с миллионами подписчиков — чтение из общего. Граница проводится по порогу числа участников.
Почему рассылка на миллион — отдельная задача
Один пост в канал-миллионник = потенциально миллион доставок. Размножать его «в лоб» при каждой отправке нельзя — это лавина записей и доставок за один пост. Поэтому большие каналы обрабатывают иначе:
- пост хранится один раз (как в «собирать при чтении»);
- доставка идёт «лениво» и растянуто, а не миллиону сразу в одну секунду;
- система пользуется тем, что большинство подписчиков офлайн или неактивны — не всем нужно сообщение прямо сейчас, многие увидят его позже, когда зайдут.
Здесь же всплывают знакомые вещи: «горячий шард» из Раздела 8 — это ровно про каналы-гиганты (один пост, но миллионы читателей бьют в один шард), лечится кэшированием и отдельными копиями для чтения. А медиа в большом канале раздаётся через CDN (Раздел 9).
Маленькая, но важная деталь
В группе умножаются не только сами сообщения, но и статусы: у каждого участника свои «доставлено» и «прочитано». В личке это две галочки, а в группе на 1000 — потенциально тысяча подтверждений на одно сообщение. Поэтому в больших группах детальную прочитанность по каждому часто упрощают или вовсе не показывают.
Вопросы интервьюера (с разбором)
«Как доставить сообщение в группу на 1000 человек?» Образец: «Для такой группы — размножение при отправке: в момент отправки кладу копию сообщения в ящик каждого из тысячи участников. Запись обходится в тысячу операций, но это терпимо, зато чтение мгновенное — у каждого его сообщения уже готовы. Онлайн-участникам сообщение проталкивается сразу через шину, офлайн заберут из своих очередей при входе.»
«А в канал на 10 миллионов?» Образец: «Тут размножать при отправке нельзя — это 10 млн записей и доставок за один пост. Переключаюсь на собирать при чтении: храню пост один раз в ящике канала, подписчики подтягивают его сами при открытии. Доставку растягиваю и опираюсь на то, что большинство подписчиков неактивны. Чтение разгружаю кэшем и репликами, медиа отдаю через CDN.»
«Когда писать в каждый ящик, а когда читать из общего?» Образец: «По размеру аудитории. Маленькие и средние группы — пишу в каждый ящик (дёшево размножить, чтение мгновенное). Большие каналы — храню один раз и даю читать из общего (дёшево писать ценой более дорогого чтения). На практике это гибрид с порогом: до некоторого числа участников — один режим, выше — другой.»
#мессенджер #группы #fan-out #каналы #масштаб #подготовка-к-интервью