2 pontos por GN⁺ 2 시간 전 | 1 comentários | Compartilhar no WhatsApp
  • Quack fornece comunicação entre instâncias do DuckDB, permitindo uma configuração cliente-servidor e o uso do mesmo banco de dados por vários escritores simultâneos
  • O DuckDB mantém sua arquitetura in-process, enquanto trata via protocolo remoto a sincronização de estado necessária quando vários processos modificam o mesmo arquivo
  • O Quack é um protocolo de requisição-resposta baseado em HTTP, usa serialização application/duckdb e autenticação por token, e a porta padrão é 9494
  • Nos benchmarks, o Quack transferiu 60 milhões de linhas em 4,94 segundos e, em testes de append pequeno, registrou cerca de 5.434 tx/s com 8 threads
  • O Quack planeja integração com o DuckLake, um servidor de Catalog remoto, instalação e carregamento automáticos, extensões de protocolo e um protocolo de replicação, com objetivo de lançamento em produção na época do DuckDB v2.0

Objetivo e contexto do Quack

  • Quack é um protocolo remoto que permite a comunicação entre instâncias do DuckDB, possibilitando executar o DuckDB em uma configuração cliente-servidor e permitir que vários escritores simultâneos usem o mesmo banco de dados
  • Desde 2019, o DuckDB vem enfatizando a arquitetura in-process; esse modelo, que opera com chamadas de API de baixo nível sem servidor nem protocolo separados, se encaixava bem em trabalhos interativos de ciência de dados, como notebooks em Python, e em oferecer recursos SQL dentro de aplicações
  • Para que vários processos modifiquem simultaneamente o mesmo arquivo de banco de dados DuckDB, é preciso sincronizar entre os processos muito do estado que o DuckDB mantém na memória principal
  • Até agora, havia abordagens indiretas, como um processo RPC separado, projetos que usam o Arrow Flight SQL protocol, o protocolo próprio da MotherDuck e combinações de PostgreSQL com pg_duckdb, como o “EleDucken”
  • Para expandir o DuckDB como uma ferramenta de processamento de dados de uso geral, um protocolo cliente-servidor pode abrir novos casos de uso além dos recursos in-process

Como usar o Quack

  • No Quack, duas ou mais instâncias do DuckDB se comunicam entre si, e o DuckDB atua tanto como cliente quanto como servidor
  • As duas instâncias podem estar em computadores diferentes, em locais remotos ou até em janelas de terminal diferentes no mesmo notebook
  • A extensão Quack está atualmente no repositório core_nightly e pode ser usada na versão de release atual, DuckDB v1.5.2
  • Na instância DuckDB do lado do servidor, depois de instalar e carregar o Quack, chama-se quack_serve; no exemplo, são usados quack:localhost e token = 'super_secret'
INSTALL quack FROM core_nightly;
LOAD quack;

CALL quack_serve(
    'quack:localhost',
    token = 'super_secret'
);

CREATE TABLE hello AS
    FROM VALUES ('world') v(s);
  • Na instância DuckDB do lado do cliente, também se instala e carrega o Quack, define-se o token com CREATE SECRET e conecta-se à instância remota com ATTACH 'quack:localhost' AS remote;
INSTALL quack FROM core_nightly;
LOAD quack;

CREATE SECRET (
    TYPE quack,
    TOKEN 'super_secret'
);

ATTACH 'quack:localhost' AS remote;
FROM remote.hello;
  • Com essa configuração, o DuckDB #2 pode consultar o valor world da tabela remota hello
  • Também é possível copiar dados da instância local para a instância remota; no exemplo, o DuckDB #2 cria a tabela remote.hello2, e o DuckDB #1 confirma com FROM hello2;
  • Em consultas complexas ou grandes conjuntos de dados, a função query, que envia a consulta diretamente ao lado remoto, oferece melhor controle sobre o que será executado remotamente
FROM remote.query(
    'SELECT s FROM hello'
);

