Как OpenAI держит 800 млн пользователей на одном PostgreSQL
800 миллионов человек пользуются ChatGPT каждую неделю. И все их данные — чаты, настройки, подписки — хранятся в одной базе данных. Не в десяти. Не в сотне. В одной.
Когда я это прочитал, первая мысль была: «Это невозможно». Обычно компании такого размера разбивают базу на много частей, чтобы справиться с нагрузкой. OpenAI этого не делает. И у них всё работает.
Как это вообще устроено
Давайте разберёмся с базовыми понятиями.
PostgreSQL — это база данных. Представьте огромную таблицу Excel, только умную: она умеет быстро искать, фильтровать и связывать данные между собой.
У OpenAI эта база работает по простой схеме:
КАК УСТРОЕНА БАЗА OPENAI
────────────────────────
┌─────────────────┐
Запись данных ──▶│ ГЛАВНЫЙ СЕРВЕР │
(новый чат, │ (primary) │
подписка) └────────┬────────┘
│
копирует данные на всех
│
┌──────────────────┼──────────────────┐
▼ ▼ ▼
┌───────────┐ ┌───────────┐ ┌───────────┐
│ Копия 1 │ │ Копия 2 │ │ Копия 3 │
│ (США) │ │ (Европа) │ │ (Азия) │
└───────────┘ └───────────┘ └───────────┘
│ │ │
└──────────────────┴──────────────────┘
│
... всего ~50 копий
│
Чтение данных ◀───────────┘
(открыть чат,
показать историю)
Primary (главный сервер) — единственный, кто может изменять данные. Когда вы отправляете сообщение в ChatGPT, оно сначала записывается сюда.
Реплики (копии) — серверы, которые только читают данные. Когда вы открываете историю чатов, запрос идёт к ближайшей копии, а не к главному серверу.
Почему так? Потому что читают данные в 100 раз чаще, чем записывают. Разделив нагрузку, можно обслужить больше людей.
Цифры, от которых голова кругом
- 800 миллионов активных пользователей в неделю
- 1 миллион запросов к базе каждую секунду
- ~50 копий базы по всему миру
- 10-20 миллисекунд — время ответа (это быстрее, чем вы моргаете)
За последний год нагрузка выросла в 10 раз. И они не развалились.
Три хитрости, которые спасают систему
1. Переиспользование соединений
Каждый раз, когда приложение хочет что-то спросить у базы, нужно установить соединение — как позвонить по телефону. Это занимает время.
OpenAI не «вешает трубку» после каждого запроса. Они держат пул готовых соединений и переиспользуют их. Время на подключение упало с 50 миллисекунд до 5. При миллионе запросов в секунду это экономит кучу ресурсов.
2. Защита от «стада»
Представьте: в кеше (временном хранилище) лежат популярные данные. Кеш устарел. Тысячи пользователей одновременно просят одни и те же данные. Все запросы летят в базу. База падает.
Это называется thundering herd (эффект стада) — когда толпа одновременно ломится в одну дверь.
ПРОБЛЕМА "СТАДА"
────────────────
БЕЗ ЗАЩИТЫ:
Кеш устарел → 1000 запросов → все в базу → 💥 авария
С ЗАЩИТОЙ:
Кеш устарел → 1000 запросов → 1 идёт в базу
→ 999 ждут
→ результат всем
Решение простое: первый запрос идёт в базу, остальные ждут. Когда данные получены — раздаём всем.
3. Гибридный подход: не всё в одну базу
OpenAI не запихивают всё в PostgreSQL:
- Новые таблицы в PostgreSQL запрещены — если нужно хранить что-то новое, используй другую систему
- Тяжёлые операции записи переезжают в Azure Cosmos DB (распределённая база от Microsoft)
- Остальное — агрессивно оптимизируется
Это как с квартирой: можно бесконечно запихивать вещи в одну комнату, а можно часть вынести в кладовку.
Драконовские правила для разработчиков
Самое интересное — не технологии, а дисциплина. OpenAI ввели жёсткие правила:
ПРАВИЛА РАБОТЫ С БАЗОЙ ────────────────────── ┌─────────────────────────────────────────────────┐ │ Изменение структуры таблиц │ │ ├─ Должно выполняться за 5 секунд │ │ ├─ Полная перестройка таблицы: ЗАПРЕЩЕНО │ │ └─ Только лёгкие изменения │ ├─────────────────────────────────────────────────┤ │ Запросы к базе │ │ ├─ Долгие запросы: автоматически убиваются │ │ ├─ Мешают обслуживанию? → убить │ │ └─ Сложные запросы на 12 таблиц: под запретом │ ├─────────────────────────────────────────────────┤ │ Массовое обновление данных │ │ ├─ Строгие лимиты скорости │ │ └─ Операция на неделю? Это нормально │ └─────────────────────────────────────────────────┘
Schema changes (изменение структуры) — это когда нужно добавить новый столбец в таблицу или изменить тип данных. В обычной жизни это просто. Но когда таблица весит терабайты и к ней каждую секунду идут тысячи запросов — одно неловкое движение может положить всё.
Backfill (массовое обновление) — это когда нужно обновить миллионы записей. Например, добавили новое поле и хотите заполнить его для всех существующих пользователей. OpenAI делают это очень медленно, чтобы не перегрузить базу.
История про один запрос
Отдельная история про ORM (Object-Relational Mapping — прослойка между кодом и базой, которая автоматически генерирует SQL-запросы).
Команда нашла один автоматически сгенерированный запрос, который объединял данные из 12 таблиц одновременно. Один запрос. Он вызвал несколько серьёзных аварий при скачках трафика.
Мораль: удобные абстракции могут генерировать чудовищные запросы. Особенно когда нагрузка растёт в 10 раз.
Почему они не разбили базу на части
Шардинг — это когда одну большую базу разбивают на много маленьких. Пользователи с именами на A-M в одной базе, N-Z в другой. Это решает проблему масштабирования, но создаёт новые:
- Как сделать транзакцию, затрагивающую несколько баз?
- Как искать данные, если не знаешь, в какой части они лежат?
- Как всё это поддерживать и не сойти с ума?
OpenAI решили, что проще:
- Выжать максимум из одной базы
- Новое выносить в другие системы
- Установить жёсткие правила для разработчиков
Что из этого следует
Если OpenAI с миллиардом запросов в день не торопится разбивать PostgreSQL — может, и вам не надо?
Скучные оптимизации работают. Переиспользование соединений, правильные индексы, убийство долгих запросов — это не модно, но это работает.
Дисциплина важнее архитектуры. Правило «изменение структуры за 5 секунд или не делаем» звучит жёстко. Но оно предотвращает аварии.
Не всё в одну корзину. PostgreSQL для одного, другая база для другого. Каждому инструменту — своя задача.
Ссылки
- Оригинальная статья OpenAI — полный технический разбор
- PostgreSQL — официальный сайт базы данных
- Azure Cosmos DB — распределённая база, куда OpenAI выносит новые данные