2 puntos por GN⁺ 2 시간 전 | 1 comentarios | Compartir por WhatsApp
  • Quack proporciona comunicación entre instancias de DuckDB, lo que permite una configuración cliente-servidor y que varios escritores concurrentes usen la misma base de datos
  • DuckDB mantiene su arquitectura in-process, mientras que la sincronización de estado necesaria cuando varios procesos modifican el mismo archivo se maneja mediante un protocolo remoto
  • Quack es un protocolo de solicitud-respuesta basado en HTTP, usa serialización application/duckdb y autenticación por token, y su puerto predeterminado es 9494
  • En benchmarks, Quack transfirió 60 millones de filas en 4.94 segundos, y en pruebas de append pequeño registró unos 5,434 tx/s con 8 hilos
  • Quack planea integración con DuckLake, un servidor de catálogo remoto, instalación y carga automáticas, extensiones del protocolo y un protocolo de replicación, con el objetivo de una versión de producción en la época de DuckDB v2.0

Propósito y contexto de Quack

  • Quack es un protocolo remoto que permite que instancias de DuckDB se comuniquen entre sí, para ejecutar DuckDB en una configuración cliente-servidor y permitir que varios escritores concurrentes usen la misma base de datos
  • Desde 2019, DuckDB ha enfatizado una arquitectura in-process; su forma de operar mediante llamadas API de bajo nivel, sin un servidor ni protocolo separados, encajaba bien con trabajos interactivos de ciencia de datos como notebooks de Python y con ofrecer capacidades SQL dentro de aplicaciones
  • Para que varios procesos modifiquen simultáneamente el mismo archivo de base de datos de DuckDB, es necesario sincronizar entre procesos gran parte del estado que DuckDB mantiene en memoria principal
  • Hasta ahora existían alternativas indirectas como un proceso RPC separado, proyectos que usan el protocolo Arrow Flight SQL, el protocolo propio de MotherDuck, o combinaciones de PostgreSQL con pg_duckdb como “EleDucken”
  • Para ampliar DuckDB como una herramienta general de procesamiento de datos, además de sus capacidades in-process, un protocolo cliente-servidor puede abrir nuevos casos de uso

Cómo se usa Quack

  • En Quack, dos o más instancias de DuckDB se comunican entre sí, y DuckDB cumple tanto el rol de cliente como de servidor
  • Las dos instancias pueden estar en computadoras distintas, en ubicaciones remotas o en diferentes ventanas de terminal de la misma laptop
  • La extensión Quack está actualmente en el repositorio core_nightly y puede usarse con la versión de lanzamiento actual, DuckDB v1.5.2
  • En la instancia DuckDB del lado del servidor, se instala y carga Quack y luego se llama a quack_serve; en el ejemplo se usan quack:localhost y 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);
  • En la instancia DuckDB del lado del cliente también se instala y carga Quack; luego se configura el token con CREATE SECRET y se conecta la instancia remota con 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;
  • Con esta configuración, en DuckDB #2 se puede consultar el valor world de la tabla remota hello
  • También se pueden copiar datos desde la instancia local hacia la instancia remota; en el ejemplo, DuckDB #2 crea la tabla remote.hello2 y luego se verifica en DuckDB #1 con FROM hello2;
  • En consultas complejas o datasets grandes, la función query permite controlar mejor qué trabajo se ejecuta del lado remoto enviando la consulta tal cual
FROM remote.query(
    'SELECT s FROM hello'
);

