2 points par GN⁺ 2 시간 전 | 1 commentaires | Partager sur WhatsApp
  • Quack fournit une communication entre instances DuckDB, rendant possible une configuration client-serveur et l’utilisation de la même base de données par plusieurs rédacteurs concurrents
  • DuckDB conserve son architecture in-process, tout en gérant via un protocole distant la synchronisation d’état nécessaire lorsque plusieurs processus modifient le même fichier
  • Quack est un protocole requête-réponse basé sur HTTP, qui utilise la sérialisation application/duckdb et une authentification par jeton, avec le port par défaut 9494
  • Dans les benchmarks, Quack a transféré 60 millions de lignes en 4,94 secondes, et a aussi atteint environ 5 434 tx/s sur un test de petits append avec 8 threads
  • Quack prévoit l’intégration avec DuckLake, un serveur de Catalog distant, l’installation et le chargement automatiques, des extensions de protocole et un protocole de réplication, avec une sortie en production visée autour de DuckDB v2.0

Objectif et contexte de Quack

  • Quack est un protocole distant qui permet aux instances DuckDB de communiquer entre elles, afin d’exécuter DuckDB dans une configuration client-serveur et de permettre à plusieurs rédacteurs concurrents d’utiliser la même base de données
  • Depuis 2019, DuckDB met en avant une architecture in-process : fonctionner via des appels d’API de bas niveau, sans serveur ni protocole séparés, convenait bien aux tâches interactives de data science comme les notebooks Python et à l’intégration de fonctionnalités SQL dans les applications
  • Pour que plusieurs processus modifient simultanément le même fichier de base de données DuckDB, il faut synchroniser entre les processus une grande quantité d’état que DuckDB conserve en mémoire principale
  • Jusqu’ici, il existait des solutions de contournement comme un processus RPC séparé, des projets utilisant le protocole Arrow Flight SQL, le protocole propriétaire de MotherDuck, ou encore “EleDucken”, qui combine PostgreSQL et pg_duckdb
  • Pour étendre DuckDB en outil généraliste de traitement de données, un protocole client-serveur peut ouvrir de nouveaux cas d’usage en complément des capacités in-process

Mode d’utilisation de Quack

  • Avec Quack, deux instances DuckDB ou plus communiquent entre elles, DuckDB jouant à la fois les rôles de client et de serveur
  • Les deux instances peuvent se trouver sur des machines différentes, à distance, ou dans deux terminaux différents sur le même ordinateur portable
  • L’extension Quack est actuellement disponible dans le dépôt core_nightly et peut être utilisée avec la version actuelle DuckDB v1.5.2
  • Côté serveur, il faut installer et charger Quack, puis appeler quack_serve ; dans l’exemple, quack:localhost et token = 'super_secret' sont utilisés
INSTALL quack FROM core_nightly;
LOAD quack;

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

CREATE TABLE hello AS
    FROM VALUES ('world') v(s);
  • Côté client, il faut aussi installer et charger Quack, définir le jeton avec CREATE SECRET, puis connecter l’instance distante avec 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;
  • Avec cette configuration, DuckDB #2 peut lire la valeur world de la table distante hello
  • Il est également possible de copier des données de l’instance locale vers l’instance distante ; dans l’exemple, DuckDB #2 crée la table remote.hello2, puis DuckDB #1 la vérifie avec FROM hello2;
  • Pour les requêtes complexes ou les gros jeux de données, la fonction query, qui envoie la requête telle quelle au côté distant, permet de mieux contrôler ce qui s’exécute à distance
FROM remote.query(
    'SELECT s FROM hello'
);

