Проектирование Telegram
Проектирование Telegram
Введение
Telegram — мессенджер, построенный вокруг скорости, облачного хранения и открытости. По масштабу:
- ~950 млн активных пользователей в месяц
- ~200 000 новых пользователей ежедневно
- Каналы до 200 000+ подписчиков, некоторые — миллионы
- Супергруппы до 200 000 участников
- 15+ млрд сообщений в день
- Все сообщения хранятся в облаке (кроме Secret Chats)
Telegram часто сравнивают с WhatsApp, но архитектурные решения принципиально разные:
| Аспект | Telegram | |
|---|---|---|
| Хранение | На устройстве | В облаке |
| Шифрование | E2E по умолчанию | Облачное (E2E только в Secret Chats) |
| Протокол | Стандартный TLS + Signal | Собственный MTProto |
| Макс. группа | 1024 | 200 000 |
| Каналы | Нет | Да (broadcast) |
| Боты | Нет | Полноценная платформа |
| Мультиустройство | До 4 дополнительных | Неограниченно (облако) |
Эти различия приводят к совершенно другой архитектуре.
Требования
Функциональные требования
| # | Требование |
|---|---|
| FR-1 | Пользователь может отправить текст, медиа, стикеры, файлы (до 2 ГБ) другому пользователю или в чат |
| FR-2 | Поддержка групп до 200 000 участников |
| FR-3 | Поддержка каналов (broadcast — один пишет, миллионы читают) |
| FR-4 | Сообщения хранятся в облаке и синхронизируются между всеми устройствами |
| FR-5 | Secret Chats с E2E-шифрованием (device-to-device) |
| FR-6 | Поиск по сообщениям (полнотекстовый) |
| FR-7 | Платформа ботов с Bot API |
| FR-8 | Статусы: онлайн, набирает текст, записывает голосовое |
Нефункциональные требования
| # | Требование | Целевое значение |
|---|---|---|
| NFR-1 | Задержка доставки | < 100 мс (внутри DC), < 300 мс (между DC) |
| NFR-2 | Доступность | 99.99% |
| NFR-3 | Масштабируемость | ~1 млрд пользователей, 15+ млрд msg/day |
| NFR-4 | Хранение | Бессрочное облачное хранение всех данных |
| NFR-5 | Скорость синхронизации | Мгновенный доступ к истории с нового устройства |
| NFR-6 | Размер файлов | До 2 ГБ на файл |
Оценка масштаба
Сообщения
DAU: ~500 млн
Сообщений в день: 15 млрд
Сообщений в секунду: 15 000 000 000 / 86 400 ≈ 173 600 msg/sec
Пиковая нагрузка (×3): ~520 000 msg/sec
Хранилище сообщений (ОБЛАЧНОЕ — бессрочное!)
В отличие от WhatsApp, Telegram хранит все сообщения навсегда на серверах.
Средний размер сообщения с метаданными: ~300 байт
Текст в день: 15 млрд × 300 байт = 4.5 ТБ/день
В год: 4.5 ТБ × 365 ≈ 1.6 ПБ/год текста
За 10 лет работы: ~16 ПБ только текста
Медиа и файлы
~30% сообщений содержат медиа. Средний размер — 500 КБ, но хвост распределения — файлы до 2 ГБ.
Медиа в день: 4.5 млрд × 500 КБ ≈ 2.25 ПБ/день
Telegram — одна из крупнейших систем хранения данных в мире.
Каналы: проблема broadcast
Крупнейшие каналы имеют миллионы подписчиков. Пост в канале с 5 млн подписчиков — это потенциально 5 млн push-уведомлений одновременно.
Крупный канал: 5 000 000 подписчиков
Из них онлайн: ~10% = 500 000
Push для оффлайн: ~4 500 000
High-level архитектура
┌────────────────────────────────────────────────────┐
│ КЛИЕНТЫ │
│ iOS │ Android │ Desktop │ Web │ macOS │ Linux │
└───────────────────────────┬────────────────────────┘
│ MTProto (TLS + custom binary)
▼
┌──────────────────────────────────────────────────────┐
│ FRONTEND SERVERS │
│ (авторизация, роутинг, rate limiting) │
│ │
│ DC-1 (US) │ DC-2 (EU) │ DC-3 (Asia) │ DC-4/5 │
└─────────────┬─────────────┬─────────────┬────────────┘
│ │ │
▼ ▼ ▼
┌───────────────────────────────────────────────────────┐
│ MESSAGE ROUTERS │
│ (определяют, в каком DC хранятся данные чата) │
└────────────┬─────────────┬─────────────┬──────────────┘
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ STORAGE │ │ STORAGE │ │ STORAGE │
│ ENGINES │ │ ENGINES │ │ ENGINES │
│ (DC-1) │ │ (DC-2) │ │ (DC-3) │
│ │ │ │ │ │
│ ┌──────────┐ │ │ ┌──────────┐ │ │ ┌──────────┐ │
│ │Messages │ │ │ │Messages │ │ │ │Messages │ │
│ │Media │ │ │ │Media │ │ │ │Media │ │
│ │Users │ │ │ │Users │ │ │ │Users │ │
│ │Search idx│ │ │ │Search idx│ │ │ │Search idx│ │
│ └──────────┘ │ │ └──────────┘ │ │ └──────────┘ │
└──────────────┘ └──────────────┘ └──────────────┘
▲ ▲ ▲
│ Репликация между DC │
└─────────────┴─────────────┘
Ключевое отличие: привязка данных к DC
Telegram привязывает каждого пользователя к конкретному датацентру (DC). Все данные этого пользователя — сообщения, контакты, медиа — хранятся в его «домашнем» DC.
Пользователь из России → DC-2 (Европа, Амстердам)
Пользователь из США → DC-1 (США, Майами)
Пользователь из Азии → DC-3/4/5 (Сингапур)
Когда Alice (DC-1) пишет Bob (DC-2):
- Сообщение приходит на Frontend Server DC-1
- Message Router определяет, что Bob в DC-2
- Сообщение пересылается в DC-2 для записи
- DC-2 доставляет сообщение Bob
MTProto: собственный протокол
Telegram не использует стандартные протоколы (HTTP, WebSocket) для передачи сообщений. Вместо этого — собственный бинарный протокол MTProto.
Почему собственный протокол?
HTTP/JSON: MTProto:
{ Бинарный формат
"msg_id": 123, Минимальный overhead
"text": "Привет", Встроенное шифрование
"timestamp": ... Встроенная компрессия
} Мультиплексирование
≈ 150 байт overhead ≈ 16 байт overhead
Преимущества MTProto:
- Минимальный overhead — бинарный формат вместо текстового JSON/XML
- Встроенное шифрование — AES-256 + RSA-2048 + DH key exchange
- Мультиплексирование — несколько логических «каналов» внутри одного TCP-соединения
- Оптимизация для мобильных сетей — быстрый reconnect, минимальный handshake
Структура MTProto-сессии
┌──────────────────────────────────────────────┐
│ MTProto Session │
│ │
│ ┌─ TCP/UDP соединение ───────────────────┐ │
│ │ │ │
│ │ ┌── Auth Layer (шифрование) ───────┐ │ │
│ │ │ │ │ │
│ │ │ ┌── Transport Layer ─────────┐ │ │ │
│ │ │ │ │ │ │ │
│ │ │ │ messages │ │ │ │
│ │ │ │ updates │ │ │ │
│ │ │ │ file chunks │ │ │ │
│ │ │ │ acknowledgements │ │ │ │
│ │ │ │ │ │ │ │
│ │ │ └────────────────────────────┘ │ │ │
│ │ └──────────────────────────────────┘ │ │
│ └────────────────────────────────────────┘ │
└──────────────────────────────────────────────┘
Шифрование в MTProto (облачные чаты)
Облачные чаты (по умолчанию):
Клиент ◄──► Сервер: шифрование AES-256-IGE
Сервер расшифровывает → обрабатывает → зашифровывает → отправляет получателю
Сервер ВИДИТ содержимое сообщений.
Это позволяет: поиск, синхронизацию, уведомления с текстом
Secret Chats (опциональные):
Клиент ◄──► Клиент: E2E шифрование (DH key exchange)
Сервер НЕ видит содержимое
Ограничения: нет синхронизации, нет поиска, привязан к устройству
Хранение сообщений: облачная модель
Почему облачное хранение?
В отличие от WhatsApp, где сообщения хранятся на устройстве, Telegram хранит всё в облаке. Это даёт:
- Мгновенную синхронизацию — залогинился на новом устройстве → вся история доступна
- Поиск — серверный full-text search по всем сообщениям
- Неограниченная история — не зависит от памяти телефона
- Бесшовный мультиустройство — нет «основного устройства»
Цена — серверы видят содержимое (но Telegram утверждает, что данные зашифрованы на серверах и ключи хранятся в разных юрисдикциях).
Архитектура хранения
┌──────────────────────────────────────────────┐
│ STORAGE ENGINE │
│ ┌────────────────┐ ┌────────────────┐ │
│ │ Hot Storage │ │ Warm Storage │ │
│ │ (SSD, RAM) │ │ (HDD) │ │
│ │ │ │ │ │
│ │ Последние │ │ Старые │ │
│ │ сообщения │ │ сообщения │ │
│ │ (< 7 дней) │ │ (> 7 дней) │ │
│ └────────────────┘ └────────────────┘ │
│ ┌────────────────────────────────────────┐ │
│ │ Media Storage (S3-like) │ │
│ │ │ │
│ │ Фото: сжатые + оригиналы │ │
│ │ Видео: транскодированные + оригиналы │ │
│ │ Файлы: as-is, до 2 ГБ │ │
│ │ Стикеры: кешированные WebP/Lottie │ │
│ └────────────────────────────────────────┘ │
└──────────────────────────────────────────────┘
Схема данных сообщений
Telegram использует собственный хранилищный движок, но концептуально структура выглядит так:
Таблица: messages
┌──────────┬──────────────┬─────────┬──────────┬───────────┬──────────────┐
│ chat_id │ msg_id │ sender │ text │ media_ref │ date │
│ (shard │ (auto-incr │ │ │ │ │
│ key) │ per chat) │ │ │ │ │
├──────────┼──────────────┼─────────┼──────────┼───────────┼──────────────┤
│ c_1001 │ 42 │ u_alice │ "Привет" │ null │ 2026-03-24 │
│ c_1001 │ 43 │ u_bob │ null │ photo_xyz │ 2026-03-24 │
└──────────┴──────────────┴─────────┴──────────┴───────────┴──────────────┘
msg_id — монотонно возрастающий в рамках chat_id.
Это обеспечивает порядок и простую пагинацию: "дай сообщения с msg_id > 40"
Pts / Updates: система синхронизации
Telegram использует механизм pts (points) для синхронизации клиента с сервером:
Сервер хранит глобальный счётчик pts для каждого пользователя.
Каждое событие (новое сообщение, удаление, редактирование) увеличивает pts.
Клиент запоминает свой последний pts.
При reconnect: "Дай мне обновления с pts=1234"
┌──────────┐ ┌──────────────┐
│ Клиент │ pts=1234 │ Сервер │
│ │ ───────────────► │ │
│ │ │ current │
│ │ updates [ │ pts=1240 │
│ │ ◄────────────── │ │
└──────────┘ [1235..1240] └──────────────┘
pts=1240
(обновлён)
Если разрыв слишком большой (клиент был оффлайн долго), сервер отвечает getDifference — полный пакет текущего состояния.
Каналы: broadcast на миллионы
Каналы — уникальная фича Telegram. Это односторонний broadcast: администратор пишет, подписчики читают.
Проблема fan-out для каналов
Канал с 5 млн подписчиков. Каждый пост — это потенциально 5 млн уведомлений.
Наивный подход:
Пост → 5 000 000 push-запросов → APNs/FCM
Время: ~5 000 000 / 10 000 rps = 500 секунд = 8+ минут!
Решение Telegram: fan-out-on-read + lazy notifications
┌────────────────────────────────────────────────────┐
│ КАНАЛЫ │
│ │
│ 1. Пост сохраняется ОДИН РАЗ в storage чата │
│ │
│ 2. Подписчики видят пост, когда: │
│ a) Открывают Telegram (pull новых updates) │
│ b) Получают push (для включённых уведомлений) │
│ │
│ 3. Push отправляется БАТЧАМИ через очередь: │
│ Batch 1: users[0..10000] → APNs/FCM │
│ Batch 2: users[10001..20000] → APNs/FCM │
│ ... │
│ Batch 500: users[4990001..5000000] → APNs/FCM │
│ │
│ 4. Многие подписчики заглушили уведомления → │
│ реальный fan-out значительно меньше 5M │
└────────────────────────────────────────────────────┘
Оптимизация: контрреакция на горячие посты
Когда пост набирает тысячи реакций, каждая реакция — это обновляемый счётчик. Наивный подход — обновлять запись при каждой реакции — приведёт к write contention.
Решение: Buffered Counter
Реакция 1 ─┐
Реакция 2 ─┤
Реакция 3 ─┼──► Буфер (Redis) ──► Периодический flush в DB
Реакция 4 ─┤ (каждые 5 сек)
Реакция 5 ─┘
В буфере: post_12345: { "👍": +47, "❤️": +12, "😂": +8 }
Flush: UPDATE reactions SET count = count + 47 WHERE ...
Супергруппы: 200 000 участников
Супергруппы Telegram поддерживают до 200 000 участников — в 200 раз больше, чем WhatsApp. Это создаёт уникальные инженерные вызовы.
Архитектура супергруппы
Супергруппа — это по сути КАНАЛ + возможность писать для всех.
┌─────────────────────────────────────────────────────┐
│ СУПЕРГРУППА │
│ │
│ Хранение: │
│ - Сообщения хранятся централизованно (как канал) │
│ - НЕ копируются в inbox каждого участника │
│ │
│ Доставка: │
│ - Участники получают updates через pts │
│ - Lazy loading: клиент запрашивает сообщения │
│ при открытии чата │
│ │
│ Уведомления: │
│ - По умолчанию ОТКЛЮЧЕНЫ для больших групп │
│ - Только mentions (@user) генерируют push │
└─────────────────────────────────────────────────────┘
Различие обычная группа vs супергруппа
Обычная группа (до 200 участников):
┌──────┐ msg ┌──────┐
│ Alice│──────►│Server│──► Копия в inbox каждого участника
└──────┘ └──────┘ (fan-out-on-write)
Супергруппа (до 200 000):
┌──────┐ msg ┌──────┐
│ Alice│──────►│Server│──► Одна копия в shared storage
└──────┘ └──────┘ Клиенты читают при открытии
(fan-out-on-read)
Администрирование и anti-spam
С 200 000 участников модерация критична:
┌───────────────────────────────────────┐
│ MODERATION PIPELINE │
│ │
│ Сообщение ──► Anti-Spam Filter │
│ │ │
│ ├─ Regex patterns │
│ ├─ ML spam classifier │
│ ├─ Rate limiting │
│ │ (5 msg / 10 sec) │
│ ├─ Slow mode │
│ │ (1 msg / N секунд) │
│ └─ Banned words list │
│ │
│ Если spam → auto-delete + ban │
│ Если ok → доставка участникам │
└───────────────────────────────────────┘
Медиа и файлы: загрузка до 2 ГБ
Разбиение на части (Chunked Upload)
Файл до 2 ГБ нельзя загрузить одним HTTP-запросом. Telegram использует chunked upload через MTProto:
Файл: video.mp4 (1.5 ГБ)
Разбивается на части по 512 КБ:
Part 0: [0 .. 512 КБ)
Part 1: [512 КБ .. 1 МБ)
Part 2: [1 МБ .. 1.5 МБ)
...
Part 2999: [последний кусок]
Каждая часть загружается отдельным запросом:
upload.saveBigFilePart(file_id, part_num, total_parts, data)
Преимущества chunked upload:
- Возобновляемость — при разрыве соединения не нужно начинать заново
- Параллельная загрузка — несколько частей загружаются одновременно
- Прогресс — клиент показывает точный % загрузки
Хранение медиа
┌─────────────────────────────────────────────────┐
│ MEDIA STORAGE │
│ │
│ Входящий файл: │
│ → Дедупликация (по SHA-256 хешу) │
│ → Если фото: генерация thumbnails │
│ (s: 100px, m: 320px, x: 800px, y: 1280px) │
│ → Если видео: транскодирование (H.264, VP9) │
│ → Если стикер: конвертация в WebP/Lottie/TGS │
│ → Сохранение в distributed file system │
│ │
│ Реплики: минимум 3 копии в разных DC │
│ │
│ CDN: кеширование популярных файлов │
│ (с шифрованием — CDN не видит контент) │
└─────────────────────────────────────────────────┘
Дедупликация
Telegram активно дедуплицирует медиа. Если 1000 человек пересылают одно и то же фото — хранится одна копия:
User A загружает photo.jpg → SHA-256: abc123 → сохранено, file_id = F001
User B загружает то же photo.jpg → SHA-256: abc123 → найден дубликат → file_id = F001
User C пересылает от A → тот же file_id = F001
Результат: 1 копия вместо 3
Экономия: колоссальная при вирусном контенте
Полнотекстовый поиск
Telegram позволяет искать по тексту сообщений во всех чатах. При бессрочном хранении — это поиск по петабайтам данных.
Архитектура поиска
┌──────────────┐ "алгоритмы" ┌───────────────────┐
│ Клиент │ ────────────────► │ Search Service │
│ │ │ │
│ │ │ 1. Определить │
│ │ │ scope (чат?) │
│ │ │ │
│ │ │ 2. Запрос к │
│ │ │ Search Index │
│ │ результаты │ │
│ │ ◄──────────────── │ 3. Ранжирование │
└──────────────┘ └───────────────────┘
│
▼
┌───────────────────┐
│ Inverted Index │
│ (по user_id) │
│ │
│ "алгоритм" → │
│ [msg_12, msg_45,│
│ msg_89, ...] │
└───────────────────┘
Индексирование
Индекс партиционирован по пользователю — каждый пользователь может искать только в своих чатах:
Индексация нового сообщения:
1. Токенизация текста: "Привет, как изучать алгоритмы?"
→ tokens: ["привет", "как", "изучать", "алгоритмы"]
2. Стоп-слова фильтруются: ["как"] → удалено
3. Стемминг: ["алгоритмы"] → ["алгоритм"]
4. Обновление inverted index:
user_alice: "алгоритм" → [...existing, msg_new]
user_alice: "изучать" → [...existing, msg_new]
Боты: платформа Bot API
Telegram предоставляет мощный Bot API — боты могут отправлять/получать сообщения, создавать inline-клавиатуры, обрабатывать платежи и т.д.
Архитектура ботов
┌──────────────┐ ┌──────────────────┐
│ Пользователь │ │ Bot Server │
└──────┬───────┘ │ (разработчик) │
│ └────────▲─────────┘
│ сообщение боту │ Webhook / Long Polling
▼ │
┌────────────────────────────────────────┐
│ TELEGRAM SERVERS │
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Message │ │ Bot API │ │
│ │ Router │───►│ Gateway │ │
│ │ │ │ │ │
│ │ "это боту" │ │ HTTP/JSON │ │
│ │ → Bot API │ │ wrapper │ │
│ └──────────────┘ └──────────────┘ │
└────────────────────────────────────────┘
Bot API Gateway переводит внутренний MTProto в HTTP/JSON, который понятен разработчикам:
Webhook (push):
POST https://mybot.example.com/webhook
{
"update_id": 123456,
"message": {
"message_id": 42,
"from": { "id": 111, "first_name": "Alice" },
"chat": { "id": 222 },
"text": "/start"
}
}
Ответ бота:
POST https://api.telegram.org/bot<TOKEN>/sendMessage
{ "chat_id": 222, "text": "Добро пожаловать!" }
Secret Chats: настоящий E2E
Secret Chats — единственный режим с полноценным E2E-шифрованием в Telegram.
Отличия от облачных чатов
┌────────────────────┬──────────────────┬─────────────────┐
│ │ Облачный чат │ Secret Chat │
├────────────────────┼──────────────────┼─────────────────┤
│ Шифрование │ Клиент↔Сервер │ Клиент↔Клиент │
│ Хранение │ Облако │ Только на устр. │
│ Синхронизация │ Все устройства │ Одно устройство │
│ Пересылка │ Да │ Нет │
│ Поиск │ Да │ Нет │
│ Самоуничтожение │ Нет │ Да (таймер) │
│ Скриншот │ Без ограничений │ Уведомление │
└────────────────────┴──────────────────┴─────────────────┘
Протокол E2E (DH + AES)
Установка Secret Chat (Alice → Bob):
1. Alice генерирует DH-параметры (g, p, a)
2. Alice → Сервер: g^a mod p
3. Сервер → Bob: g^a mod p
4. Bob генерирует b, вычисляет shared_key = (g^a)^b mod p
5. Bob → Сервер: g^b mod p
6. Сервер → Alice: g^b mod p
7. Alice вычисляет shared_key = (g^b)^a mod p
shared_key у Alice = shared_key у Bob
Сервер знает g^a и g^b, но НЕ может вычислить shared_key
(Diffie-Hellman problem)
Шифрование:
AES-256-IGE(message, shared_key) → зашифрованный blob → сервер
Сервер пересылает blob получателю → расшифровка
Распределённые датацентры
География DC
┌─────────────────────────────────────────────────────┐
│ │
│ DC-1: Майами, США │
│ DC-2: Амстердам, Нидерланды (основной для EU/RU) │
│ DC-3: Майами, США (медиа) │
│ DC-4: Амстердам (медиа) │
│ DC-5: Сингапур (Азия) │
│ │
│ DC для тестов: DC-10xx (staging) │
│ │
└─────────────────────────────────────────────────────┘
Меж-DC маршрутизация
Alice (DC-2, Амстердам) пишет Bob (DC-1, Майами):
Alice ──MTProto──► DC-2 Frontend
│
│ "Bob в DC-1"
▼
DC-2 Router ──внутренний канал──► DC-1 Router
│
▼
DC-1 Storage
(сохраняет msg)
│
▼
DC-1 Frontend ──► Bob
Задержка между DC: 80-150 мс (зависит от расстояния). Для пользователей внутри одного DC — < 30 мс.
Репликация и отказоустойчивость
Каждый DC внутри:
┌──── Rack 1 ────┐ ┌──── Rack 2 ─────┐ ┌───── Rack 3 ────┐
│ Node A (лидер) │ │ Node B (реплика)│ │ Node C (реплика)│
│ Storage + CPU │ │ Storage + CPU │ │ Storage + CPU │
└────────────────┘ └─────────────────┘ └─────────────────┘
Запись: Node A (лидер) → реплицируется на B и C
Чтение: с любой ноды (eventual consistency)
Если Node A падает:
→ Выборы нового лидера (Raft / Paxos)
→ Node B становится лидером
→ Менее секунды на переключение
Масштабирование и оптимизации
Кеширование
┌───────────────────────────────────────────┐
│ L1: Клиентский кеш │
│ SQLite на устройстве │
│ Последние 1000 сообщений каждого чата │
└─────────────────────┬─────────────────────┘
│ cache miss
▼
┌───────────────────────────────────────────┐
│ L2: In-memory кеш │
│ Горячие данные в RAM на Frontend серверах │
│ Активные сессии, metadata чатов │
└─────────────────────┬─────────────────────┘
│ cache miss
▼
┌───────────────────────────────────────────┐
│ L3: SSD / HDD Storage │
│ Полная история сообщений │
│ Все медиафайлы │
└───────────────────────────────────────────┘
Connection Management
Один клиент → одно TCP-соединение → мультиплексирование через MTProto
Внутри одного соединения:
- Сообщения (приоритет: высокий)
- Updates (приоритет: высокий)
- Загрузка файлов (приоритет: низкий)
- Скачивание файлов (приоритет: низкий)
Для больших файлов — отдельное соединение к media-DC
Итого: ключевые решения
| Решение | Выбор | Обоснование |
|---|---|---|
| Протокол | MTProto (custom) | Минимальный overhead, встроенное шифрование, мобильная оптимизация |
| Хранение сообщений | Облачное (бессрочное) | Мгновенная синхронизация, поиск, мультиустройство |
| Шифрование | Облако: client↔server, Secret: E2E | Баланс между функциональностью и безопасностью |
| Каналы | Fan-out-on-read + lazy push | Масштабирование до миллионов подписчиков |
| Синхронизация | Pts-based | Минимальный трафик при reconnect |
| Медиа | Chunked upload, дедупликация, CDN | Файлы до 2 ГБ, экономия хранилища |
| Поиск | Inverted index, партиционированный по user | Приватный поиск без утечки data между пользователями |
| Боты | HTTP/JSON gateway поверх MTProto | Простой API для разработчиков |
| Датацентры | Привязка пользователя к конкретному DC | Локальность данных, быстрое чтение |
| Отказоустойчивость | Raft/Paxos внутри DC, master-slave между DC | Автоматическое восстановление < 1 сек |
Типичные вопросы на интервью
Q: Почему Telegram не использует E2E по умолчанию? A: Облачное хранение и синхронизация между устройствами невозможны с E2E. Это осознанный trade-off: удобство + поиск + бесшовный мультиустройство vs максимальная приватность.
Q: Как Telegram доставляет пост канала 5 млн подписчикам? A: Fan-out-on-read. Пост хранится один раз. Клиенты получают его при открытии приложения через pts-механизм. Push отправляется батчами только тем, кто включил уведомления.
Q: Как масштабировать группу до 200 000? A: Супергруппа = по сути канал с разрешённой записью. Сообщения хранятся централизованно, клиенты читают при открытии. Slow mode + anti-spam для контроля нагрузки.
Q: Как работает полнотекстовый поиск при петабайтах данных? A: Inverted index партиционирован по user_id. Каждый пользователь ищет только в своих чатах. Индекс масштабируется горизонтально — каждый DC индексирует данные своих пользователей.
Q: Зачем собственный протокол MTProto вместо gRPC/WebSocket? A: Минимальный overhead (16 байт vs 150+ для JSON), встроенное шифрование, мультиплексирование в одном TCP-соединении, оптимизация для нестабильных мобильных сетей. Ценой — сложность разработки клиентов.
Q: Как обеспечить E2E в Secret Chat? A: Diffie-Hellman key exchange для установки shared secret. AES-256-IGE для шифрования сообщений. Сервер видит только зашифрованный blob. Привязка к одному устройству (нет синхронизации).