Design do protocolo

  • Baseado em HTTP

    • O Quack foi construído diretamente sobre HTTP, que se consolidou como a camada de protocolo padrão de fato sobre TCP e camadas inferiores
    • A stack HTTP é otimizada com eficiência para transmissão de streams de mensagens e, quando bem implementada, tem baixo overhead
    • Há amplo conhecimento sobre como lidar com HTTP em áreas como balanceamento de carga, autenticação, firewall e detecção de intrusão
    • Por usar HTTP, a distribuição DuckDB-Wasm também pode usar o Quack nativamente
    • Um DuckDB executando no navegador pode se conectar diretamente, via Quack, a uma instância do DuckDB rodando em um servidor EC2
  • Padrão de requisição-resposta

    • As interações do Quack sempre funcionam em um padrão requisição-resposta conduzido pelo cliente
    • As mensagens incluem solicitação de conexão para autenticação por token, solicitação de execução de consulta, retorno da primeira parte da resposta e mensagens subsequentes de fetch para obter resultados grandes
    • Resultados grandes podem ser buscados em paralelo por várias threads
  • Serialização

    • Requisições e respostas são codificadas em um novo tipo MIME, application/duckdb
    • Essa codificação aproveita os primitivos internos de serialização do DuckDB para estruturas complexas, como tipos de dados e conjuntos de resultados
    • Os mesmos primitivos já são usados há anos nos arquivos WAL do DuckDB e passaram por bastante otimização e validação
  • Criptografia e forma de exposição

    • Ao iniciar o servidor, o Quack gera por padrão um token de autenticação aleatório, e o cliente precisa fornecer esse token
    • O servidor Quack, por padrão, faz bind apenas em localhost, embora isso possa ser sobrescrito
    • Por padrão, ele não usa SSL, pois foi considerado inadequado adicionar essa infraestrutura e dependências apenas para comunicação em localhost
    • Não é recomendado expor diretamente um endpoint DuckDB Quack à internet
    • Se for necessário expor o Quack na web, é fortemente recomendado usar um endpoint HTTP comum, como nginx, e deixar esse proxy terminar o SSL com Let’s Encrypt ou equivalente
    • O cliente Quack presume que SSL está habilitado para conexões não locais, embora esse comportamento possa ser sobrescrito
    • As configurações relacionadas estão na documentação de reverse proxy
  • Otimização do número de round trips

    • O Quack foi projetado para reduzir o número de round trips de protocolo necessários para uma consulta
    • Após a conexão, uma consulta pode ser processada em um único round trip, o que é vantajoso em ambientes sensíveis à latência
    • A transmissão de respostas grandes também foi otimizada, e a equipe do DuckDB considera o Quack atualmente a forma mais rápida de transferir tabelas por socket
    • Os benchmarks mostram que é possível transferir milhões de linhas em poucos segundos
  • Autenticação e autorização

    • O Quack projetou seu modelo de autenticação e autorização de acordo com a filosofia de extensibilidade do DuckDB
    • Ele fornece autenticação padrão e autorização padrão sem restrições, mas ambas podem ser substituídas por código fornecido pelo usuário
    • Ao iniciar, o servidor gera um token de autenticação aleatório, e o cliente fornece uma string de autenticação ao se conectar
    • O servidor chama um callback de autenticação; o callback padrão compara o token fornecido pelo cliente com o token gerado pelo servidor
    • O callback de autenticação pode ser substituído por configuração para usar consulta a diretório LDAP, leitura de arquivo de texto ou lógica arbitrária
    • A função de autorização também pode ser substituída; a função padrão permite todas as requisições
    • A função de autorização fornecida pelo usuário pode inspecionar cada consulta que o cliente pretende executar e tomar a decisão vinculando-a à string de autenticação usada anteriormente
    • Esses callbacks podem até ser escritos como macros SQL comuns
  • Porta padrão

    • O servidor Quack escuta por padrão na porta 9494
    • O 94 foi escolhido para remeter de forma fácil ao ano de lançamento do Netscape Navigator, 1994