Conception du protocole

  • Basé sur HTTP

    • Quack est construit directement sur HTTP, qui s’est imposé de facto comme couche standard au-dessus de TCP et des couches inférieures
    • Les piles HTTP sont efficacement optimisées pour le transport de flux de messages et, lorsqu’elles sont bien implémentées, entraînent peu de surcoût
    • Les pratiques autour de l’équilibrage de charge, de l’authentification, des pare-feu et de la détection d’intrusion en environnement HTTP sont largement maîtrisées
    • Grâce à HTTP, la distribution DuckDB-Wasm peut aussi utiliser Quack nativement
    • Une instance DuckDB exécutée dans le navigateur peut ainsi se connecter directement via Quack à une instance DuckDB tournant sur un serveur EC2
  • Modèle requête-réponse

    • Les interactions de Quack suivent toujours un modèle requête-réponse initié par le client
    • Les messages couvrent notamment les requêtes de connexion pour l’authentification par jeton, les demandes d’exécution de requête, le retour de la première partie d’une réponse, ainsi que les messages de fetch suivants pour récupérer de gros résultats
    • Les gros résultats peuvent être récupérés en parallèle sur plusieurs threads
  • Sérialisation

    • Les requêtes et réponses sont encodées avec un nouveau type MIME : application/duckdb
    • Cet encodage s’appuie sur les primitives internes de sérialisation de DuckDB pour gérer des structures complexes comme les types de données et les ensembles de résultats
    • Les mêmes primitives sont aussi utilisées depuis des années dans les fichiers WAL de DuckDB, et ont été largement optimisées et validées
  • Chiffrement et exposition

    • Au démarrage du serveur, Quack génère par défaut un jeton d’authentification aléatoire, que le client doit fournir
    • Par défaut, le serveur Quack n’écoute que sur localhost, même si ce comportement peut être redéfini
    • Par défaut, SSL n’est pas utilisé, car ajouter cette infrastructure et ces dépendances pour des communications uniquement sur localhost n’est pas considéré comme approprié
    • Il n’est pas recommandé d’exposer directement un endpoint DuckDB Quack sur Internet
    • Si Quack doit être exposé sur le Web, il est fortement recommandé d’utiliser un endpoint HTTP classique comme nginx et de laisser ce proxy terminer SSL avec Let’s Encrypt ou équivalent
    • Le client Quack suppose que SSL est activé pour les connexions non locales, même si ce comportement peut être redéfini
    • Les paramètres associés sont décrits dans la documentation sur le reverse proxy
  • Optimisation des allers-retours

    • Quack a été conçu pour réduire le nombre d’allers-retours de protocole nécessaires à une requête
    • Une fois la connexion établie, une requête peut être traitée en un seul aller-retour, ce qui est avantageux dans les environnements sensibles à la latence
    • Le transfert de réponses volumineuses a aussi été optimisé, et l’équipe DuckDB estime que Quack est actuellement le moyen le plus rapide de transférer une table via socket
    • Les benchmarks montrent qu’il peut transférer des millions de lignes en quelques secondes
  • Authentification et autorisation

    • Quack conçoit son modèle d’authentification et d’autorisation en accord avec la philosophie d’extensibilité de DuckDB
    • Il fournit une méthode d’authentification par défaut et une autorisation ouverte par défaut, mais les deux peuvent être remplacées par du code fourni par l’utilisateur
    • Au démarrage du serveur, un jeton d’authentification aléatoire est généré, et le client fournit une chaîne d’authentification à la connexion
    • Le serveur appelle un callback d’authentification ; le callback par défaut compare le jeton fourni par le client avec celui généré par le serveur
    • Ce callback peut être remplacé par configuration afin d’utiliser une recherche dans un annuaire LDAP, la lecture d’un fichier texte ou une logique arbitraire
    • La fonction d’autorisation peut elle aussi être remplacée ; la fonction par défaut autorise toutes les requêtes
    • Une fonction d’autorisation utilisateur peut inspecter chaque requête que le client tente d’exécuter et prendre une décision en lien avec la chaîne d’authentification précédemment utilisée
    • Ces callbacks peuvent aussi être écrits sous forme de macros SQL classiques
  • Port par défaut

    • Par défaut, le serveur Quack écoute sur le port 9494
    • Le 94 fait référence à 1994, l’année de sortie de Netscape Navigator, pour un numéro facile à retenir