Diseño del protocolo

  • Basado en HTTP

    • Quack fue construido directamente sobre HTTP, que en la práctica se ha consolidado como la capa de protocolo estándar sobre TCP y niveles inferiores
    • La pila HTTP está optimizada de forma eficiente para la transmisión de flujos de mensajes y, si se implementa bien, tiene una sobrecarga baja
    • El manejo de HTTP es ampliamente conocido en áreas como balanceo de carga, autenticación, firewalls y detección de intrusiones
    • Al usar HTTP, la distribución DuckDB-Wasm también puede usar Quack de forma nativa
    • DuckDB ejecutándose en el navegador puede conectarse directamente con Quack a una instancia de DuckDB que corre en un servidor EC2
  • Patrón de solicitud-respuesta

    • La interacción en Quack siempre funciona con un patrón de solicitud-respuesta impulsado por el cliente
    • Los mensajes incluyen solicitudes de conexión para autenticación por token, solicitudes de ejecución de consultas, devolución de la primera parte de la respuesta y mensajes de fetch posteriores para traer resultados grandes
    • Los resultados grandes pueden obtenerse en paralelo desde varios hilos
  • Serialización

    • Las solicitudes y respuestas se codifican con un nuevo tipo MIME: application/duckdb
    • Esta codificación aprovecha primitivas internas de serialización de DuckDB para estructuras complejas como tipos de datos y conjuntos de resultados
    • Las mismas primitivas se han usado durante años en los archivos WAL de DuckDB y han sido bastante optimizadas y validadas
  • Cifrado y forma de exposición

    • Al iniciar el servidor, Quack genera por defecto un token de autenticación aleatorio, que el cliente debe proporcionar
    • El servidor Quack, por defecto, solo se enlaza a localhost, aunque ese comportamiento puede sobrescribirse
    • No usa SSL por defecto, porque consideran que no tiene sentido añadir esa infraestructura y dependencias solo para comunicación por localhost
    • No se recomienda exponer directamente a internet un endpoint Quack de DuckDB
    • Si es necesario exponer Quack a la web, recomiendan enfáticamente usar un endpoint HTTP común como nginx y que ese proxy termine SSL con Let’s Encrypt o equivalente
    • El cliente Quack asume que SSL está habilitado para conexiones no locales, aunque ese comportamiento puede sobrescribirse
    • La configuración relacionada está en la documentación de reverse proxy
  • Optimización de viajes de ida y vuelta

    • Quack fue diseñado para reducir la cantidad de round trips del protocolo que requiere una consulta
    • Después de la conexión, una consulta puede resolverse en un solo viaje de ida y vuelta, lo que es ventajoso en entornos sensibles a la latencia
    • También se optimizó la transmisión de respuestas voluminosas, y el equipo de DuckDB considera que Quack es actualmente la forma más rápida de transferir tablas por socket
    • Los benchmarks muestran que puede transferir millones de filas en pocos segundos
  • Autenticación y autorización

    • Quack diseñó su modelo de autenticación y autorización de acuerdo con la filosofía de extensibilidad de DuckDB
    • Ofrece un método de autenticación predeterminado y una autorización predeterminada sin restricciones, pero ambos pueden reemplazarse con código provisto por el usuario
    • Al arrancar el servidor se genera un token de autenticación aleatorio, y el cliente proporciona una cadena de autenticación al conectarse
    • El servidor invoca un callback de autenticación; el callback predeterminado compara el token enviado por el cliente con el token generado por el servidor
    • El callback de autenticación puede sustituirse por configuración para usar consultas a directorios LDAP, lectura de archivos de texto o cualquier lógica arbitraria
    • La función de autorización también puede cambiarse, y la función predeterminada permite todas las solicitudes
    • La función de autorización del usuario puede inspeccionar cada consulta que el cliente intenta ejecutar y decidir en relación con la cadena de autenticación usada previamente
    • Estos callbacks incluso pueden escribirse como macros SQL normales
  • Puerto predeterminado

    • El servidor Quack escucha por defecto en el puerto 9494
    • 94 se eligió para recordar fácilmente 1994, el año en que se lanzó Netscape Navigator