Benchmarks

  • Os benchmarks foram executados em máquinas virtuais AWS rodando Ubuntu on Arm
  • O tipo de instância era m8g.2xlarge, com 8 vCPU, 32 GB de RAM e largura de banda de rede de “até 15 Gbps”
  • O objetivo era reproduzir um cenário real em que cliente e servidor estão no mesmo datacenter, mas em máquinas diferentes
  • As duas instâncias foram colocadas na mesma zona de disponibilidade, com ping médio de cerca de 0,280 ms
  • Transferência em massa

    • O primeiro benchmark mede a transferência em massa de muitas linhas por um protocolo de banco de dados
    • Os comparativos foram Quack, protocolo PostgreSQL e protocolo Arrow Flight SQL
    • O Arrow Flight foi oferecido pelo servidor GizmoSQL, que usa o DuckDB internamente
    • Foram transferidas quantidades crescentes de linhas da tabela TPC-H lineitem, chegando a 60 milhões de linhas
    • 60 milhões de linhas correspondem a 76 GB em formato CSV
    • Cada resultado foi reportado como o tempo de relógio de parede mediano de 5 execuções
    • Os principais resultados foram:
      • 100k linhas: DuckDB Quack 0.07 s, Arrow Flight 0.07 s, PostgreSQL 0.20 s
      • 1M de linhas: DuckDB Quack 0.24 s, Arrow Flight 0.38 s, PostgreSQL 2.20 s
      • 10M de linhas: DuckDB Quack 0.89 s, Arrow Flight 2.90 s, PostgreSQL 25.64 s
      • 60M de linhas: DuckDB Quack 4.94 s, Arrow Flight 17.40 s, PostgreSQL 158.37 s
    • O Quack transferiu 60 milhões de linhas em menos de 5 segundos, mostrando forte desempenho na transferência de grandes conjuntos de resultados
    • Mesmo o Arrow Flight SQL, voltado a esse objetivo, ficou atrás do Quack nesses resultados, e o protocolo baseado em linhas do PostgreSQL saiu em desvantagem de forma geral
    • Clientes PostgreSQL padrão não paralelizam leituras em várias threads, mas Quack e Arrow podem paralelizar
    • O cliente PostgreSQL do DuckDB também pode fazer leituras paralelas em alguns casos
  • Escritas pequenas

    • O segundo benchmark mede operações de append pequeno
    • Isso corresponde a cenários em que pequenas escritas são centralizadas, como ao reunir dados de observabilidade em uma instância central do DuckDB
    • É um teste desfavorável para protocolos que exigem várias idas e voltas cliente-servidor para concluir uma única transação
    • Foi criada uma tabela vazia com a mesma estrutura de TPC-H lineitem, e valores aleatórios foram inseridos uma linha por vez, cada um em sua própria transação INSERT
    • O teste foi executado por 5 segundos com número crescente de threads paralelas, repetido 5 vezes, e foi reportada a mediana de transações por segundo
    • Os principais resultados foram:
      • 1 thread: DuckDB Quack 1,038 tx/s, Arrow Flight 469 tx/s, PostgreSQL 839 tx/s
      • 2 threads: DuckDB Quack 1,956 tx/s, Arrow Flight 799 tx/s, PostgreSQL 1,094 tx/s
      • 4 threads: DuckDB Quack 3,504 tx/s, Arrow Flight 1,224 tx/s, PostgreSQL 2,180 tx/s
      • 8 threads: DuckDB Quack 5,434 tx/s, Arrow Flight 1,358 tx/s, PostgreSQL 4,320 tx/s
    • O Quack superou o PostgreSQL até 8 threads paralelas, alcançando uma taxa de cerca de 5.500 tx/s
    • Acima disso, chega-se ao limite atual do próprio DuckDB para o número de inserts simultâneos por segundo na mesma tabela
    • O PostgreSQL escala melhor nessa faixa, e a equipe do DuckDB vê isso como algo a ser analisado no futuro próximo
    • O Arrow Flight, como esperado, teve desempenho fraco e ficou em aproximadamente metade do desempenho do PostgreSQL
    • Os scripts de benchmark estão disponíveis publicamente

