ScyllaDB Seastar Perftune 实战指南:IRQ 绑定、CPU 掩码与 perftune.yaml 调优
【免费下载链接】scylladbNoSQL data store using the Seastar framework, compatible with Apache Cassandra and Amazon DynamoDB项目地址: https://gitcode.com/GitHub_Trending/sc/scylladb
Seastar Perftune(perftune.py)是 ScyllaDB 高性能运行的关键调优工具,它通过重新分配网卡与磁盘的 IRQ(中断)到指定 CPU 核、配置/proc/sys内核参数等手段,把大部分 CPU 核从中断处理中解放出来,供 ScyllaDB 的 Seastar 运行时独占使用。本文以 docs/operating-scylla/admin-tools/perftune.rst 为骨架,结合仓库内scylla_prepare、scylla_cpuset_setup等脚本源码,系统讲解 perftune.py 的全部命令行选项、perftune.yaml的生成与集群一致性要求,并给出可直接落地的配置示例与重启持久化方案。
Perftune 是什么:让 ScyllaDB 独占 CPU 核心
ScyllaDB 基于 Seastar 框架,采用 shared-nothing 的线程模型,每个 CPU 核心上运行一个独立的应用线程。要让 ScyllaDB 发挥最大性能,就必须把中断处理(IRQ)从应用线程所在的核心上挪走,避免中断风暴抢占 CPU 时间。perftune.py脚本正是为完成这一任务而生。
按照官方文档(docs/operating-scylla/admin-tools/perftune.rst)的描述,运行该脚本会依次完成以下工作:
- 阻止 irqbalance 移动相关 IRQ:将相关中断从 irqbalance 的管辖中“禁掉”,防止系统级中断均衡守护进程把 IRQ 移回应用核心;
- 配置
/proc/sys下的各种系统参数:对网络、磁盘相关的内核可调参数进行统一设置; - 按
irq_cpu_mask通过 SMP affinity 配置分发 IRQ:把中断绑定到指定的 CPU 核心上。注意:在大型机器上,IRQ 处理会使用不止一个物理核心(这一点在后续“CPU 掩码与集群一致性”一节会详细展开)。
值得一提的是,perftune 并非 ScyllaDB 独有,它是 Seastar 框架自带的脚本(原文链接指向seastar/scripts/perftune.py),ScyllaDB 发行版中将其以/opt/scylladb/scripts/perftune.py路径随包安装。在 docs/getting-started/_common/system-configuration-index.rst 的脚本清单中,perftune.py 的定位被描述为“配置各种系统参数以提升 Seastar 应用性能”,可见它是整个系统配置环节中面向性能的核心一环。
perftune.yaml:调优配置的输出与集群一致性
什么是 perftune.yaml
perftune.yaml是perftune.py脚本以--dump-options-file选项运行时的输出文件。脚本会依据当前机器硬件自动探测出一个合适的irq_cpu_mask(IRQ 绑定核心掩码),并把包括该掩码在内的完整调优配置以 YAML 格式打印出来,供后续重复执行使用。
在 ScyllaDB 的自动化部署中,这个文件被固定写入/etc/scylla.d/perftune.yaml。仓库源码 dist/common/scripts/scylla_prepare 中的create_perftune_conf()函数清晰地展示了这一流程:
- 读取
/etc/scylla.d/scylla-server配置,判断是否启用了 perftune 相关项; - 通过 hwloc-calc 计算
irq_cpu_mask(get_irq_cpu_mask()函数); - 执行
/opt/scylladb/scripts/perftune.py --tune net --nic ... --irq-cpu-mask ... --dump-options-file得到 YAML 内容; - 写入
/etc/scylla.d/perftune.yaml并设置 0644 权限。
集群一致性:同一个 irq_cpu_mask 至关重要
文档特别强调了一个容易踩坑的运维要点:集群中所有节点必须使用相同的irq_cpu_mask值,即使后续有新机器加入集群也一样。原因在于 ScyllaDB 的 CPU 布局会影响节点间的网络处理行为与性能特征,若集群出现“混合配置”(mixed-cluster)——即部分节点使用一套 IRQ 掩码、另一部分使用另一套——可能导致节点间处理中断的核不一致,进而产生性能不均衡与难以排查的问题。
只在文件不存在时生成
文档中有一个容易被忽略的细节:perftune.yaml仅当文件不存在时才会生成。仓库源码完全印证了这一点。在 dist/common/scripts/scylla_prepare 的create_perftune_conf()中有如下逻辑:
if os.path.exists('/etc/scylla.d/perftune.yaml'): return True params += ' --dump-options-file' yaml = out('/opt/scylladb/scripts/perftune.py ' + params) with open('/etc/scylla.d/perftune.yaml', 'w') as f: f.write(yaml)即:如果文件已存在,则直接返回并跳过生成步骤;只有文件缺失时才重新生成。这意味着手动定制过的perftune.yaml不会被自动覆盖,用户可以放心地手工编辑该文件实现自定义调优。
与之呼应的是 dist/common/scripts/scylla_cpuset_setup:当用户通过scylla_cpuset_setup修改 CPU 集(cpuset)时,脚本会主动删除已存在的/etc/scylla.d/perftune.yaml,强制下次启动时基于新的 cpuset 重新计算并生成调优配置,从而保证 IRQ 掩码与 CPU 集始终一致:
if cpuset != args.cpuset or smp != args.smp: if os.path.exists('/etc/scylla.d/perftune.yaml'): os.remove('/etc/scylla.d/perftune.yaml') ...同样的语义也出现在 docs/kb/customizing-cpuset.rst 中:“scylla-server服务只会在/etc/scylla.d/perftune.yaml不存在时生成它。”
perftune.py 全部命令行选项详解
文档以表格形式完整列出了perftune.py支持的命令行选项。以下是原文的完整继承与扩充(含默认值与使用说明):
| 选项 | 说明 |
|---|---|
--arfs | 启用/禁用 aRFS(Accelerated Receive Flow Steering,加速接收流转向)。 |
--cpu-mask | 指定要使用的核心掩码;默认使用所有可用核心。 |
--dev | 指定要优化的块设备,例如sda1;可多次使用以指定多个设备。 |
--dir | 指定要优化的目录;可多次使用以指定多个目录。 |
--dry-run | 只打印将要执行的调优建议,不实际执行任何操作。 |
--dump-options-file | 打印包含当前配置的 YAML 配置文件内容(即 perftune.yaml 的内容来源)。 |
--get-cpu-mask | 打印用于计算(ScyllaDB 计算核)的 CPU 掩码。 |
--get-cpu-mask-quiet | 打印用于计算的 CPU 掩码;当结果是零 CPU 集时也会打印零集(安静模式)。 |
--get-irq-cpu-mask | 打印用于 IRQ 绑定的 CPU 掩码。 |
--irq-core-auto-detection-ratio | 指定 IRQ 掩码自动探测的比例。例如给定 8 且请求自动探测时,则按cpu_mask值每 8 个可用 CPU 核心分配 1 个 IRQ CPU 核心。默认值为 16。 |
--irq-cpu-mask | 指定用于 IRQ 绑定的核心掩码。 |
--nic | 网卡接口名,默认eth0;可多次使用以指定多个接口。 |
--num-rx-queues | 设置给定数量的 Rx(接收)队列。 |
--options-file | 指定配置 YAML 文件(即后续直接使用 perftune.yaml 执行调优)。 |
--tune | 指定要调优的组件,可多次使用。可用值:net(调优网络)、disks(调优磁盘)、system(调优系统相关组件)。 |
--tune-clock | 强制调优/system/clocksource(时钟源)。默认false。需要与--tune配合使用。 |
--verbose | 输出更多操作细节及结果信息。 |
--write-back-cache | 启用/禁用磁盘的 write back(回写)缓存模式。 |
典型命令行用法
基于文档描述与仓库脚本(dist/common/scripts/scylla_prepare)的实际调用方式,常见用法如下:
# 1. 仅预览调优建议(不实际改动系统) perftune.py --tune net --nic eth0 --dry-run # 2. 只调优网络(官方推荐的网络配置方式,见 # docs/getting-started/_common/system-configuration-index.rst) perftune.py --tune net --nic eth0 # 3. 调优网络 + 磁盘 + 系统时钟,并指定 IRQ 掩码 perftune.py --tune net --nic eth0 --tune disks --dev sda1 \ --tune system --tune-clock --irq-cpu-mask 0x38 # 4. 输出配置 YAML(生成 perftune.yaml 的核心命令) perftune.py --tune net --nic eth0 --tune disks --dir /var/lib/scylla \ --dump-options-file > perftune.yaml # 5. 直接使用已生成的 YAML 执行调优(scylla_prepare 启动时的实际做法) perftune.py --options-file /etc/scylla.d/perftune.yaml与系统配置脚本的集成:scylla_prepare 如何驱动 perftune
在真实部署中,perftune 并不是孤立运行的,而是被 ScyllaDB 的发行版脚本体系所驱动。梳理仓库源码可以还原出完整的调用链:
调用链一:启动时自动调优
scylla_prepare 是“每次 ScyllaDB 启动且机器需要调优时自动运行”的脚本(见 docs/getting-started/_common/system-configuration-index.rst)。它读取/etc/scylla.d/scylla-server配置,并根据配置项组合出 perftune 参数:
IFNAME:网卡名,缺省回退为eth0;SET_CLOCKSOURCE=yes:追加--tune system --tune-clock;DISABLE_WRITEBACK_CACHE=yes:追加--write-back-cache=false。
随后按“先--dump-options-file生成 perftune.yaml、再--options-file执行调优”的两步走方式运行:
# 生成阶段(文件不存在时) params += ' --dump-options-file' yaml = out('/opt/scylladb/scripts/perftune.py ' + params) # ...写入 /etc/scylla.d/perftune.yaml # 执行阶段 run("{} --options-file /etc/scylla.d/perftune.yaml".format(perftune_base_command()), shell=True, check=True)其中perftune_base_command()定义于 dist/common/scripts/scylla_util.py:
def perftune_base_command(): return '/opt/scylladb/scripts/perftune.py {}'.format(disk_tune_param)调用链二:IRQ 掩码的自动推导
dist/common/scripts/scylla_prepare 中get_irq_cpu_mask()揭示了 IRQ 掩码的推导原理,值得单独说明:
- 读取
/etc/scylla.d/cpuset.conf中的CPUSET(如--cpuset 0,2-7,17-24,35); - 运行
hwloc-calc --pi all ~PU:0 ~PU:2-7 ...,即从“全部 CPU”中扣除ScyllaDB 计算核,得到 IRQ 核集合(CPU 掩码不变式:irq_cpu_mask | compute_cpu_mask == cpu_mask); - 若结果全零(说明所有 CPU 都被 ScyllaDB 占用),则 IRQ 掩码回退为“全部 CPU”,即 MQ(多队列)模式。
这正是文档中所说“脚本会确定irq_cpu_mask并打印到 perftune.yaml”的底层实现。
实际配置示例:cpuset.conf 与 perftune.yaml 的配合
perftune 的调优对象是 IRQ 绑定的核心,而 ScyllaDB 应用线程运行的核心由/etc/scylla.d/cpuset.conf决定。两者必须配合修改。以下三个示例来自仓库文档 docs/kb/customizing-cpuset.rst,均为 16 CPU 系统、网卡eth5、数据目录/var/lib/scylla的场景,可直接参考。
示例 1:ScyllaDB 与 IRQ 共用核心,其他应用共享网卡收益
- 场景:ScyllaDB 运行在 CPU 3、4、5 上,IRQ 也由这些核处理,同时希望机器上其他应用仍能从
eth5的 XFS/RFS/RPS 受益。
cpuset.conf:
CPUSET="--cpuset 3,4,5 "perftune.yaml:
cpu_mask: '0xffff' dir: - /var/lib/scylla irq_cpu_mask: '0x38' nic: - eth5 tune: - net - disks示例 2:ScyllaDB 独占 eth5(cpu_mask 与 irq_cpu_mask 相同)
- 场景:ScyllaDB 是唯一使用
eth5的应用,运行核与 IRQ 核同为 3、4、5。
cpuset.conf:
CPUSET="--cpuset 3,4,5 "perftune.yaml:
cpu_mask: '0x38' dir: - /var/lib/scylla irq_cpu_mask: '0x38' nic: - eth5 tune: - net - disks示例 3:IRQ 与计算核分离(IRQ 在 6、7、8 号核)
- 场景:ScyllaDB 运行在 CPU 3、4、5,IRQ 绑定到 CPU 6、7、8,同时允许其他应用受益于
eth5的 XFS/RFS/RPS。
cpuset.conf:
CPUSET="--cpuset 3,4,5 "perftune.yaml:
cpu_mask: '0xffff' dir: - /var/lib/scylla irq_cpu_mask: '0x1c0' nic: - eth5 tune: - net - disks可以看到三个示例的关键差异在于cpu_mask(ScyllaDB 可用的全部核)与irq_cpu_mask(IRQ 绑定的核)两个字段的取值组合,以及tune列表中net、disks的启用。手动修改perftune.yaml时务必保证这两个掩码符合上述不变式,避免中断与计算核冲突。
让调优在重启后持续生效
perftune.py所做的内核参数与 IRQ 绑定属于运行时设置,主机重启后会丢失。文档明确建议:创建一个 systemd unit,在主机启动时自动运行调优,确保调优在重启后依然生效。
在标准 ScyllaDB 安装中,这一建议已由发行版实现:scylla-server服务依赖的 scylla_prepare 会在每次启动时执行“生成/读取 perftune.yaml 并应用”的流程(前文调用链已述)。对于使用打包安装的用户,只需确认scylla-server服务正常启用即可。若是手工部署、或想独立于 ScyllaDB 服务维护调优,可自行创建类似下面的 unit 文件:
[Unit] Description=Tune network and disk for ScyllaDB with Seastar Perftune After=network.target [Service] Type=oneshot ExecStart=/opt/scylladb/scripts/perftune.py --options-file /etc/scylla.d/perftune.yaml [Install] WantedBy=multi-user.target配套调优建议(来自生产就绪检查清单)
仓库中的生产就绪文档 docs/operating-scylla/procedures/tips/production-readiness.rst 给出了两条与 perftune 直接相关的补充建议:
- 超过 8 个核心(或 16 个 vCPU)时,务必使用
mode: sq_split; - 确保
/etc/scylla.d/cpuset.conf中的 CPU 集与sq_split模式对应,并且物理核 0 的超线程从 CPU 列表中排除(物理核 0 通常专用于网卡 IRQ 等系统中断处理)。
这两条与 perftune 的 IRQ 绑定逻辑一脉相承:把系统中断集中到专用核(通常是 CPU 0 及其超线程兄弟),把其余物理核完整地交给 ScyllaDB。
常见问题速查
Q1:perftune.yaml 被我不小心改坏了,如何重新生成?删除/etc/scylla.d/perftune.yaml后重启scylla-server,或手动执行perftune.py --tune net --nic <iface> --tune disks --dir /var/lib/scylla --dump-options-file重新生成(文件不存在时 scylla_prepare 会自动重建)。
Q2:修改了 cpuset.conf 后 perftune.yaml 还是旧的吗?不会。scylla_cpuset_setup在检测到 cpuset 变化时会删除旧的 perftune.yaml(见 dist/common/scripts/scylla_cpuset_setup),下次启动基于新 CPU 集重新计算 IRQ 掩码。
Q3:--tune-clock报错?该选项强制调优/system/clocksource,文档明确标注“默认 false,需要与--tune选项配合使用”。请确保命令中同时包含--tune system。
Q4:大机器上 IRQ 只用 1 个核够吗?文档指出,在大型机器上 IRQ 处理会使用不止一个物理核心。这正是--irq-core-auto-detection-ratio(默认 16)所控制的比例:每 16 个可用核心自动分配 1 个 IRQ 核,比例可通过该选项调整。
Q5:如何确认当前实际生效的配置?使用perftune.py --get-cpu-mask、--get-irq-cpu-mask查看计算核与 IRQ 核掩码;用--dry-run在不改动系统的情况下预览全部调优动作;--verbose可输出每个操作的详细结果。
小结
Seastar Perftune 是 ScyllaDB 性能调优体系的基石:它以 IRQ 绑定为核心,通过perftune.yaml固化配置,配合scylla_prepare在每次启动时自动应用,确保中断处理与 ScyllaDB 计算核互不干扰。理解cpu_mask与irq_cpu_mask的关系、保持集群内irq_cpu_mask一致、并在修改 cpuset 后让 perftune.yaml 重新生成,是保障集群性能均衡的三个关键运维动作。更多背景可参考 docs/operating-scylla/admin-tools/index.rst 与 docs/operating-scylla/_common/tools_index.rst。
【免费下载链接】scylladbNoSQL data store using the Seastar framework, compatible with Apache Cassandra and Amazon DynamoDB项目地址: https://gitcode.com/GitHub_Trending/sc/scylladb
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考