Benchmarks

  • Los benchmarks se realizaron en máquinas virtuales de AWS ejecutando Ubuntu on Arm
  • El tipo de instancia fue m8g.2xlarge, con 8 vCPU, 32GB de RAM y ancho de banda de red de “hasta 15Gbps”
  • Se buscó reproducir un escenario realista con cliente y servidor en máquinas distintas, pero dentro del mismo centro de datos
  • Las dos instancias se ubicaron en la misma zona de disponibilidad y el tiempo promedio de ping fue de aproximadamente 0.280ms
  • Transferencia masiva

    • El primer benchmark midió una tarea de transferencia masiva de muchas filas a través de un protocolo de base de datos
    • Los comparados fueron Quack, el protocolo PostgreSQL y el protocolo Arrow Flight SQL
    • Arrow Flight se ofreció mediante el servidor GizmoSQL, que internamente usa DuckDB
    • Se transfirieron cantidades crecientes de filas de la tabla lineitem de TPC-H, con mediciones de hasta 60 millones de filas
    • 60 millones de filas equivalen a 76GB en formato CSV
    • Cada resultado se reportó como el tiempo de reloj de pared mediano de 5 ejecuciones
    • Los principales resultados fueron los siguientes
      • 100k filas: DuckDB Quack 0.07 s, Arrow Flight 0.07 s, PostgreSQL 0.20 s
      • 1M filas: DuckDB Quack 0.24 s, Arrow Flight 0.38 s, PostgreSQL 2.20 s
      • 10M filas: DuckDB Quack 0.89 s, Arrow Flight 2.90 s, PostgreSQL 25.64 s
      • 60M filas: DuckDB Quack 4.94 s, Arrow Flight 17.40 s, PostgreSQL 158.37 s
    • Quack transfirió 60 millones de filas en menos de 5 segundos, mostrando un rendimiento fuerte en transferencia de conjuntos de resultados grandes
    • Incluso Arrow Flight SQL, diseñado con un propósito específico, quedó por detrás de Quack en estos resultados, y el protocolo basado en filas de PostgreSQL estuvo en desventaja general
    • El cliente estándar de PostgreSQL no paraleliza la lectura en varios hilos, mientras que Quack y Arrow sí pueden hacerlo
    • El cliente PostgreSQL de DuckDB también puede hacer lecturas en paralelo en algunos casos
  • Escrituras pequeñas

    • El segundo benchmark midió operaciones de append pequeño
    • Corresponde a escenarios donde se centralizan escrituras pequeñas, como una configuración que recopila datos de observabilidad en una instancia central de DuckDB
    • Es una prueba desfavorable para protocolos que requieren varios viajes cliente-servidor para completar una sola transacción
    • Se creó una tabla vacía con la misma estructura que lineitem de TPC-H y se insertaron valores aleatorios fila por fila, cada uno en su propia transacción INSERT
    • Se ejecutó durante 5 segundos aumentando la cantidad de hilos en paralelo, y el experimento se repitió 5 veces reportando la mediana de transacciones por segundo
    • Los principales resultados fueron los siguientes
      • 1 hilo: DuckDB Quack 1,038 tx/s, Arrow Flight 469 tx/s, PostgreSQL 839 tx/s
      • 2 hilos: DuckDB Quack 1,956 tx/s, Arrow Flight 799 tx/s, PostgreSQL 1,094 tx/s
      • 4 hilos: DuckDB Quack 3,504 tx/s, Arrow Flight 1,224 tx/s, PostgreSQL 2,180 tx/s
      • 8 hilos: DuckDB Quack 5,434 tx/s, Arrow Flight 1,358 tx/s, PostgreSQL 4,320 tx/s
    • Quack superó a PostgreSQL hasta 8 hilos paralelos y mostró un rendimiento máximo de alrededor de 5,500 tx/s
    • Más allá de eso, se alcanza el límite actual del propio DuckDB en inserciones concurrentes por segundo sobre la misma tabla
    • PostgreSQL escala mejor en ese terreno, y el equipo de DuckDB lo ve como un área a revisar en el futuro cercano
    • Como era de esperarse, Arrow Flight no rindió bien y mostró aproximadamente la mitad del rendimiento de PostgreSQL
    • Los scripts de benchmark están publicados