Benchmarks

  • Les benchmarks ont été réalisés sur des machines virtuelles AWS exécutant Ubuntu on Arm
  • Le type d’instance était m8g.2xlarge, avec 8 vCPU, 32GB RAM et une bande passante réseau “jusqu’à 15Gbps”
  • Le scénario reproduit un cas réaliste où le client et le serveur sont dans le même datacenter mais sur des machines distinctes
  • Les deux instances ont été placées dans la même zone de disponibilité, avec un temps de ping moyen d’environ 0,280 ms
  • Transfert massif

    • Le premier benchmark mesure un transfert massif de nombreuses lignes via un protocole de base de données
    • Les comparaisons portent sur Quack, le protocole PostgreSQL et le protocole Arrow Flight SQL
    • Arrow Flight est fourni via le serveur GizmoSQL, qui utilise DuckDB en interne
    • Le nombre de lignes transférées depuis la table TPC-H lineitem a été progressivement augmenté, jusqu’à 60 millions de lignes
    • 60 millions de lignes correspondent à 76GB au format CSV
    • Chaque résultat est rapporté comme la médiane du temps mur sur 5 exécutions
    • Résultats principaux :
      • 100k lignes : DuckDB Quack 0.07 s, Arrow Flight 0.07 s, PostgreSQL 0.20 s
      • 1M lignes : DuckDB Quack 0.24 s, Arrow Flight 0.38 s, PostgreSQL 2.20 s
      • 10M lignes : DuckDB Quack 0.89 s, Arrow Flight 2.90 s, PostgreSQL 25.64 s
      • 60M lignes : DuckDB Quack 4.94 s, Arrow Flight 17.40 s, PostgreSQL 158.37 s
    • Quack a transféré 60 millions de lignes en moins de 5 secondes, montrant de solides performances sur le transfert de grands ensembles de résultats
    • Même Arrow Flight SQL, pourtant conçu pour cet usage, n’a pas atteint le niveau de Quack sur ces résultats, et le protocole PostgreSQL basé sur les lignes a été globalement désavantagé
    • Les clients PostgreSQL standards ne parallélisent pas les lectures sur plusieurs threads, alors que Quack et Arrow le peuvent
    • Le client PostgreSQL de DuckDB peut lui aussi effectuer des lectures parallèles dans certains cas
  • Petites écritures

    • Le second benchmark mesure des opérations de petits append
    • Il correspond à des situations où de petites écritures sont centralisées, comme pour agréger des données d’observabilité dans une instance DuckDB centrale
    • C’est un test défavorable aux protocoles qui nécessitent plusieurs allers-retours client-serveur pour terminer une transaction unique
    • Une table vide avec la structure de TPC-H lineitem est créée, puis des valeurs aléatoires sont insérées une ligne à la fois, chaque insertion étant sa propre transaction INSERT
    • Le test a été exécuté pendant 5 secondes en augmentant le nombre de threads parallèles, puis répété 5 fois afin de rapporter la médiane du nombre de transactions par seconde
    • Résultats principaux :
      • 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
    • Quack a dépassé PostgreSQL jusqu’à 8 threads parallèles, avec un débit maximal d’environ 5 500 tx/s
    • Au-delà, les limites actuelles de DuckDB lui-même sont atteintes pour le nombre d’insertions concurrentes par seconde sur la même table
    • PostgreSQL évolue mieux dans cette zone, et l’équipe DuckDB considère cela comme un point à étudier prochainement
    • Arrow Flight a, comme prévu, obtenu de mauvais résultats, autour de la moitié des performances de PostgreSQL
    • Les scripts de benchmark sont publiés