Casos de uso e significado para o DuckDB

  • O Quack possibilita um uso multiplayer do DuckDB, em que vários processos independentes podem modificar em paralelo o conteúdo das mesmas tabelas local ou remotamente
  • Algumas dessas capacidades já eram possíveis com o DuckLake, mas o Quack simplifica isso e oferece desempenho muito superior
  • Isso amplia o alcance de uso do DuckDB em cenários em que o estado central é mais importante do que consultas locais de latência ultrabaixa
  • A disseminação dos data lakes já mostrou que os dados nem sempre estão locais, e o Quack se encaixa nessa direção
  • O Quack será integrado ao DuckLake, permitindo que o próprio DuckDB se torne um servidor de Catalog acessível remotamente
  • Essa integração pode abrir novos recursos, como data inlining
  • Mais perguntas estão no FAQ do Quack
  • O DuckDB está se afastando de seu nicho inicial como banco de dados in-process para análise interativa e avançando mais em direção a um componente central da arquitetura moderna de dados

Por que não usar Arrow Flight SQL

  • Projetos relacionados, como Arrow e ADBC, têm valor como APIs de intercâmbio para reduzir o atrito na troca de dados entre sistemas, como ODBC e JDBC
  • Ainda assim, há cautela quanto ao uso de formatos de intercâmbio como Arrow dentro do próprio DuckDB
  • A estrutura interna dos resultados intermediários de consulta do DuckDB é, em alguns aspectos, próxima do Arrow, mas em outros bastante diferente
  • A visão é que, para continuar inovando em sistemas de dados, não se deve ficar restrito a formatos controlados externamente; por isso, o Quack usa serialização própria
  • Com serialização própria, é possível disponibilizar imediatamente novos tipos de dados ou novas mensagens de protocolo quando necessário
  • O Arrow Flight SQL tem um design em que toda consulta exige pelo menos dois round trips de protocolo, CommandStatementQuery e DoGet
  • Essa abordagem não é ideal para pequenas atualizações, especialmente em ambientes com maior latência
  • O Quack foi projetado para permitir, em consultas pequenas, execução e fetch do resultado em um único round trip

Planos futuros

  • O Quack será integrado ao DuckLake para que servidores DuckDB remotos possam ser usados como DuckLake catalog
  • Espera-se que essa integração melhore significativamente o desempenho, especialmente em inlining
  • Nos próximos meses, o plano é refinar o Quack e lançar a primeira versão para produção junto com o DuckDB v2.0, previsto para este outono
  • Também está nos planos permitir instalação e carregamento automáticos da extensão Quack quando necessário
  • Com o novo parser, também se pretende melhorar a sintaxe para o DuckDB conversar com bancos de dados SQL remotos
  • Do lado do core do DuckDB, o plano é aumentar significativamente o número de transações por segundo para permitir escalar muito além de 8 threads paralelas
  • Além de autenticação e autorização, também está sendo considerada a possibilidade de permitir extensões de protocolo do Quack, para que extensões do DuckDB possam adicionar novas mensagens de protocolo e código de processamento
  • Também está em estudo adicionar, sobre o Quack, um protocolo de replicação para replicar mudanças de instâncias DuckDB para outros servidores e formar um cluster de réplicas de leitura
  • O Quack e seu lançamento inicial também devem ser abordados em 24 de junho na conferência da comunidade DuckCon #7
  • Também há uma página separada do projeto Quack