Casos de uso y significado para DuckDB

  • Quack hace posible un uso de DuckDB multijugador, donde varios procesos individuales pueden modificar en paralelo el contenido de las mismas tablas, ya sea local o remotamente
  • Parte de esto ya era posible con DuckLake, pero Quack lo simplifica y ofrece un rendimiento mucho mayor
  • Amplía el rango de escenarios donde DuckDB puede usarse cuando el estado central es más importante que consultas locales ultracercanas
  • La expansión de los data lakes ya había mostrado que los datos no siempre están en local, y Quack encaja con esa dirección
  • Quack se integrará con DuckLake, permitiendo que el propio DuckDB se convierta en un servidor de catálogo accesible de forma remota
  • Esa integración puede abrir nuevas funciones, como el inlineado de datos
  • Más preguntas están en el FAQ de Quack
  • DuckDB se está moviendo más allá de su nicho inicial como base de datos in-process para análisis interactivo, acercándose a ser un componente central de la arquitectura moderna de datos

Por qué no usaron Arrow Flight SQL

  • Proyectos relacionados como Arrow y ADBC tienen valor como APIs de intercambio para reducir la fricción del intercambio de datos entre sistemas, similar a ODBC y JDBC
  • Aun así, hay cautela respecto a usar formatos de intercambio como Arrow dentro del interior de DuckDB
  • La estructura interna de resultados intermedios de las consultas de DuckDB se parece a Arrow en algunos aspectos, pero en otros es bastante distinta
  • Consideran que, para seguir innovando en sistemas de datos, no pueden quedar limitados por un formato controlado externamente, así que Quack usa su propia serialización
  • Usar serialización propia también permite desplegar de inmediato nuevos tipos de datos o nuevos mensajes de protocolo cuando se necesiten
  • Arrow Flight SQL tiene un diseño en el que toda consulta requiere al menos dos round trips del protocolo: CommandStatementQuery y DoGet
  • Ese enfoque no es ideal para actualizaciones pequeñas, especialmente en entornos con mayor latencia
  • Quack está diseñado para que consultas pequeñas puedan ejecutar la consulta y hacer fetch del resultado en un solo viaje de ida y vuelta

Planes a futuro

  • Quack se integrará con DuckLake para permitir usar servidores remotos de DuckDB como catálogo de DuckLake
  • Se espera que esta integración mejore considerablemente el rendimiento, especialmente en inlineado
  • Durante los próximos meses planean pulir Quack y lanzar su primera versión de producción junto con DuckDB v2.0, prevista para este otoño
  • Planean permitir instalación automática y carga automática de la extensión Quack cuando sea necesaria
  • También planean mejorar la sintaxis para interactuar desde DuckDB con bases de datos SQL remotas usando el nuevo parser
  • Del lado del core de DuckDB, planean aumentar significativamente las transacciones por segundo para escalar mucho más allá de 8 hilos paralelos
  • Además de autenticación y autorización, también están evaluando permitir extensiones del protocolo Quack para que las extensiones de DuckDB puedan agregar nuevos mensajes de protocolo y código de manejo
  • También están evaluando agregar un protocolo de replicación sobre Quack para replicar cambios de una instancia de DuckDB a otros servidores y construir clústeres de réplicas de lectura
  • Quack y su adopción inicial también se tratarán en la conferencia de comunidad del 24 de junio, DuckCon #7
  • También hay una página separada del proyecto Quack