Cas d’usage et importance pour DuckDB

  • Quack rend possible un DuckDB multijoueur, dans lequel plusieurs processus distincts peuvent modifier en parallèle le contenu des mêmes tables, en local ou à distance
  • Une partie de cela était déjà possible avec DuckLake, mais Quack le simplifie et offre des performances bien supérieures
  • Cela élargit les usages possibles de DuckDB dans les cas où un état centralisé est plus important que des requêtes locales ultra-proches
  • L’essor des data lakes a déjà montré que les données ne se trouvent pas toujours en local, et Quack s’inscrit dans cette direction
  • Quack doit être intégré à DuckLake, permettant à DuckDB lui-même de devenir un serveur de Catalog accessible à distance
  • Cette intégration peut ouvrir de nouvelles possibilités comme l’inlining de données
  • Des réponses supplémentaires sont disponibles dans la FAQ Quack
  • DuckDB s’éloigne ainsi davantage de sa niche initiale de base de données in-process pour l’analyse interactive, pour se rapprocher d’un composant central des architectures de données modernes

Pourquoi ne pas avoir utilisé Arrow Flight SQL

  • Arrow et des projets liés comme ADBC ont de la valeur comme API d’échange destinées à réduire les frictions des échanges de données entre systèmes, à l’image d’ODBC et JDBC
  • En revanche, DuckDB reste prudent sur l’utilisation de formats d’échange comme Arrow en interne
  • La structure interne des résultats intermédiaires des requêtes de DuckDB ressemble à Arrow sur certains points, mais s’en écarte fortement sur d’autres
  • L’équipe estime que pour continuer à innover dans les systèmes de données, elle ne doit pas être contrainte par un format piloté de l’extérieur, d’où l’utilisation d’une sérialisation maison dans Quack
  • Avec une sérialisation propre, il devient possible de déployer immédiatement de nouveaux types de données ou de nouveaux messages de protocole quand nécessaire
  • Arrow Flight SQL impose dans sa conception que toute requête nécessite au minimum deux allers-retours de protocole, à savoir CommandStatementQuery et DoGet
  • Cette approche n’est pas idéale pour les petites opérations de mise à jour, surtout dans des environnements à latence plus élevée
  • Quack a été conçu pour permettre, sur les petites requêtes, l’exécution et la récupération du résultat en un seul aller-retour

Feuille de route

  • Quack doit être intégré à DuckLake afin qu’un serveur DuckDB distant puisse être utilisé comme catalog DuckLake
  • Cette intégration devrait améliorer fortement les performances, notamment pour l’inlining
  • Dans les prochains mois, l’équipe prévoit d’affiner Quack et de publier une première version de production en même temps que DuckDB v2.0, attendue à l’automne
  • Il est aussi prévu de permettre l’installation et le chargement automatiques de l’extension Quack lorsqu’elle est nécessaire
  • Grâce au nouveau parser, la syntaxe de DuckDB pour dialoguer avec des bases SQL distantes devrait aussi être améliorée
  • Côté cœur DuckDB, l’objectif est d’augmenter fortement le nombre de transactions par seconde, afin de dépasser largement l’échelle actuelle de 8 threads parallèles
  • Au-delà de l’authentification et de l’autorisation, l’équipe étudie aussi la possibilité d’autoriser des extensions du protocole Quack, afin que des extensions DuckDB puissent ajouter de nouveaux messages de protocole et leur logique de traitement
  • L’ajout d’un protocole de réplication au-dessus de Quack est également à l’étude, afin de répliquer les changements d’une instance DuckDB vers d’autres serveurs et de former un cluster de réplicas en lecture
  • Quack et ses premiers usages seront aussi présentés le 24 juin à la conférence communautaire DuckCon #7
  • Une page dédiée au projet Quack est également disponible

