35 pontos por GN⁺ 2025-05-24 | 2 comentários | Compartilhar no WhatsApp
  • A OpenAI compartilhou na PGConf.dev 2025 como consegue usar PostgreSQL sem sharding e ainda assim lidar de forma eficiente com o tráfego de centenas de milhões de usuários
  • Para resolver o problema de gargalo de escrita, adotou várias abordagens, como distribuição de escritas, otimização de consultas e gestão de esquema
  • Entre os principais desafios citados estão limitações estruturais do PostgreSQL e dificuldades operacionais, como inchaço de tabelas/índices causado pelo design de MVCC e atraso de replicação provocado pelo WAL
  • Estratégias de otimização de consultas, como distribuição da carga de leitura, limitação de transações longas e uso mínimo de ORM, são centrais
  • A OpenAI alcançou 1 milhão de QPS com mais de 40 réplicas distribuídas geograficamente, garantindo alta disponibilidade mesmo em caso de falhas

Caso de escalabilidade em grande escala do PostgreSQL na OpenAI

Contexto

  • Muitos dos serviços centrais da OpenAI dependem do PostgreSQL
  • Se ocorrer uma falha no banco de dados, todo o serviço é diretamente afetado
  • No passado, já houve interrupções em serviços importantes, incluindo o ChatGPT, por problemas relacionados ao PostgreSQL
  • A OpenAI opera uma arquitetura Primary-Replica (uma Primary + mais de 40 Replicas) em um banco de dados gerenciado da Azure
  • Em um ambiente que atende 500 milhões de usuários ativos por mês, a escalabilidade é um fator-chave para o sucesso do negócio

Principais desafios

  • O tráfego de leitura pode ser distribuído entre várias Replicas, mas as requisições de escrita se concentram em uma única Primary, criando gargalo
  • Pontos principais de melhoria
    • Distribuir por offloading todas as escritas possíveis
    • Minimizar novos acessos adicionais ao banco Primary por parte de novos serviços
  • Pela própria estrutura do MVCC (controle de concorrência multiversão), há desvantagens como inchaço de tabelas/índices, tuning complexo da coleta de lixo e verificações de visibilidade em índices
  • À medida que o número de Replicas cresce, o tráfego de WAL (Write-Ahead Logging) também aumenta rapidamente, e a largura de banda de rede passa a ser outro gargalo

Medidas adotadas

Distribuição da carga no banco Primary

  • Previsão e mitigação da carga de escrita:
    • Offloading de todas as escritas possíveis
    • Prevenção de escritas desnecessárias no nível da aplicação
    • Aplicação de Lazy Write e ajuste do ciclo de backfill de dados
  • A carga de leitura é distribuída ao máximo para as Replicas; quando inevitavelmente precisa ser tratada na Primary, exige alta eficiência

Otimização de consultas

  • Transações longas ocupam recursos do sistema por muito tempo e atrasam a coleta de lixo
  • Aplicação de Timeout por sessão/consulta/cliente, com limitação de sessões Idle in transaction
  • Foi destacado que o uso de ORM pode aumentar a ineficiência, recomendando cautela
  • Foi realizada otimização de consultas complexas com múltiplos joins (ex.: join de 12 tabelas)

Mitigação de ponto único de falha (SPOF)

  • Se a Primary falhar, não é possível escrever; já as Replicas garantem continuidade de leitura mesmo com algumas falhas
  • Requisições importantes (alta prioridade) são tratadas em uma Replica dedicada, minimizando a interferência de requisições de baixa prioridade

Gestão de esquema

  • A criação de novas tabelas e a introdução de novas cargas de trabalho são limitadas no cluster
  • Adição/remoção de colunas só é permitida em operações leves dentro do limite de 5 segundos; operações que exigem reescrita completa da tabela não são permitidas
  • Criação/remoção de índices só é permitida com a opção CONCURRENTLY
  • Houve o problema de consultas longas com duração superior a 1 segundo bloquearem continuamente mudanças de esquema, exigindo otimização/offloading dessas consultas no nível da aplicação

Resultados operacionais

  • O cluster inteiro processa 1 milhão de QPS (leitura + escrita), sustentando os principais serviços da OpenAI
  • Mesmo com a adição de cerca de 40 Replicas, não houve aumento no atraso de replicação
  • Read-only Replicas foram distribuídas por diferentes regiões, mantendo baixa latência
  • Nos últimos 9 meses, ocorreu apenas 1 incidente SEV0 relacionado ao PostgreSQL
  • Foi garantida capacidade para suportar crescimento futuro

