Silk: 开源协作式纤程调度器
摘要
Silk 是一个面向 Linux 的开源协作式纤程调度器,具有每 CPU 调度线程、io_uring 集成和拓扑感知的工作窃取功能,专为低开销下的高并发而设计。
查看缓存全文
缓存时间: 2026/05/24 09:37
ClickHouse/silk
来源:https://github.com/ClickHouse/silk
Silk
一个面向 Linux 的协作式纤程调度器,具有每 CPU 调度线程、io_uring 集成和拓扑感知的任务窃取能力。纤程是轻量级的有栈协程,它们挂起而非阻塞其所属的 OS 线程,从而以较低开销实现高并发。
文档
docs/scheduler.md— 调度循环、上下文切换、挂起模式、异步 IO、睡眠取消、任务窃取设计及性能基准docs/sync.md— 同步原语:FiberFuture、FiberFutex、FiberMutex、FiberSequencer、FiberEvent、FairFiberMutexdocs/util.md— 工具库:无锁数据结构、TSC 计时、内存池、CPU 拓扑、日志、断言docs/perf.md—net-perf和file-perf基准测试结果及 fio 对比docs/coroutines.md— 无栈协程与有栈纤程:设计差异与性能数据src/fibers/tests/— 使用示例:纤程生命周期、future、同步原语、异步 IOsrc/gdb/fiber.py— GDB 扩展;通过source src/gdb/fiber.py加载,然后使用fiber-list、fiber-savecontext、fiber-restorecontext、fiber-switchcontext
依赖
- CMake >= 3.28
- Ninja
- Clang 21
- ccache(可选)
- Boost 头文件(
libboost-dev) - libelf(
libelf-dev)—— 可选,仅src/profiler需要;若缺失则静默跳过 profiler。
GTest、Google Benchmark、libbacktrace、liburing、librseq、libbpf、bpftool 和 cxxopts 以子模块形式捆绑在contrib/下,无需单独安装。用于纤程切换的两个 Boost.Context 汇编源文件放入contrib/fcontext/中,systemtap 的 USDT 头文件(和)放入contrib/systemtap-sdt/中(均为直接放入,非子模块)。Poco、AWS SDK 和 jemalloc 可通过向configure传递--build-poco、--build-aws和--build-jemalloc来按需构建。可选基准测试的运行时依赖:nginx(仅http-perf --nginx需要;默认使用http-perf二进制内置的基于 Poco 的内部服务器)、fio(用于fio-perf)和 MinIO(用于s3-perf)。如果未在 PATH 中找到 MinIO,会自动下载到.tools/目录;其余依赖需单独安装。
构建
./bb [选项] [命令]
全局选项
| 选项 | 值 | 默认值 | 描述 |
|---|---|---|---|
-b, --build | debug, release | debug | 构建类型 |
-s, --sanitizer | thread, address, memory, undefined | 启用 sanitizer | |
-v, --verbose | 在运行前打印每条命令;同时将 --verbose 传递给 perf 二进制以启用调试日志 |
命令
configure [--build-poco] [--build-aws] [--build-jemalloc]
配置(或重新配置)CMake 构建目录。可选标志启用默认关闭的组件:--build-poco 启用 http-perf(需要 Poco),--build-aws 启用 s3-perf(需要 AWS SDK),--build-jemalloc 启用 jemalloc(由 http-perf 和 s3-perf 使用以提升分配器性能)。
./bb configure ./bb configure --build-poco --build-aws ./bb -b release configure
fmt [--check]
使用 clang-format-21 格式化所有源文件。传递 --check 在不修改文件的情况下检查格式(若有文件将被更改则退出非零)。
./bb fmt ./bb fmt --check
clean
删除整个 build/ 目录。
./bb clean
build [目标]
构建项目。如果构建目录不存在则自动配置。当未指定命令时,build 是默认命令。
./bb # debug 构建 ./bb -b release # release 构建 ./bb -s thread # 带 TSan 的 debug 构建 ./bb -b release -s address # 带 ASan 的 release 构建 ./bb build fibers-test # 构建特定目标
test [-R 模式] [-N] [ctest 标志...]
构建并运行测试。使用所有可用 CPU 并行运行。任何额外标志直接传递给 ctest。
| 标志 | 描述 |
|---|---|
-R <模式> | 仅运行匹配正则表达式的测试 |
-N | 列出测试而不运行 |
--timeout SECONDS | 每个测试的超时时间(秒,默认 180,0 表示无限制) |
--coverage | 使用覆盖率检测、运行测试,并生成 HTML 报告、lcov 文件和 Cobertura XML 报告(位于 build/debug-coverage/ 下) |
--rerun-failed | 仅重新运行上次失败的测试 |
--repeat until-fail:<n> | 每个测试最多重复 n 次,首次失败即停止(适合查找不稳定测试) |
--output-on-failure | 测试失败时输出测试内容 |
| `` | |
| ./bb test | |
| ./bb test -R FiberMutex | |
| ./bb -s thread test | |
| ./bb test –rerun-failed | |
| ./bb test –coverage | |
| `` |
bench [-R 模式] [-N] [gbench 标志...]
构建并运行基准测试。
| 标志 | 描述 |
|---|---|
-R <模式> | 仅运行匹配模式的基准测试 |
-N | 列出基准测试而不运行 |
--timeout SECONDS | 每个基准测试的超时时间(秒,默认 180,0 表示无限制) |
| `` | |
| ./bb -b release bench | |
| ./bb -b release bench -R LockFreeQueue | |
| `` |
性能命令
每个 perf 命令构建相关二进制并运行基准测试,以 Markdown 表格形式输出结果。持续时间、预热和延迟选项可接受单位后缀(ns、us、ms、s、m);裸数字被视为秒。所有 perf 命令均接受 --timeout SECONDS(每次运行的超时时间;默认 180,0 表示无限制)。
file-perf
使用 io_uring 的异步文件 I/O 基准测试。
| 选项 | 默认值 | 描述 |
|---|---|---|
--file PATH | /dev/shm/file-perf.bin | 测试文件路径 |
--bs SIZE | 4k | 块大小 |
--size SIZE | 1g | 文件大小 |
--duration DURATION | 10 | 测量持续时间 |
--warmup DURATION | 2 | 预热持续时间 |
--numjobs N [N ...] | 1 | 并行作业数 |
--iodepth N [N ...] | 16 | 每个作业的 IO 队列深度 |
--rw MODE [MODE ...] | randread | 访问模式:randread、randwrite、seqread |
--flamegraph | 分析并生成火焰图 SVG | |
--print-counters | 每次运行后打印性能计数器 | |
| `` | ||
| ./bb -b release file-perf | ||
| ./bb -b release file-perf –bs 64k –size 4g | ||
| ./bb -b release file-perf –numjobs 1 16 –iodepth 1 16 | ||
| ./bb -b release file-perf –rw randread randwrite | ||
| ./bb -b release file-perf –flamegraph | ||
| `` |
fio-perf
使用 io_uring 引擎的 fio 对比。选项与 file-perf 相同(除 --flamegraph 和 --print-counters)。不构建任何东西。
./bb fio-perf ./bb fio-perf --bs 64k ./bb fio-perf --numjobs 1 16 --iodepth 1 16
net-perf
TCP 回显基准测试。启动本地服务器并运行客户端。当 --host 指向远程主机时,不在本地启动服务器。
| 选项 | 默认值 | 描述 |
|---|---|---|
--host | 127.0.0.1 | 服务器主机 |
--port | 17777 | 服务器端口 |
--msg-size BYTES | 64 | 回显消息大小 |
--duration DURATION | 10 | 测量持续时间 |
--warmup DURATION | 2 | 预热持续时间 |
--connections N [N ...] | 1000 | 要扫描的连接数 |
--delay DURATION | 0 | 服务端每条消息的延迟(例如 1ms、100us) |
--flamegraph | 分析客户端并生成火焰图 SVG | |
--print-counters | 每次运行后打印性能计数器 | |
| `` | ||
| ./bb -b release net-perf | ||
| ./bb -b release net-perf –connections 1 64 256 1024 | ||
| ./bb -b release net-perf –delay 1ms | ||
| ./bb -b release net-perf –host 10.0.0.2 | ||
| ./bb -b release net-perf –flamegraph | ||
| `` |
net-perf-asio
使用 Boost.Asio C++20 协程的 TCP 回显基准测试。选项与 net-perf 相同。
./bb -b release net-perf-asio ./bb -b release net-perf-asio --connections 1 64 256 1024 ./bb -b release net-perf-asio --delay 1ms ./bb -b release net-perf-asio --flamegraph
http-perf
HTTP/1.1 GET 基准测试。默认使用 silk 的内部 HTTP 服务器(基于 FiberSocketImpl 的 Poco HTTPServerConnection,每个连接一个纤程);传递 --nginx 则针对 nginx 运行。
| 选项 | 默认值 | 描述 |
|---|---|---|
--host | 127.0.0.1 | 服务器主机 |
--port | 18080 | 服务器端口 |
--duration DURATION | 10 | 测量持续时间 |
--warmup DURATION | 2 | 预热持续时间 |
--connections N [N ...] | 1000 | 要扫描的连接数 |
--delay DURATION | 0 | 服务端每个请求的延迟(例如 1ms、100us);纤程服务器使用 silk::FiberScheduler::sleep,nginx 使用 lua sleep |
--threads | 使用每连接线程客户端模式而非纤程 | |
--nginx | 客户机针对 nginx 而非内部服务器运行 | |
--flamegraph | 分析客户端并生成火焰图 SVG | |
--print-counters | 每次运行后打印性能计数器 | |
| `` | ||
| ./bb -b release http-perf | ||
| ./bb -b release http-perf –threads | ||
| ./bb -b release http-perf –nginx | ||
| ./bb -b release http-perf –delay 5ms | ||
| ./bb -b release http-perf –connections 1 512 1024 2048 | ||
| ./bb -b release http-perf –flamegraph | ||
| `` |
s3-perf
S3 对象存储基准测试。启动本地 MinIO 服务器(如果未在 PATH 中找到,会自动下载到 .tools/ 目录)并运行客户端。
| 选项 | 默认值 | 描述 |
|---|---|---|
--endpoint URL | http://127.0.0.1:9000 | S3 端点 |
--bucket NAME | test-bucket | S3 桶 |
--key NAME | test-object | S3 对象键 |
--region NAME | us-east-1 | S3 区域 |
--access-key KEY | minioadmin | S3 访问键 |
--secret-key KEY | minioadmin | S3 秘密键 |
--size SIZE | 4096 | 对象大小;无单位时为字节(例如 4096、64k、1g) |
--duration DURATION | 10 | 测量持续时间 |
--warmup DURATION | 2 | 预热持续时间 |
--numjobs N [N ...] | 1 | 并行作业数 |
--iodepth N [N ...] | 16 | 每个作业的 IO 队列深度 |
--rw MODE [MODE ...] | read | 访问模式:read、write、readwrite |
--threads | 同时使用线程执行器运行 | |
--flamegraph | 分析第一个配置并生成火焰图 SVG | |
--print-counters | 每次运行后打印性能计数器 | |
--data-dir PATH | /dev/shm/minio-data | MinIO 数据目录 |
| `` | ||
| ./bb -b release s3-perf | ||
| ./bb -b release s3-perf –rw read write | ||
| ./bb -b release s3-perf –numjobs 1 16 –iodepth 1 64 | ||
| ./bb -b release s3-perf –threads | ||
| ./bb -b release s3-perf –flamegraph | ||
| `` |
perf
一次运行多个 perf 基准测试。目标为位置值,列在选项之后。
| 目标 | 描述 |
|---|---|
file | file-perf |
fio | fio 对比 |
net | net-perf |
net-asio | net-perf-asio |
net-epoll | net-perf-epoll |
http | http-perf(内部服务器,纤程客户端) |
http-threads | http-perf(内部服务器,线程客户端) |
http-nginx | 针对 nginx 的 http-perf(纤程客户端) |
s3 | s3-perf(纤程) |
s3-threads | s3-perf(线程) |
all | 运行以上所有目标 |
| 选项 | 描述 |
| — | — |
--duration DURATION | 覆盖每二进制的测量持续时间(例如 60s) |
--warmup DURATION | 覆盖每二进制的预热持续时间(例如 10s) |
--timeout SECONDS | 每次运行的超时时间(默认 180,0 表示无限制) |
| `` | |
| ./bb -b release perf file net | |
| ./bb -b release perf all | |
| ./bb -b release perf –duration 60s –warmup 10s file net net-asio | |
| ./bb -b release perf –duration 60s –warmup 10s all | |
| `` |
相似文章
如何在低延迟的线程池上调度工作?
本文来自《The Old New Thing》,解释了Windows线程池是为吞吐量而非延迟优化的,并提供了低延迟调度的解决方案,例如创建自定义线程池或使用专用工作线程,并附有C++和C#的代码示例。
In Parallel
In Parallel 是一款面向执行的操作系统,专为管理和协调并行工作流与任务而设计。
通过HTTP提供文件的三种方式:同步、epoll和io_uring
一篇技术文章,比较了通过HTTP提供文件的三种方法:同步的每个请求一个线程、基于epoll的异步I/O和io_uring,并附有C语言代码示例。
Sim2Schedule:一种模拟器引导的LLM框架,用于自主露天矿调度
本文介绍Sim2Schedule,一种由模拟器引导的LLM框架,用于自主露天矿调度。该框架在计算时间线性扩展的情况下,能达到MILP最优净现值的94%-99%,且无需微调即可零样本运行。
我们捕获了智能体系统中的静默协调失败。接下来该发布什么?
一款旨在检测智能体系统中静默协调失败(如无限循环和流量激增)的开源工具,未来计划推出 FinOps 功能以追踪成本并防止预算超支。