1 comentários

 
GN⁺ 2 시간 전
Comentários no Hacker News
  • Eu estava querendo exatamente algo assim na semana passada, o timing foi perfeito
    Eu estava enviando valores de sensores para o DuckDB por um servidor em Deno, mas não conseguia inspecionar os dados com duckdb -ui sem derrubar o servidor
    Eu não queria adicionar funcionalidade ao servidor só para visualizar o conteúdo do DB, então ia simplesmente conviver com isso por enquanto, mas isso resolveu de forma elegante esse problema e outros parecidos que eu vinha tendo com DuckDB
    DuckDB é minha tecnologia favorita de 2025/26 e já está profundamente presente em vários fluxos de trabalho, como tarefas com LLM, armazenamento de dados, análise e pipelines de dados

    • Gostaria de ouvir mais detalhes sobre como você usa isso nos seus fluxos de trabalho
      Tenho bastante interesse, mas ainda não consegui encaixar o DuckDB de forma natural no meu jeito de resolver problemas, então também não sei bem a quais casos de uso ele pode se mapear
  • Muito legal. Eu estava avaliando usar DuckDB no framework interno de apps da empresa, e isso resolveu a questão de “então como eu faço escalabilidade horizontal?”
    Palmas para a equipe do DuckDB, e também gostei do nome do protocolo ser Quack

  • Eu estava trabalhando em um projeto open source para armazenar e consultar dados de observabilidade — métricas, logs e traces — em Parquet, e embora eu concorde fortemente com a ideia de usar formatos de armazenamento e catálogos abertos, eu estava frustrado com a usabilidade do Apache Iceberg
    Vendo isso, o DuckLake ficou muito mais interessante para o meu caso de uso, e estou animado para ver para onde isso vai
    https://github.com/smithclay/duckdb-otlp

    • Fiquei curioso se você está usando isso para substituir o Mimir
  • DuckDB é ótimo, mas eu não entendo bem o que ele quer ser
    Continuam surgindo novas formas de usá-lo, e não é fácil ter uma visão clara de qual delas faz mais sentido

    • DuckDB é autônomo e ao mesmo tempo um componente
      Esta tentativa é bem coerente, e em certo sentido o traz de volta a um modelo de uso familiar de banco de dados relacional tradicional cliente-servidor
      Um SGBD relacional originalmente era um sistema de concorrência multiusuário, e o DuckDB é um motor local extremamente rápido que pode ser embutido em outros sistemas, por isso tem tantos casos de uso diferentes
      É parecido com perguntar o que o SQLite quer ser. Ele está em celulares, navegadores, aplicativos desktop e dispositivos IoT, e as pessoas o expandiram em várias direções. A diferença aqui é que isso está sendo feito pela própria equipe, não por terceiros, e para mim é um movimento muito fácil de entender
    • Você só precisa encontrar o jeito que funciona para você
    • Nosso pipeline de dados gera arquivos .duckdb que o aplicativo baixa
      O app monitora recursos no S3 e faz o download quando o etag muda
      É fácil obter algo parecido com o desempenho de BigQuery ou ClickHouse sem precisar operar essa infraestrutura por conta própria nem pagar por ela
      Não é perfeito para todos os casos, mas dá conta de muito mais coisas do que eu esperava
    • Eu leio isso menos como “o DuckDB está tentando virar Postgres” e mais como ele se tornando a camada de execução dentro de um fluxo de trabalho maior
      Agora o motor em si nem sempre é o ponto problemático; o problema está ao redor. Banco vivo, caminhos no S3, arquivos Parquet, credenciais, execução reproduzível, exportação, validação e os momentos em que um script pontual silenciosamente vira infraestrutura
      O Quack deixa a parte remota/servidor mais organizada, mas a tendência maior parece ser o DuckDB virar menos uma ferramenta para usuário final e mais uma camada SQL dentro de outras ferramentas
    • Fora movimentação de dados, não me vêm muitos casos de uso em comum com Arrow Flight
  • Eles não explicaram o que querem dizer com “gravadores concorrentes”
    Pela aparência, parece que só estão serializando as escritas no lado do servidor

    • Acho que não é isso. O DuckDB já suporta escritas concorrentes dentro de um único processo
      Não vejo motivo para esse recurso de repente serializar todas as escritas
  • Parece útil para pequenos conjuntos de dados analíticos internos que você queira colocar em um servidor compartilhado da equipe
    Também vale bastante olhar isso para uso em homelab

    • Junto com DuckLake, isso escala bem até datasets de vários terabytes
      Uma grande vantagem desse protocolo de servidor é poder compartilhar um servidor com muita memória e aproveitar um cache compartilhado dos dados recentes
  • Eu tenho uma aplicação em C++ e, durante a execução, tudo fica em memória
    Entre sessões, ela grava em disco como XML e isso funciona bem, mas é estritamente para um único usuário, e alguns clientes querem generalizar isso para que vários usuários possam ler e escrever ao mesmo tempo
    A exigência de desempenho é baixa, algo como 2 ou 3 pessoas atualizando alguns milhares de registros ao mesmo tempo. Nesse caso, DuckDB + Quack seria uma boa escolha? Ou existe alguma opção melhor? Também olhei o SQLite, mas entendo que ele não funciona como cliente-servidor

    • https://firebirdsql.org existe discretamente há décadas entre o SQLite e um PostgreSQL de verdade, mas se você me perguntasse qual banco cliente-servidor usar, minha recomendação padrão seria PostgreSQL
    • DuckDB está mais para o lado analítico
      Acho difícil encontrar uma boa opção para lidar com usuários concorrentes sem hospedar de alguma forma um banco de dados no lado do servidor
      Claro, assim como alguns jogos implementam seu próprio cliente-servidor multiplayer, dá para fazer, mas sinceramente hospedar Postgres ou SQLite é absurdamente barato e fácil e, acima de tudo, é a abordagem padrão para esse problema
    • Isso parece um caso de uso que combina bem com CRDT, e ainda permitiria edição offline
    • Acho que o termo para pesquisar é local-first
  • Excelente. Eu estava usando DuckDB para criar um aplicativo de planilha colunar tipo Excel, e precisei reconstruir o “cliente” por cima de uma camada HTTP tradicional

  • Essa pergunta sobre “o que o DuckDB quer ser” continua aparecendo, mas para mim a resposta já está clara
    Ele quer ser o SQLite para análise. Embutível, sem necessidade de configuração e funcionando em qualquer lugar
    O Quack é só a parte que faz esse “em qualquer lugar” também incluir o remoto

    • Seria muito bom se a equipe do DuckDB mantivesse um cookbook oficial
  • Sobre “é possível usar o DuckDB com Quack como banco de dados de catálogo do DuckLake?”, está escrito “ainda não, mas estamos trabalhando nisso!”
    Parece um caso de uso de nicho, mas é o que mais me interessa
    Nosso lakehouse usa DuckLake e usa Postgres para o catálogo, mas um catálogo com DuckDB / Quack parece uma excelente alternativa

    • No futuro, o Quack provavelmente vai se tornar a principal opção para o catálogo do DuckLake
      Há vários motivos. Primeiro, não existe incompatibilidade de tipos no processamento inline. Quando se usa um catálogo que não é DuckDB, muitos tipos não têm mapeamento 1:1, então há overhead extra ao lidar com esses tipos de dados
      Segundo, você passa a ter o desempenho analítico do DuckDB e agora também o desempenho transacional diretamente sobre o catálogo. O DuckDB lendo DuckDB é simplesmente mais rápido do que nossos scanners de Postgres/SQLite
      Terceiro, não há ida e volta para retries. Toda a lógica de retry pode ser executada facilmente(tm) no lado do servidor DuckDB. Hoje, esses retries geram várias idas e voltas ao Postgres e isso vira gargalo de desempenho em cargas com muita contenção
      Para referência, sou desenvolvedor de duckdb/ducklake
    • Isso realmente está em andamento: https://github.com/duckdb/ducklake/pull/1151
      Deve dar para testar em alguns dias