Casos de falha

  • Falha de cache com efeito cascata
  • Bug em que, sob alto uso de CPU, o processo WALSender para de enviar WAL e entra em estado de loop → causando atraso de replicação

Solicitações de melhoria de funcionalidades propostas ao PostgreSQL

  1. Gestão de índices: proposta de uma função de Disable para desativar índices desnecessários com segurança (para minimizar risco antes da exclusão)
  2. Observabilidade: solicitação de métricas baseadas em histogramas/percentis de latência, como p95 e p99
  3. Histórico de mudanças de esquema: necessidade de uma função para armazenar o histórico de alterações de esquema, como DDL
  4. Clareza no significado das views de monitoramento: questionamento sobre as causas e formas de resposta para sessões que permanecem por muito tempo no estado ClientRead
  5. Otimização de parâmetros padrão: os padrões do PostgreSQL são excessivamente conservadores, e foi solicitada a adoção de valores melhores ou heurísticas mais adequadas

Comentários de Lao Feng

  • A estratégia de escalabilidade da OpenAI nesse ambiente extremo é um caso prático valioso para os desenvolvedores do núcleo do PostgreSQL
  • Grandes serviços como o chinês Tantan também tiveram experiências semelhantes (33 Replicas, 400 mil QPS, adoção de sharding no lado da aplicação)
  • No ambiente atual de hardware de alto desempenho, isso sugere que uma expansão agressiva com um único cluster PostgreSQL, como a da OpenAI, é viável, e que um banco de dados distribuído não é necessariamente obrigatório
  • A OpenAI usa PostgreSQL gerenciado da Azure, mais de 40 Replicas, implantação cross-region e Kubernetes + PgBouncer
  • Mesmo com forte apoio da equipe do Azure PostgreSQL, ainda são essenciais a capacidade operacional de aplicação/DBA e a observabilidade
  • Foi mencionado o monitoramento via Datadog, junto com os custos e o impacto em desempenho
  • Know-how operacional, experiência com falhas e ativos de DBA são centrais para a qualidade do serviço

Perguntas e respostas de Lao Feng

Função de desativação de índices

  • Internamente no PostgreSQL, é possível desativar índices pelo campo indisvalid (mas isso exige privilégio de superuser e é limitado em ambientes RDS)
  • A alternativa prática é verificar o uso do índice via monitoramento e então removê-lo com segurança

Expansão de observabilidade: latência P95/P99

  • O suporte a métricas de percentis no pg_stat_statements é difícil por causa do overhead de memória, mas existem alternativas como pg_stat_monitor, eBPF e monitoramento de latência na camada de aplicação
  • Em ambientes gerenciados de PostgreSQL na Azure, algumas opções (acesso ao servidor, eBPF etc.) não são suportadas

Histórico de mudanças de esquema

  • É possível usar arquivos de log, pgaudit, CREATE EVENT TRIGGER, pg_ddl_historization etc. (mas isso exige privilégio de superuser e há limitações de suporte na Azure RDS)
  • O formato desejado é o armazenamento do histórico em uma system view/tabela consultável

Significado das views de monitoramento

  • A combinação State=Active + WaitEvent=ClientRead significa que, durante a execução de uma statement, o sistema está aguardando entrada do cliente; isso não é necessariamente um bug e pode ter várias causas
  • É possível minimizar efeitos colaterais com limite de duração de conexão (por exemplo, expiração de conexão na camada de rede com HAProxy e gestão do tempo de vida do pool de conexões no cliente), mas na Azure não está claro se isso é suportado

Parâmetros padrão

  • Os valores padrão do PostgreSQL são conservadores demais, mas isso pode ser compensado com heurísticas específicas por serviço ou tuning automatizado de parâmetros (RDS, Pigsty etc.)
  • Se futuramente ferramentas do PostgreSQL passarem a detectar e aplicar automaticamente as especificações de hardware, a carga operacional em campo deve diminuir

