尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Turso 连接性能基准测试指南:对比 Limbo 与 rusqlite 在万表规模下的建连耗时

Turso 连接性能基准测试指南:对比 Limbo 与 rusqlite 在万表规模下的建连耗时 Turso 连接性能基准测试指南对比 Limbo 与 rusqlite 在万表规模下的建连耗时【免费下载链接】tursoA SQL database in Rust: SQLite-compatible, now also speaking Postgres (experimental). The LLVM of databases.项目地址: https://gitcode.com/GitHub_Trending/tu/turso导读本指南围绕 turso 仓库 perf/connection 目录下的连接Connection基准测试展开系统讲解如何测量打开一个数据库连接这一操作的耗时并对比两套实现用 Rust 从零实现的 SQLite 兼容数据库 Limbo即本仓库核心turso_core以及官方 SQLite 的 Rust 绑定 rusqlite。你将掌握完整的基准测试运行流程、数据库生成脚本的参数语义、以 HDR 直方图统计的百分位耗时p50/p90/p95/p99 等解读方法以及两个 benchmark 程序在源码层面的实现差异。基准测试背景为什么要测量建连耗时连接connection是数据库访问的最基本单元。在实际应用中每次请求通常都会打开一个新连接、执行 SQL、再关闭连接因此打开连接并准备一条语句的耗时直接决定了短查询场景下的延迟上限。当数据库 schema 中包含大量表时例如万表规模的库打开连接往往需要扫描并解析 schema这一成本会随表数量增长而放大。本仓库中的 perf/connection/README.md 明确了该基准测试的目标测量打开一个到包含不同数量表1,000、10,000 甚至 100,000 张表的数据库连接所需的时间。它在 limbo 与 rusqlite 两个目录中各自维护了一份独立可运行的 benchmark从而可以对比 Limbo 与 SQLite经 rusqlite在 schema 规模增大时的建连性能曲线。基准测试目录结构在开始运行之前先理清 perf/connection 目录的组织方式perf/connection/ ├── README.md # 运行说明本文主体 ├── gen-database.py # 数据库生成脚本根目录版本 ├── gen-databases # 批量生成脚本根目录版本 ├── plot.py # 结果可视化脚本 ├── limbo/ │ ├── gen-database.py # Limbo 侧的数据库生成脚本 │ ├── gen-databases # Limbo 侧批量生成脚本 │ ├── run-benchmark.sh # Limbo 侧基准运行脚本 │ ├── plot.py # Limbo 侧绘图脚本 │ └── src/main.rs # Limbo 连接 benchmark 程序 └── rusqlite/ ├── gen-database.py # rusqlite 侧的数据库生成脚本 ├── gen-databases # rusqlite 侧批量生成脚本 ├── run-benchmark.sh # rusqlite 侧基准运行脚本 ├── plot.py # rusqlite 侧绘图脚本 └── src/main.rs # rusqlite 连接 benchmark 程序limbo 与 rusqlite 两个子目录内的脚本gen-database.py、gen-databases、run-benchmark.sh、plot.py内容完全一致只是运行的是各自的二进制程序。因此你可以在两个目录中分别执行相同流程得到两份可对比的results.csv。三步运行流程按照 perf/connection/README.md 的说明在rusqlite和limbo目录中依次执行./gen-databases ./run-benchmark.sh第一步生成测试数据库第二步编译并运行 benchmark 程序、把百分位耗时写入results.csv。下面拆解每一步。第 1 步生成测试数据库gen-database.py使用 Python 标准库sqlite3生成指定表数量的数据库核心逻辑如下见 perf/connection/limbo/gen-database.py通过PRAGMA journal_modeWAL启用 WAL 日志模式循环创建table_0、table_1……共-t指定数量的表每张表包含id INTEGER PRIMARY KEY、name TEXT、value INTEGER、created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP四个字段每张表插入一行样例数据item_{i},i以保证数据库内容更接近真实场景最后打印创建结果并提交、关闭连接。命令行参数只有两个位置参数filename指定输出数据库文件路径-t/--tables指定表数量。例如python3 gen-database.py database_10.db -t 10而gen-databases见 perf/connection/limbo/gen-databases是批量执行入口依次生成四个表数量的数据库python3 gen-database.py database_10.db -t 10 python3 gen-database.py database_1k.db -t 1000 python3 gen-database.py database_5k.db -t 5000 python3 gen-database.py database_10k.db -t 10000即实际生成 10、1,000、5,000、10,000 张表四个档位的数据库。README 中提到的 100,000 张表属于该基准测试设计上可覆盖的更大规模场景你同样可以用-t 100000生成默认脚本则以 10k 为最大档位以保证生成耗时可控。第 2 步编译并运行 benchmarkrun-benchmark.sh见 perf/connection/limbo/run-benchmark.sh完成两件事编译cargo build --release定位产物通过仓库根目录下的 scripts/cargo-target-dir 查询 cargo 的真实 target 目录该脚本用cargo metadata --no-deps --offline解析 workspace 的target_directory从而兼容CARGO_TARGET_DIR被重定向的场景再拼接出 release 二进制路径逐个运行对database_10.db、database_1k.db、database_5k.db、database_10k.db依次执行$RELEASE_DIR/limbo-connection-benchmark $db --iterations 1000 | tail -1 results.csvrusqlite 侧的脚本perf/connection/rusqlite/run-benchmark.sh完全相同只是二进制名为rusqlite-connection-benchmark。脚本先写入 CSV 表头database,iterations,p50,p90,p95,p99,p999,p9999,p99999再把每个数据库 benchmark 程序输出的最后一行即百分位统计行追加到results.csv最终打印整个文件。第 3 步可视化可选两个目录下都提供了 plot.py用 matplotlib 读取results.csvpython3 plot.py results.csv它会提取每行的database、p50、p95、p99三列绘制分组柱状图X 轴为不同表数量的数据库Y 轴为建连耗时纳秒并使用log对数刻度以便同时呈现数量级差异较大的数据最终以 300 DPI 保存为connection_benchmark.png并弹出显示。两个 benchmark 程序的实现对比两个程序的代码结构高度对称分别见 perf/connection/limbo/src/main.rs 与 perf/connection/rusqlite/src/main.rs便于公平对比。核心差异在于连接打开方式维度Limboturso_corerusqlite连接 APIDatabase::open_file(io, path, false)打开数据库对象再db.connect()建立连接Connection::open(path)一步建立连接IO 抽象显式传入PlatformIO通过Arc共享内部封装 libsqlite3 的文件 IO被测语句SELECT name FROM table_0 WHERE id ?SELECT name FROM table_0 WHERE id ?完全一致统计hdrhistogram::Histogramu64hdrhistogram::Histogramu64完全一致CLIclap 派生-i/--iterations默认 100clap 派生-i/--iterations默认 100Limbo 侧实现要点Limbo 的程序二进制名limbo-connection-benchmark见 perf/connection/limbo/Cargo.toml直接依赖 workspace 内的turso_corecratepath ../../../core体现了该基准测试与核心引擎的紧耦合let io Arc::new(PlatformIO::new().unwrap()); let db Database::open_file(io.clone(), opts.database, false).unwrap(); for i in 0..opts.iterations { let start Instant::now(); let conn db.connect().unwrap(); let _stmt conn.prepare(SELECT name FROM table_0 WHERE id ?).unwrap(); let elapsed start.elapsed(); hist.record(elapsed.as_nanos() as u64).unwrap(); ... }关键点Database::open_file在循环之外只执行一次含 schema 加载而每次迭代重复执行的是db.connect()加prepare——这正是该基准测试的测点在 schema 已经就绪的前提下新建连接并准备语句的成本。PlatformIO是 turso 核心层的平台 IO 抽象位于 core/io以Arc共享给数据库实例。rusqlite 侧实现要点rusqlite 的程序二进制名rusqlite-connection-benchmark见 perf/connection/rusqlite/Cargo.toml通过 workspace 依赖rusqlite每次迭代调用Connection::open打开并解析 schema随后 prepare 同一条语句。由于Connection::open本身就包含 schema 读取与解析它与 Limbo 侧open_file 一次 反复 connect的测点不完全等价——这是阅读对比数据时需要注意的前提差异Limbo 侧测的是连接复用同一已打开数据库的场景rusqlite 侧测的是每次完整打开文件的场景。两边的统计口径完全一致都使用hdrhistogramcrate记录每次操作的纳秒耗时最终输出 p50/p90/p95/p99/p999/p9999/p99999 七个百分位。histogram 以Histogram::u64::new(2)创建即 2 位有效数字的 HDR 直方图。结果输出格式解读无论 Limbo 还是 rusqlite最终都输出一行 CSV 格式的数据tail -1取的就是这一行database,iterations,p50,p90,p95,p99,p999,p9999,p99999 10k,1000,13713,18001,19457,23553,40575,90113,147457各字段含义database从文件名提取的表数量标识database_10k.db→10k见main.rs中replace(.db, ).replace(database_, )iterations本次运行的迭代次数脚本固定传 1000p50/p90/p95/p99第 50/90/95/99 百分位建连耗时纳秒分别代表典型值、常见尾部延迟和极端尾部延迟p999/p9999/p99999第 99.9/99.99/99.999 百分位耗时纳秒用于观察极端异常值如页面缓存未命中、调度抖动。解读时建议重点观察两个趋势(1) 随表数量从 10 → 1k → 5k → 10k 增长p50 与 p99 是否同步上升可判断 schema 规模对建连成本的放大效应(2) Limbo 与 rusqlite 在同档位下的 p50/p99 对比可评估两套实现在建连路径上的相对开销。实战运行示例在仓库根目录依次执行假设已安装 Python3、Rust 工具链与 cargo# 1. 生成测试数据库limbo 目录 cd perf/connection/limbo ./gen-databases # 2. 编译并运行 Limbo benchmark约 1000 次迭代 x 4 个数据库 ./run-benchmark.sh # 3. 生成可视化图表 python3 plot.py results.csv再在 rusqlite 目录重复以上三步两份results.csv即可用于交叉对比。注意run-benchmark.sh依赖git rev-parse --show-toplevel定位仓库根目录因此请在 git 仓库内执行release 编译可能需要几分钟--iterations默认 100脚本中显式传 1000 以获得更稳定的百分位估计。适用前提与局限该基准测试面向 Linux/macOS 类 Unix 环境脚本为 bash Python3未提供 Windows 版本被测语句固定为SELECT name FROM table_0 WHERE id ?只覆盖建连 单语句 prepare 路径不代表读写吞吐、事务或并发场景的结论两个实现Database::open_fileconnect对比Connection::open测点不完全对等对比结果应结合第 4 节的前提差异理解数值均为本机环境硬件、文件系统、WAL 状态、缓存热度相关的相对参考值不宜跨机器直接比较。延伸阅读core/database.rsDatabase::open_file与connect的实现core/ioPlatformIO等平台 IO 抽象perf/README.md仓库性能测试总览perf/connection/limbo/gen-database.py 与 perf/connection/rusqlite/gen-database.py数据库生成逻辑perf/connection/plot.py结果绘图脚本。【免费下载链接】tursoA SQL database in Rust: SQLite-compatible, now also speaking Postgres (experimental). The LLVM of databases.项目地址: https://gitcode.com/GitHub_Trending/tu/turso创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表