数据架构

除了进程内功能之外还需要客户端-服务器协议
用户交互的层
agent层和中间层
中间层会逐渐消失,或者至少会被大幅重构
基础设施层:
AI 计算层: PARK 技术栈,它包含 PyTorch、AI 基础模型、Ray 和 Kubernetes
多模态湖屋层 基于 Lance、LanceDB 和 Lance 格式构建的多模态湖屋(Lakehouse

RStudio 官方已更名为 Posit
Spreadsheets remain a ubiquitous tool for data management and analysis
INSTALL sheetreader FROM community;

历史问题

ML工具和数据库架构不兼容,序列化协议不匹配
ML 框架不支持流式、增量、分页读取,它们要的是:一张完整、连续、可切片的大表,
数据库发出来的数据,ML 工具必须重新解析、重排、拷贝到内存,等于做了两次无用转换
ML 框架没有 “数据库执行层
(怕断、怕慢、怕不一致)
“高效传输协议”
列存序列化 零拷贝传输 直接映射到 DataFrame 的格式 让 ML 工具不用全量导出,直接高效读数据库

新一代计算

Network Impact
Data Compression Data Serialization
String Handling
通过 统一列存数据格式 + 高效客户端协议 + 零拷贝数据交换 + 计算下推,让两者无缝对齐。
存储层 : 数据库端直接输出列存格式
内存层 : Apache Arrow(跨语言零拷贝) 零拷贝变成 DataFrame / Tensor。格式统一 采用 Apache Arrow 作为跨平台内存标准
传输层 : 协议层解决:替换低效客户端协议
接口层 : 给 ML 工具原生 “数据库直连能力”
计算层 : 计算下推(Pushdown)
Python/R/TensorFlow 直接用数据库做数据源
传输层--协议重点
行式 vs 列式 分块列式传输(chunked columnar)
块大小(Chunk Size) 压缩方法-轻量级压缩(Snappy)
序列化格式:自定义 vs Protobuf 字符串编码

新一代

共同改变:都从 “行存 / 客户端-服务器” 转向 “列存 + Arrow 原生集成”
存储层:Lance 格式(Arrow 持久化)
内存与传输:全链路 Arrow,零拷贝到 PyTorch/TensorFlow
DuckDB 与 LanceDB 从底层重新设计了数据库与机器学习工具的交互方式

论文

论文 new traditional protocol--a columnar serialization method
why:
在同一台机器上(无网络瓶颈),序列化/反序列化也占据主导时间。
Result set serialization

并发控制机制(三选一)
方案 A:MVCC(最主流,PostgreSQL/DuckDB/MySQL InnoDB)
方案 B:锁机制(行锁 + 意向锁)
方案 C:QUACK 协议(DuckDB 新一代多写)
步骤:
写入以日志 / 变更流方式提交
多写者通过共识协议有序合并
本地保持快照,远程合并变更
无中心锁,高并发低冲突
事务原子性(WAL 日志)
写入先落WAL 预写日志
日志成功 → 才算写入成功
崩溃后从 WAL 恢复
保证:要么全成功,要么全失败

版本

Quack 以 DuckDB v1.5.2 发布,并存储在扩展仓库中:core_nightly
DuckDB v1.5.3 开始, Quack 作为核心扩展程序提供
2026 Fall DuckDB v2.0.0 DuckDB v2.0一起发布 Quack 的生产就绪版本。

技术方案

之前: DuckDB 严格执行一条规则:一个写入进程,多个读者进程
现在:对于中等流量工作负载,无需中间队列
[Worker 1] → INSERT INTO quack_server.events
[Worker 2] → INSERT INTO quack_server.events
[Worker 3] → INSERT INTO quack_server.events
[Dashboard] → SELECT * FROM quack_server.events WHERE ts > NOW() - INTERVAL '5 min'

之前:
每个work分别写入一个独立的DuckDB文件,然后再合并它们成为一个( 临时文件+合并步骤)

高频 OLTP 和大量小交易--PostgreSQL
DuckDB低运营开销加上Quack的多写能力,是中型工作负载中建立ClickHouse或Redshift的有力替代方案。
duckdb-just-changed-the-game-meet-quack-the-protocol-that-unlocks-multiple-writers

示例代码

import duckdb
import threading
import time
import uuid

==============================================

对应文章:QUACK 让多个客户端同时写同一个 DuckDB

==============================================

DB_FILE = r"D:\Tools\Data\duckdb_test\quack_demo.db"

def server():
# --------------------------
# DuckDB 服务端启动和创建表
# --------------------------
init_conn = duckdb.connect(DB_FILE)
quack_server = """ CALL quack_serve( 'quack:localhost', token = 'super_secret'); """
init_conn.execute(quack_server)
init_conn.execute(''' CREATE TABLE IF NOT EXISTS events ( event_id STRING, worker_id INT,
message STRING, ts FLOAT ) ''')
return init_conn

--------------------------

工具函数:每个"写者"独立连接

--------------------------

def worker(worker_id):
# 每个 writer 独立连接 ← 文章核心
conn = duckdb.connect()
# 【关键】启用 QUACK 多写者协议
quack_client = """ INSTALL quack ; LOAD quack;
CREATE SECRET (TYPE quack, TOKEN 'super_secret');
ATTACH 'quack:localhost' AS remote;
"""
conn.execute(quack_client)
print(f" 写 {worker_id} 已启动,准备并发写入")
try:
# 模拟多个并发写入
for i in range(5):
event_id = str(uuid.uuid4())
timestamp = time.time()
# 多个写者同时 INSERT → QUACK 自动协调
conn.execute('''
INSERT INTO remote.events (event_id, worker_id, message, ts)
VALUES (?, ?, ?, ?)
''', (event_id, worker_id, f"msg_{i}", timestamp))
print(f" 写 {worker_id} 写入第 {i} 条数据")
time.sleep(0.1)
finally:
conn.close()

if name == "main":
init_con = server()
print(" 启动 4 个 QUACK 多写者...\n")
threads = [threading.Thread(target=worker, args=(i,)) for i in range(4)]
# ### ======================
# ## # 顺序执行
# ## ======================
# for t in threads:
# t.start()
# t.join() # 一个跑完再跑下一个
# --------------------------
# 启动 4 个并发写者
# 对应文章:Multiple Writers At The Same Time
# --------------------------
for t in threads:
t.start()
for t in threads:
t.join()
# --------------------------
# 查看最终结果
# --------------------------
total = init_con.execute("SELECT COUNT(*) FROM events").fetchone()[0]
dat = init_con.execute("SELECT * FROM events limit 2").fetchone()
print(f"\n 总写入行数: {total} \r\n 示例数据 {dat}")
init_con.close()

服务端2个注意点

服务的链接--要么一直在,要么con=start_server()

文件被占用--加一个如果存在则删除的逻辑
_duckdb.IOexception:IO Erro: Failed to send message:
IO Error: Could not connect to server erro for HTTP POST to 'http://localhost:9494/quack'

con=start_server()

_duckdb.IOexception:IO Erro: Cannot open file '/app/quack:/localhost' :NO such sile or directory

客户端1个注意点

时间戳字段导致的
_duckdb.BinderException: Bibder Error: catalog remote does not exist

语法错误

_duckdb.ParserException: parser Error: syntax error at or near

标准

ISO/IEC 20546
ISO/IEC 20547系列 大数据参考体系结构(BDRA)国际标准
ISO/IEC 20547系列包括:
ISO/IEC TR 20547-1,信息技术——大数据参考体系结构——第1部分:框架和应用过程 :2020
ISO/IEC TR 20547-2,信息技术——大数据参考体系结构——第2部分:用例和派生需求
ISO/IEC 20547-3 ,信息技术——大数据参考体系结构——第3部分:参考体系架构
ISO/IEC 20547-4 ,信息技术——大数据参考体系结构——第4部分:安全和隐私
ISO/IEC TR 20547-5,信息技术——大数据参考体系架构——第5部分:标准路线图

ISO 9001: 2026是全球知名质量管理体系(QMS)标准的最新更新版本,将全面替代现行的ISO 9001: 2015。

使用 DuckDB 的 Python API 创建自定义函数(UDF), Python 将逻辑封装成一个函数,
使用 DuckDB 的 Python API 创建自定义函数(UDF), Python 将逻辑封装成一个函数,

多线程编程-quack

状态管理--了解当前运行到了多少,总数多少,现在运行了多少,进度是什么,成功多少,失败多少
资源管理-- batch_size 批量处理的数据大小,数据库处理的数据到一定程度的数据清理
# 分成5组,线程池大小 = 组数
资源--内存和cpu 以及硬盘大小和网络 输入输出I/O 时间资源--处理时间和等待时间

参考

https://duckdb.org/release_calendar

posted on 2026-05-21 17:54  辰令  阅读(92)  评论(0)    收藏  举报