1 comentarios

 
GN⁺ 2 시간 전
Comentarios de Hacker News
  • Justo la semana pasada pensé que necesitaba exactamente algo así; el timing es perfecto
    Estaba enviando valores de sensores a DuckDB desde un servidor en Deno, pero no podía revisar los datos con duckdb -ui sin bajar el servidor
    No quería agregarle funcionalidades al servidor solo para ver el contenido de la DB, así que pensaba aguantar así por un tiempo, pero esto resuelve de forma muy limpia ese problema y otros similares que venía teniendo con DuckDB
    DuckDB es mi tecnología favorita de 2025/26 y ya está metida a fondo en varios flujos de trabajo: tareas con LLM, almacenamiento de datos, análisis, pipelines de datos y más

    • Me gustaría escuchar más detalles sobre cómo lo usas en tus flujos de trabajo
      Me interesa mucho, pero todavía no logro encajar DuckDB de forma natural en mi manera de resolver problemas, así que tampoco tengo claro a qué casos de uso podría mapearlo
  • Qué genial. Estaba viendo si usar DuckDB en el framework de apps internas de la empresa, y esto me resolvió la pregunta de “¿y entonces cómo hago escalado horizontal?”
    Aplausos para el equipo de DuckDB, y además me encanta que el protocolo se llame Quack

  • Estaba trabajando en un proyecto open source para guardar y consultar datos de observabilidad —métricas, logs y trazas— en Parquet, y aunque coincido mucho con la idea de usar formatos de almacenamiento y catálogos abiertos, la usabilidad de Apache Iceberg siempre me ha resultado frustrante
    Al ver esto, DuckLake me parece mucho más interesante para mi caso de uso, y me emociona ver hacia dónde va
    https://github.com/smithclay/duckdb-otlp

    • Me pregunto si lo estás usando para reemplazar Mimir
  • DuckDB me gusta, pero no tengo claro qué quiere llegar a ser
    Siguen apareciendo nuevas formas de usarlo y no es fácil ver de un vistazo cuál es la correcta

    • DuckDB es a la vez standalone y también un componente
      Este intento es bastante coherente, y en cierto sentido lo devuelve a un modelo de uso familiar: el de una base de datos relacional tradicional cliente-servidor
      Los DBMS relacionales originalmente eran sistemas de concurrencia multiusuario, y DuckDB es un motor local rapidísimo que además puede embutirse en otros sistemas, así que tiene muchos casos de uso distintos
      Es parecido a preguntar qué quiere llegar a ser SQLite. Está en teléfonos, navegadores, apps de escritorio y dispositivos IoT, y la gente lo ha extendido en muchas direcciones. La diferencia aquí es que esto no viene de terceros sino del propio proyecto, y a mí me parece un movimiento muy fácil de entender
    • Solo hace falta encontrar la forma que te funcione a ti
    • Nuestro pipeline de datos genera archivos .duckdb que la app descarga
      La app monitorea assets en S3 y los baja cuando cambia el etag
      Es una forma sencilla de obtener un rendimiento tipo BigQuery o ClickHouse sin tener que operar esa infraestructura ni pagar su costo
      No es perfecto para todos los casos, pero resuelve muchísimo más de lo que uno esperaría
    • Yo no lo leo como “DuckDB quiere convertirse en Postgres”, sino como que se está volviendo la capa de ejecución dentro de un flujo de trabajo más grande
      Ahora el motor en sí ya no siempre es la parte dolorosa; el problema está alrededor: la DB viva, las rutas en S3, los archivos Parquet, las credenciales, las ejecuciones repetibles, las exportaciones, la validación y esos momentos en que un script improvisado termina convirtiéndose silenciosamente en infraestructura
      Quack hace más limpia la parte remota/del servidor, pero la tendencia mayor me parece que va hacia que DuckDB sea menos una herramienta para usuario final y más una capa SQL dentro de otras herramientas
    • Fuera del movimiento de datos, no se me ocurren muchos casos de uso que se superpongan con Arrow Flight
  • No explicaron qué significa “escritores concurrentes”
    Por lo que se ve, parece que simplemente serializan las escrituras del lado del servidor

    • No creo que sea eso. DuckDB ya soporta escrituras concurrentes dentro de un mismo proceso
      No veo por qué esta función haría que de repente todas las escrituras se serialicen
  • Se ve útil para datasets analíticos internos pequeños que quieras poner en un servidor compartido del equipo
    Para un homelab también parece valer mucho la pena revisarlo

    • Si lo usas junto con DuckLake, escala bastante bien incluso a datasets de varios terabytes
      Una gran ventaja de este protocolo de servidor es que te permite compartir un servidor con mucha memoria y aprovechar un caché compartido para los datos recientes
  • Tengo una aplicación en C++ y, mientras está corriendo, todo vive en memoria
    Entre sesiones se guarda en disco como XML y funciona bien, pero estrictamente es de un solo usuario, y algunos clientes quieren generalizarlo para que varios usuarios puedan leer y escribir al mismo tiempo
    Los requisitos de rendimiento son bajos: sería algo como 2 o 3 personas actualizando unos pocos miles de registros a la vez. En un caso así, ¿DuckDB + Quack sería una buena opción? ¿O habría una alternativa mejor? También miré SQLite, pero entiendo que no funciona en modo cliente-servidor

    • https://firebirdsql.org lleva décadas existiendo silenciosamente entre SQLite y PostgreSQL de verdad, pero si preguntas qué base de datos cliente-servidor usar, mi recomendación por defecto sigue siendo PostgreSQL
    • DuckDB está más orientado a analítica
      Me costaría encontrar una buena opción para manejar usuarios concurrentes sin hospedar de alguna forma una DB del lado del servidor
      Claro, se puede, igual que algunos juegos hacen su propio cliente-servidor para multijugador, pero siendo honestos, hospedar Postgres o SQLite es ridículamente barato y fácil, y además es el enfoque estándar para este problema
    • Suena como un caso de uso que encaja bien con CRDT, y además te permitiría edición offline
    • Creo que el término que deberías buscar es local-first
  • Excelente. Estaba usando DuckDB para construir una app de hojas de cálculo columnar tipo Excel, y tuve que volver a crear el “cliente” por encima de una capa HTTP tradicional

  • La pregunta de “qué quiere llegar a ser DuckDB” sigue saliendo, pero para mí la respuesta ya es clara
    Quiere ser el SQLite de la analítica: embebible, sin configuración y que funcione en todas partes
    Quack solo es la parte que hace que ese “en todas partes” incluya también lo remoto

    • Estaría buenísimo que el equipo de DuckDB sacara un cookbook oficial
  • En la parte de “¿se puede usar DuckDB con Quack como base de datos de catálogo de DuckLake?” dice “¡todavía no, pero estamos trabajando en ello!”
    Parece un caso de uso de nicho, pero es justo la parte que más me interesa
    Nuestro lakehouse usa DuckLake y Postgres para el catálogo, y un catálogo con DuckDB / Quack me parece que podría ser una alternativa excelente

    • Creo que con el tiempo Quack terminará siendo la opción principal para el catálogo de DuckLake
      Hay varias razones. Primero, no hay desajustes de tipos en el procesamiento inline. Si usas un catálogo que no sea DuckDB, muchos tipos no tienen mapeo 1:1 y eso mete overhead extra al trabajar con esos tipos de datos
      Segundo, sobre el catálogo puedes obtener tal cual el rendimiento analítico de DuckDB y ahora también su rendimiento transaccional. DuckDB leyendo DuckDB es simplemente más rápido que nuestros scanners para Postgres/SQLite
      Tercero, no hay viajes de ida y vuelta para reintentos. Toda la lógica de reintentos se puede ejecutar fácilmente(tm) del lado del servidor DuckDB. Ahora mismo, esos reintentos generan múltiples round-trips a Postgres y eso se vuelve un cuello de botella en cargas de trabajo con mucha contención
      Por cierto, soy desarrollador de duckdb/ducklake
    • De hecho ya está en desarrollo: https://github.com/duckdb/ducklake/pull/1151
      En unos días ya debería poder probarse