- A OpenAI expandiu em larga escala sua infraestrutura PostgreSQL para lidar com o forte aumento do tráfego do ChatGPT e da API, processando milhões de QPS com um único Azure PostgreSQL Flexible Server e cerca de 50 réplicas de leitura
- Mantendo uma arquitetura otimizada para cargas centradas em leitura, migrou parte das cargas de trabalho para o Azure Cosmos DB para aliviar a carga de escrita
- Diversas otimizações, como pool de conexões com PgBouncer, locking de cache, rate limiting e isolamento de workloads, melhoraram a estabilidade e a latência
- Para superar as limitações de uma arquitetura com primário único, foram conduzidos em paralelo testes de alta disponibilidade (HA), hot standby e replicação em cascata (cascading replication)
- Com essa abordagem, a empresa alcançou 99,999% de disponibilidade e latência p99 na faixa de dezenas de milissegundos, além de abrir caminho para futura expansão com PostgreSQL shardeado ou sistemas distribuídos
Visão geral da escalabilidade do PostgreSQL
- O PostgreSQL é o principal sistema de dados do ChatGPT e da API da OpenAI, e no último ano a carga aumentou mais de 10 vezes
- Um único primário e cerca de 50 réplicas de leitura distribuídas globalmente processam as requisições de 800 milhões de usuários
- Mantendo a arquitetura centrada em leitura, parte das cargas foi movida para o Azure Cosmos DB para reduzir a carga de escrita
- A adição de novas tabelas foi proibida, e novas cargas de trabalho passaram a ser alocadas por padrão em sistemas shardeados
Desafios da arquitetura com primário único e respostas adotadas
- Uma arquitetura com único escritor tem problemas de limite de escalabilidade de escrita e ponto único de falha (SPOF)
- O tráfego de leitura é distribuído para as réplicas, e o tráfego de escrita de workloads shardáveis foi movido para o Cosmos DB
- Uma configuração de alta disponibilidade com hot standby permite promoção rápida em caso de falha (failover)
- Quando a carga de leitura dispara, falhas de cache em massa podem saturar a CPU
- Foi introduzido um mecanismo de locking de cache para evitar consultas duplicadas sobre a mesma chave
Otimização de consultas e recursos
- Consultas complexas com múltiplos joins consumiam CPU em excesso e causavam lentidão no serviço
- O SQL ineficiente gerado pelo ORM foi revisado, e a lógica de joins complexos foi movida para a camada de aplicação
- A configuração idle_in_transaction_session_timeout foi usada para evitar consultas ociosas de longa duração
- Para resolver o problema de “noisy neighbor”, o tráfego foi separado em instâncias por prioridade
- O isolamento impede que requisições de baixa prioridade afetem serviços de alta prioridade
Gerenciamento de conexões e controle de carga
- Para contornar o limite de 5.000 conexões do Azure PostgreSQL, a OpenAI introduziu o PgBouncer como camada de proxy
- Com reutilização de conexões, o tempo médio de conexão caiu de 50ms para 5ms
- Para reduzir a latência de rede entre regiões, proxy, cliente e réplica foram colocados na mesma região
- Rate limiting foi aplicado nos níveis de aplicação, proxy e consulta para evitar picos bruscos de tráfego
- A camada de ORM também foi melhorada para permitir bloquear determinados query digests
Replicação e gestão de mudanças de esquema
- Como o primário precisa fazer streaming dos logs WAL para todas as réplicas, o aumento no número de réplicas eleva a carga de rede
- A equipe está testando replicação em cascata (cascading replication) em colaboração com a equipe da Azure
- Réplicas intermediárias retransmitem o WAL para réplicas subordinadas, abrindo a possibilidade de escalar para mais de 100 réplicas
- Mudanças de esquema que provoquem reescrita completa da tabela (full table rewrite) foram proibidas
- Apenas mudanças leves são permitidas dentro de um timeout de 5 segundos, e criação/remoção de índices podem ser feitas de forma concorrente
- Mesmo durante backfill, limites rigorosos de velocidade são aplicados
Resultados e próximos passos
- O PostgreSQL processa milhões de QPS, com latência p99 na faixa de dezenas de milissegundos e 99,999% de disponibilidade
- Nos últimos 12 meses, houve apenas um incidente SEV-0 (durante o lançamento do ChatGPT ImageGen)
- As cargas de trabalho restantes centradas em escrita também estão sendo gradualmente migradas para o Cosmos DB
- Após concluir a replicação em cascata, a OpenAI pretende reforçar a escalabilidade e a estabilidade das réplicas
- No futuro, a empresa avalia a possibilidade de adotar PostgreSQL shardeado ou sistemas distribuídos alternativos
1 comentários
Comentários do Hacker News
No PostgreSQL, queries idle de longa duração costumam causar problemas
Na base de código da empresa, havia muito o padrão “conectar → iniciar transação → fazer o trabalho → dar commit em caso de sucesso”
Esse método fazia com que os slots de conexão continuassem ocupados mesmo sem usar de fato o banco, e no fim foi preciso aumentar o número de conexões do Postgres para a casa dos milhares
Então adicionaram, no código Rust, uma verificação em tempo de compilação para que o compilador alertasse imediatamente se uma chamada
.awaitocorresse dentro de uma função async enquanto ainda estivesse segurando a conexãoCorrigiram mais de 100 pontos, mas graças a isso agora os testes de carga não ficam lentos mesmo rodando com um pool de 32 conexões em vez de 10.000
Reduzir o idle timeout também seria uma opção, mas a verificação estática foi uma solução muito mais confiável
O texto pareceu superficial demais e só repetia palavras-chave do tipo “nós fizemos sharding!”
Quase não havia detalhes e soava como frases feitas para SEO
A essência do texto pode ser resumida como “um único writer não escala, então reduzimos as escritas e separamos as leituras”
Quase não havia nada de novo, só mencionando abordagens comuns como otimização de queries, sharding e read replicas
O motivo de eu gostar do Postgres é que ele aguenta uma escala considerável simplesmente aumentando CPU e disco
Quando esse ponto chega, você já tem folga para contratar especialistas em sharding
Por isso, dizer que “para fazer sharding é preciso sair do Postgres” soa um pouco estranho
Por exemplo, há notícias de que a OpenAI ainda opera com prejuízos enormes e nem é certo se conseguirá aguentar até 2027
Sobre mudanças de schema e timeouts, em vez de apenas configurar timeout,
seria muito mais eficiente rodar em paralelo um script que encerra automaticamente transações em conflito durante o rollout do schema
Seria bom se o Postgres oferecesse isso nativamente — porque, em vez de ficar esperando sob locks pesados, em alguns casos é melhor cancelar parte das transações
Foi interessante por ser o primeiro texto do blog de engenharia da OpenAI
Gostaria de ver mais casos no futuro
Fiquei curioso sobre a configuração de replicação
Eles disseram que, mesmo com 50 read replicas, quase não houve atraso de replicação,
mas na prática é bem provável que algumas réplicas atrasem por picos de CPU ou memória
Nesse caso, o primário também pode ficar mais lento por causa da espera no envio do WAL
Havia um trecho dizendo que, “se um novo recurso exigir tabelas adicionais, ele vai para o Azure CosmosDB em vez do PostgreSQL”
Ou seja, parecia uma estratégia de manter o sistema existente e mover só os novos recursos para outro banco
Disseram que “aumentaram o tamanho da instância”, e isso despertou curiosidade sobre o nível disso
Quais CPUs e quanta RAM usam, se é a mesma instância disponível para usuários comuns, ou se é hardware customizado
Ex.: Azure Standard_E192ibds_v6 (96 cores, 1,8 TB de RAM, 10 TB de SSD, 3M IOPS)
Há modelos ainda maiores, como o Standard_M896ixds_24_v3, para SAP HANA, com 896 cores, 32 TB de memória e rede de 185 Gbps
Isso custa algo em torno de US$ 175 mil por mês, mas a OpenAI provavelmente recebeu um grande desconto
Pessoalmente, eu prefiro usar VMs HX176rs para servidor de banco
Graças ao cache HBM, a largura de banda de memória fica muito maior, e o desempenho foi bem superior ao de VMs comuns na mesma faixa de preço
Usar Azure PostgreSQL junto com CosmosDB deve ter um custo enorme
Ainda assim, este texto pareceu um dos relatos mais realistas de “escalar PostgreSQL”
Em vez de mexer no kernel ou hackear o código-fonte, foi uma abordagem operando em ambiente de nuvem padrão, o que tornou o caso mais fácil de se identificar