1 commentaires

 
GN⁺ 2 시간 전
Avis Hacker News
  • C’est exactement le genre de chose que j’aurais aimé avoir la semaine dernière, le timing est parfait
    J’alimentais DuckDB avec des valeurs de capteurs via un serveur Deno, mais je ne pouvais pas inspecter les données avec duckdb -ui sans arrêter le serveur
    Je ne voulais pas ajouter cette fonctionnalité au serveur juste pour consulter le contenu de la base, donc j’allais faire avec pour l’instant, mais ça règle proprement ce problème ainsi que d’autres soucis similaires que j’avais avec DuckDB
    DuckDB est ma techno préférée de 2025/26, et elle est profondément intégrée à plusieurs workflows : travail avec les LLM, stockage de données, analyse, pipelines de données, etc.

    • J’aimerais bien en savoir plus sur la façon dont tu l’utilises dans tes workflows
      Ça m’intéresse beaucoup, mais je n’ai pas encore trouvé comment intégrer DuckDB naturellement dans ma manière de résoudre les problèmes, donc j’ai encore du mal à voir à quels cas d’usage le rattacher
  • Excellent. J’étais en train de voir si on pouvait utiliser DuckDB dans le framework d’apps interne de ma boîte, et ça résout la question du « bon, et l’extension horizontale alors ? »
    Bravo à l’équipe DuckDB, et j’aime aussi que le protocole s’appelle Quack

  • Je travaillais sur un projet open source qui stocke et interroge des données d’observabilité — métriques, logs et traces — dans Parquet, et même si je suis tout à fait d’accord avec l’idée d’utiliser des formats de stockage et des catalogues ouverts, j’étais frustré par l’ergonomie de Apache Iceberg
    En voyant ça, DuckLake devient bien plus intéressant pour mon cas d’usage, et j’ai hâte de voir où ça va mener
    https://github.com/smithclay/duckdb-otlp

    • Je me demande si c’est utilisé pour remplacer Mimir
  • DuckDB est super, mais je ne comprends pas très bien ce qu’il veut devenir
    Il y a sans cesse de nouvelles façons de l’utiliser, et il n’est pas évident de voir d’un coup d’œil laquelle est la bonne

    • DuckDB est à la fois autonome et un composant
      Cette tentative est assez cohérente, et elle le ramène en partie vers un modèle d’usage familier : celui d’une base de données relationnelle client-serveur traditionnelle
      À l’origine, les SGBDR étaient des systèmes multi-utilisateurs avec concurrence, et DuckDB est un moteur local très rapide qui peut aussi être embarqué dans d’autres systèmes, d’où la variété des cas d’usage
      C’est un peu comme demander ce que SQLite veut devenir. On le retrouve dans les téléphones, les navigateurs, les apps desktop, les objets IoT, et les gens l’ont fait évoluer dans plein de directions. La différence ici, c’est que ce n’est pas du tiers mais du first-party, et pour moi c’est une évolution très facile à comprendre
    • Il suffit de trouver l’approche qui te convient
    • Notre pipeline de données génère des fichiers .duckdb que l’application télécharge
      L’app surveille des assets sur S3 et les récupère si l’etag change
      Ça permet d’obtenir facilement des performances proches de BigQuery ou ClickHouse sans devoir exploiter soi-même l’infra ni en payer le coût
      Ce n’est pas parfait pour tous les cas, mais ça couvre bien plus de choses qu’on ne l’imagine
    • Je lis ça moins comme « DuckDB essaie de devenir Postgres » que comme le fait de devenir une couche d’exécution dans un workflow plus vaste
      Le moteur lui-même n’est plus toujours le point douloureux ; le problème est plutôt à la périphérie. Base vivante, chemins S3, fichiers Parquet, identifiants, exécution reproductible, export, validation, et ces moments où un script jetable devient discrètement de l’infrastructure
      Quack rend la partie distante / serveur plus propre, mais la tendance de fond, c’est que DuckDB semble devenir moins un outil destiné à l’utilisateur final qu’une couche SQL à l’intérieur d’autres outils
    • À part le déplacement de données, je ne vois pas beaucoup de recoupements entre ce cas d’usage et celui de Arrow Flight
  • Ils n’ont pas expliqué ce que signifie « rédacteurs concurrents »
    À première vue, on dirait simplement une sérialisation des écritures côté serveur

    • Je ne pense pas. DuckDB prend déjà en charge les écritures concurrentes dans un seul processus
      Je ne vois pas pourquoi cette fonctionnalité se mettrait soudain à sérialiser toutes les écritures
  • Ça a l’air utile pour de petits jeux de données analytiques internes qu’on voudrait héberger sur un serveur partagé d’équipe
    Ça mérite aussi d’être étudié pour un homelab

    • Avec DuckLake, ça monte bien jusqu’à des jeux de données de plusieurs téraoctets
      Le gros avantage de ce protocole serveur, c’est qu’on peut mutualiser un serveur avec beaucoup de mémoire et profiter d’un cache partagé sur les données récentes
  • J’ai une application C++ où, pendant l’exécution, tout est en mémoire
    Entre les sessions, on persiste sur disque en XML et ça fonctionne bien, mais c’est strictement mono-utilisateur, et certains clients veulent généraliser ça pour permettre à plusieurs utilisateurs de lire et écrire en même temps
    Les besoins en performance sont faibles : 2 à 3 personnes qui mettent à jour en même temps quelques milliers d’enregistrements. Dans ce cas, est-ce que DuckDB + Quack serait un bon choix ? Ou existe-t-il une meilleure option ? J’ai aussi regardé SQLite, mais si j’ai bien compris il ne fonctionne pas en client-serveur

    • https://firebirdsql.org existe discrètement depuis des décennies entre SQLite et un PostgreSQL plus lourd, mais si on me demande quelle base client-serveur utiliser, ma recommandation par défaut reste PostgreSQL
    • DuckDB est plus orienté analytique
      J’ai du mal à voir une bonne option pour une base gérant des utilisateurs concurrents sans héberger d’une manière ou d’une autre quelque chose côté serveur
      Bien sûr, c’est possible, un peu comme certains jeux construisent eux-mêmes un client-serveur multijoueur, mais franchement, héberger Postgres ou SQLite coûte ridiculement peu cher et c’est très simple, et surtout c’est l’approche standard pour ce problème
    • Ça ressemble à un cas d’usage bien adapté aux CRDT, avec en plus la possibilité d’éditer hors ligne
    • Le terme à chercher est sans doute local-first
  • Génial. J’étais en train de construire une application de tableur colonnaire façon Excel avec DuckDB, mais j’ai dû recréer un « client » avec une couche HTTP traditionnelle

  • La question « que veut devenir DuckDB ? » revient sans cesse, mais pour moi la réponse est déjà claire
    Il veut devenir le SQLite de l’analytique. Embarquable, sans configuration, et capable de fonctionner partout
    Quack ne fait qu’étendre ce « partout » au distant

    • Ce serait vraiment bien s’il existait un cookbook officiel de l’équipe DuckDB
  • À la question « Peut-on utiliser DuckDB avec Quack comme base de catalogue pour DuckLake ? », il est répondu « Pas encore, mais nous y travaillons ! »
    Ça peut sembler être un cas d’usage de niche, mais c’est celui qui m’intéresse le plus
    Notre lakehouse utilise DuckLake avec Postgres comme catalogue, et un catalogue DuckDB / Quack me semblerait une excellente alternative

    • Je pense que Quack va devenir à terme l’option principale pour le catalogue DuckLake
      Pour plusieurs raisons. D’abord, il n’y a pas de décalage de types dans le traitement inline. Si on utilise un catalogue autre que DuckDB, beaucoup de types ne se mappent pas en 1:1, ce qui ajoute du surcoût quand on manipule ces types de données
      Ensuite, on récupère directement les performances analytiques de DuckDB, et maintenant aussi ses performances transactionnelles, au-dessus du catalogue. DuckDB qui lit DuckDB est tout simplement plus rapide que nos scanners Postgres/SQLite
      Enfin, il n’y a pas d’aller-retour pour les retries. On peut exécuter toute la logique de retry facilement(tm) côté serveur DuckDB. Aujourd’hui, ces retries provoquent plusieurs allers-retours vers Postgres et deviennent un goulot d’étranglement sous forte contention
      Pour info, je suis développeur sur duckdb/ducklake
    • C’est effectivement en cours : https://github.com/duckdb/ducklake/pull/1151
      Ce sera testable d’ici quelques jours