Opção de operação própria (self-hosting)

  • Na prática, muitos dos problemas operacionais derivam não do PostgreSQL em si, mas das limitações do serviço gerenciado da Azure
  • Em ambientes IaaS, montar por conta própria um cluster PostgreSQL baseado em SSD NVMe (como com Pigsty) aumenta a flexibilidade funcional e operacional
  • Foi mencionado que, com soluções como Pigsty, a maior parte das necessidades da OpenAI poderia ser resolvida de forma proativa, deixando espaço para considerar sua adoção conforme a escala e as exigências

2 comentários

 
GN⁺ 2025-05-24
Comentários do Hacker News
  • Participei da PGConf na semana passada e me impressionou que esta apresentação foi uma das sessões mais concorridas, especialmente porque era uma conferência mais introspectiva, em que a maioria das sessões estava focada no desenvolvimento do próprio Postgres, então este estudo de caso pareceu algo novo. Sempre vale lembrar que muitas equipes não sabem em profundidade como escalar certas partes da stack quando o produto cresce com sucesso, e esta apresentação foi avaliada como uma ótima história mostrando como uma equipe pequena supera problemas e aprende no processo. Em vez de reações simplistas como “não dá para fazer assim?”, passou de forma vívida a trajetória de crescimento e a enorme popularidade do produto por meio de uma história real de usuários, o que a tornou uma sessão perfeita para um evento mais voltado a desenvolvedores internos. A mensagem central da apresentação foi que, se não houver muitas escritas, é possível escalar o Postgres para uma capacidade gigantesca de leitura apenas com nós somente leitura (read replicas) e uma arquitetura de mestre único. A afirmação é que essa mensagem se aplica justamente à maioria dos aplicativos. No Q&A, as perguntas vieram principalmente de desenvolvedores do núcleo do Postgres querendo aprender com o caso de uso, quase sem intenção de criticar, e a impressão foi de que a comunidade Postgres é realmente muito gentil e aberta

    • Sobre a mensagem de que “se não houver muitas escritas, dá para ampliar bastante a taxa de leitura do Postgres com um único mestre e réplicas somente leitura”, alguém comentou que, ao fazer entrevistas de design de sistemas, percebeu que candidatos demais tentam introduzir estruturas distribuídas gigantescas ou sistemas que acabam quebrando a consistência até para sistemas simples com algo como 5 leituras por segundo. Dez milhões de usuários, na verdade, nem é uma escala tão grande assim. Mais gente do setor deveria perceber que, enquanto toda a indústria ficou obcecada por escalabilidade horizontal, o hardware real ficou mais rápido e maior do que se imagina. Vivemos num mundo em que é possível alugar na Amazon um servidor com 32 TB de RAM. Mesmo em escala, as garantias ACID continuam preciosas demais

    • Agradecimento dizendo que essa era exatamente a mensagem central que a apresentação queria transmitir (Bohan)

    • Pergunta sobre onde seria possível ver os slides ou a gravação da apresentação

    • Opinião de que este tópico pareceu um tanto duro com a equipe. Usuários experientes do HN nessa área têm interesse em como um serviço de grande porte como o ChatGPT foi escalado do ponto de vista arquitetural, e em como uma empresa com recursos quase ilimitados contrata. A interpretação é que a própria mensagem da apresentação, “ao usar ORM, é fácil acabar gerando queries ineficientes, então é preciso tomar cuidado”, já é uma evidência de que a equipe ainda não tem tanta experiência assim operando infraestrutura desse porte

  • Do ponto de vista da flexibilidade, fazer self-hosting de Postgres é atraente (uso de permissões de superusuário ou recursos avançados etc.), mas parece dar dor de cabeça operar isso diretamente. Seria bom se os provedores de nuvem também oferecessem de forma padronizada a função de desabilitar índices no planejador de consultas antes de realmente removê-los. Para empresas grandes, escolher self-hosting para customizar a stack parece perfeitamente razoável

    • Já existem várias formas de forçar ou desabilitar o uso de um índice específico no Postgres, e isso também pode ser usado em instâncias gerenciadas de Postgres na nuvem. Por exemplo, ajustar configurações do planejador por query (ex.: enable_indexscan=off), colocar operações aritméticas simples na cláusula where para evitar propositalmente o uso do índice, e também a extensão pg_hintplan (é possível dar dicas em comentários sobre qual índice usar, referência: https://pg-hint-plan.readthedocs.io/en/latest/hint_table.html#hints-for-scan-methods)

    • (Deixando claro que faz parte da equipe do Azure Postgres) a OpenAI não usa self-host, e sim o PostgreSQL gerenciado da Azure (Flexible Server)

    • O próprio palestrante da OpenAI (Bohan) esclareceu diretamente que o ambiente não é self-host, e sim Azure Database for PostgreSQL. Pediu desculpas por, embora tenha mencionado “Azure Postgres” várias vezes na apresentação, não ter deixado mais claro que se trata de um serviço gerenciado pela Microsoft

    • Opinião de que é surpreendente o Postgres não ter algo parecido com o DDL de MySQL ou MariaDB, onde um índice pode ser criado como INVISIBLE ou IGNORED para ser ignorado pelo planejador de consultas

    • Apenas citou o trecho original: “A vantagem do self-hosting postgres é a flexibilidade…”

  • Em resposta ao pedido por uma função de histórico de eventos de mudança de schema (adição/remoção de colunas etc.), foi informado que isso já pode ser implementado em tempo real usando EVENT TRIGGER, com exemplo disponível no Aquameta(https://github.com/aquametalabs/aquameta)

    • Explicação de que eles também estão implementando uma função de controle de histórico de mudanças DDL em seu próprio ambiente Postgres. O Postgres em si é poderoso e permite implementar isso de várias maneiras, mas controle de histórico e logs operacionais de bancos grandes ou críticos também são requisitos muito comuns. A maioria só percebe a importância disso depois de sentir na pele. E não apenas para mudanças DDL: quando políticas operacionais importantes são refletidas no sistema (por exemplo, mudanças em modelo de preços, customização de SKU/preço etc.), é indispensável garantir “auditabilidade”. Quando se projeta integralmente o modelo relacional, na aplicação real apenas algumas tabelas mudam com frequência, enquanto a maioria são tabelas “estáticas” que quase nunca mudam. Quando essas tabelas mudam, registrar esse histórico com cuidado ajuda muito a interpretar dados antigos ou fazer rollback

    • Nós (Xata) usamos tanto o pgroll(https://github.com/xataio/pgroll) quanto o pgstream(https://github.com/xataio/pgstream), ambos usando EVENT TRIGGER para detectar mudanças DDL e registrar histórico de migração de schema ou incluir eventos de mudança de schema no stream de replicação lógica. Porém, na maioria dos DBaaS baseados em Postgres, EVENT TRIGGER é parcialmente restrito por causa de permissões de superusuário; RDS/Aurora e Xata suportam, e o Supabase também está se preparando para suportar

    • Obrigado por lembrar do Aquameta, com uma provocação de que em breve virá um ótimo recurso novo

  • A alegação é de que esse conteúdo (criação concorrente de índices em larga escala, evitar reescrita de tabelas, distribuição de tráfego, timeout de transação, réplicas de leitura etc.) é praticamente essencial, quase senso comum, mesmo em operações muito menores do que a da OpenAI. Os pedidos feitos ao Postgres já vêm sendo feitos há muito tempo, e embora o título fale em “Next Level”, na prática parece mais um esforço desesperado para continuar escalando mantendo um mestre único [em uma situação com restrições para novas cargas de trabalho]. O ponto central seria conseguir aguentar bem carga massiva de leitura, mas isso em si já é o padrão clássico com réplicas de leitura e distribuição horizontal. O método de desabilitar índices (mexendo no campo interno indisvalid) também é um truque não oferecido oficialmente, e há um alerta de que esse tipo de ajuste no catálogo do sistema é perigoso. A sugestão de verificar o uso de índices em views de monitoramento e então removê-los também não é solução perfeita; para saber com mais clareza quais índices são necessários ou desnecessários, seria preciso verificar também os planos de execução para ter confiança

    • O TFA (artigo original) diz que a OpenAI está processando 1 milhão de queries por segundo na Azure, e isso é interpretado como algo bastante impressionante em ambiente real de nuvem, especialmente com armazenamento baseado em rede. Ainda assim, como o total está distribuído por cerca de 40 réplicas de leitura, dá algo como 25 mil QPS por instância, então não parece tão surpreendente assim. Sobre a discussão do uso de índices, a explicação é que, se você entende direito as estatísticas recentes e as características do banco, basta verificar qual índice faz sentido usar e se as condições/projeções da query seguem bem o left-most prefix do índice

    • É criticado que não houve nenhuma explicação sobre por que a OpenAI não faz sharding do Postgres, o que parece frustrante. Só fazer sharding por usuário já parece que resolveria o problema de forma muito mais simples, então fica a dúvida de por que insistem em mestre único

  • Parece que eles usam replicação física, e alguém comentou que está pensando em migrar para replicação lógica para reduzir custos (especialmente tráfego de saída entre regiões). Como a replicação lógica nativa parece ter evoluído bastante depois do Postgres 17, perguntou se isso já vale a pena em produção

  • Foi apontado que, para lidar com diferentes tipos de query, provavelmente eles também usam outros mecanismos de armazenamento em paralelo (chave-valor, busca, busca vetorial, cache etc.), então é estranho que a apresentação tenha se concentrado apenas em Postgres. A suposição é de que, na prática, internamente eles devam usar várias estratégias para distribuir tráfego e carga

  • Pensamento de que talvez fosse possível obter desempenho melhor operando diretamente apenas a instância de escrita em servidor dedicado com SSD local rápido, enquanto as leituras ficariam só no serviço gerenciado

  • Defesa enfática de que “precisam fazer sharding do banco”. A opinião é que só com sharding por usuário/organização já daria para resolver de forma simples os principais problemas atuais. A reclamação é que tentar vários contornos complexos acaba sendo dar uma volta maior

    • A apresentação defendia justamente que, mesmo sem sharding, é possível escalar para uma capacidade enorme mantendo apenas a arquitetura de mestre único, e que sharding obviamente foi considerado, mas os trade-offs não compensaram, já que a estrutura atual ainda escala

    • Resposta direta do palestrante da OpenAI (Bohan): a carga de trabalho não é algo fácil de shardear, e as cargas com muitas escritas já foram separadas do PostgreSQL e tratadas em shards, de modo que o que restou é quase somente leitura; por isso, introduzir sharding agora exigiria um esforço enorme. No momento, a avaliação é que só com Azure Database for PostgreSQL já há escalabilidade suficiente e margem para absorver o futuro. Ainda assim, a ideia não é descartar completamente sharding no longo prazo, apenas não é prioridade de curto prazo

    • Argumento de que sharding não é tão simples quanto parece. O motivo para usar um banco poderoso é justamente poder fazer análises e consultas complexas nos dados; se a ideia fosse apenas armazenar e distribuir, seria mais simples usar vários mounts NFS

    • Feedback mais pé no chão dizendo que não é algo simples mandar “aplicar sharding” em um banco monstruoso que faz um milhão de queries por segundo. Chave por organização até parece natural, mas, nessa escala, nada é realmente simples

    • Resposta concordando fortemente com o argumento acima

  • Sobre o comentário da apresentação de que é preciso tomar cuidado ao usar ORM, alguém disse que acha que todo ORM (especialmente ORM multiplataforma para vários bancos) é um problema. O uso de ORM faz as pessoas pensarem os padrões de dados apenas no nível do código da aplicação e, no fim, impede quase todo o aproveitamento dos recursos poderosos que cada banco oferece. Essa pessoa não usa ORM nenhum e prefere explorar ativamente queries e recursos específicos do Postgres, concentrando-se no poder do banco mais do que na linguagem ou na conveniência. A conclusão é que escrever um bom SQL diretamente traz mais felicidade para o sistema inteiro

    • Experiência de que, ao migrar de DB2 para psql no passado, o ORM ajudou muito a minimizar o downtime. Graças ao ORM, a troca do banco foi transparente, quase não foi preciso mexer na maior parte da lógica, e nem todo desenvolvedor está acostumado a escrever queries diretamente; quando queries ficam misturadas no código, refatorar e entender tudo pode ficar muito difícil. A ideia é que o SQL acabará sendo abstraído como uma biblioteca

    • Depois de usar o Django ORM por muito tempo e considerá-lo um software excelente, alguém comentou que recentemente passou a usar sqlc e sente que gerar código Go diretamente a partir das queries é um ponto de equilíbrio ideal entre ORM e SQL puro

    • Posição de que a outra pessoa simplesmente ainda não teve contato com um ORM realmente bom (por exemplo, Entity Framework Core)

  • Comentário leve dizendo que o título “Scaling PostgreSQL to the Next Level at OpenAI” parece ser o título que realmente combina com a apresentação

 
ddogi 2025-05-25

Parece que produtos comerciais com suporte a múltiplos writes, como Oracle RAC ou DB2 pureScale, nem estão sendo considerados.