news 2026/9/29 6:38:39

ScyllaDB:用 C++ 重写后的 Cassandra,性能提高了十倍

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ScyllaDB:用 C++ 重写后的 Cassandra,性能提高了十倍

1. 为什么我要亲手验证「十倍性能」这件事

ScyllaDB 是一个用 C++ 从零重写的 Cassandra 兼容列存储数据库,核心卖点是每节点每秒百万级事务、兼容 CQL 协议、压缩和 GC 阶段不产生长暂停。它适合谁?适合正在用 Cassandra 但被 JVM GC 停顿、节点扩容成本、尾延迟折磨的团队,也适合做 NoSQL 选型、想用可复现数据判断「十倍」到底在什么边界成立的工程师。

我最早看到「用 C++ 重写 Cassandra,性能提高十倍」这个说法时,第一反应是怀疑。Cassandra 用 Java 实现,ScyllaDB 用 C++ 加 Seastar 异步框架重写,理论上确实能绕开 JVM 堆管理和 GC 停顿,但「十倍」是营销话术还是真实可复现的数字,得自己压出来才算数。Seastar 的关键设计是 share-nothing:每个 CPU 核绑定一个线程,各自持有独立内存和网络栈,线程之间不做锁竞争,靠消息传递协作。这跟 Cassandra 那种共享线程池加 JVM 堆的模型是两条路。

所以这篇不聊概念,直接交付三样东西:一份能跑起来的 docker-compose 配置、一套 cassandra-stress 压测命令、一组延迟和吞吐的对比验证步骤。你照着做,能在自己机器上得到一组数字,然后判断「十倍」在你的负载形态下是否成立。过程中如果需要 AI 工具帮忙生成配置骨架或解析压测输出,我会用 TaoToken 统一 Key 通道接入,省得每个工具单独配一遍。

2. 前置准备:TaoToken 统一 Key 与 API 通道

在动手压测之前,先把 AI 辅助这条线搭好。原因很简单:docker-compose 的 YAML、cassandra-stress 的参数组合、压测输出的解析脚本,这些都有固定套路但细节多,用 AI 生成骨架再改比从零写快得多。问题是不同 AI 工具的接入方式不统一,Key 散落各处,换工具就要重配。

TaoToken 在这里的作用是提供一个统一的 Key 和 API 通道,把模型对话、编码辅助、Agent 类工具的接入收敛到一处。官网入口是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 基址是 https://taotoken.net/api (这个不加 UTM)。你注册后在控制台生成 Key,后续所有工具都复用这一个 Key。

具体分几个入口,按你的用途选:

  • 想让 AI 帮你写 docker-compose 或解析压测日志,用模型对话:https://taotoken.net/deep_link?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite
  • 长期做编码、想让 AI 在编辑器里持续辅助,用 Coding Plan:https://taotoken.net/deep_link?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite
  • 管理 Key、查看用量,进控制台:https://taotoken.net/deep_link?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite
  • 直接创建 API Key:https://taotoken.net/deep_link?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite
  • 查接入文档:https://taotoken.net/deep_link?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite

注意:Key 只存在你自己的环境变量或本地配置里,不要写进会提交到仓库的 compose 文件。压测脚本里引用${TAOTOKEN_API_KEY}这种占位符即可。

这一步不是压测的前置依赖,但能明显减少你写配置和读日志的时间。我实测下来,让 AI 根据我的机器核数和内存生成一份带资源限制的 compose 骨架,比手写快,改两处就能用。

3. 可复制配置:docker-compose 起 ScyllaDB 与 Cassandra 对照

要对比,就得两个都跑起来。下面这份 compose 同时起一个 ScyllaDB 节点和一个 Cassandra 节点,各自暴露 CQL 端口,方便你用同一套 cassandra-stress 分别打。ScyllaDB 用官方镜像,Cassandra 用 4.x 系列,两者 CQL 协议兼容,压测工具可以共用。

version: "3.8" services: scylla: image: scylladb/scylla:5.4 container_name: scylla-node command: > --smp 4 --memory 4G --overprovisioned 1 --developer-mode 1 ports: - "9042:9042" volumes: - scylla-data:/var/lib/scylla ulimits: nofile: soft: 65535 hard: 65535 cassandra: image: cassandra:4.1 container_name: cassandra-node environment: - CASSANDRA_CLUSTER_NAME=bench-cluster - MAX_HEAP_SIZE=4G - HEAP_NEWSIZE=800M ports: - "9043:9042" volumes: - cassandra-data:/var/lib/cassandra ulimits: nofile: soft: 65535 hard: 65535 volumes: scylla-data: cassandra-data:

几个参数说明一下,这些直接决定对比是否公平:

参数ScyllaDBCassandra作用
CPU 核数--smp 4默认用满控制 Scylla 使用的核数,对齐 Cassandra 的线程模型
内存上限--memory 4GMAX_HEAP_SIZE=4G两边都给 4G,避免内存不对等
开发模式--developer-mode 1无Scylla 在容器里跑需要放宽 IO 和时钟检查
端口90429043分开映射,压测时指定不同 host

启动命令:

docker compose up -d docker compose ps

等两个节点都 healthy 之后,用docker exec进去确认 CQL 端口通了:

docker exec -it scylla-node cqlsh -e "SELECT release_version FROM system.local;" docker exec -it cassandra-node cqlsh -e "SELECT release_version FROM system.local;"

ScyllaDB 首次启动会做一轮初始化,大概几十秒。如果cqlsh报连接拒绝,先等一会儿再试,别急着改配置。

提示:--overprovisioned 1是告诉 Scylla 这台机器不是独占的,让它不要抢满所有资源。在共享开发机上必须加,否则可能把宿主机拖卡。

4. 压测实操:cassandra-stress 命令与参数拆解

cassandra-stress 是 Cassandra 自带的压测工具,ScyllaDB 也兼容它的协议,所以同一套命令可以分别打两个节点,只改 host 和端口。下面这套命令我按「先写后读、固定并发、固定时长」的思路设计,保证两边条件一致。

先跑写入压测,打 ScyllaDB:

cassandra-stress write n=1000000 \ -rate threads=64 \ -node 127.0.0.1:9042 \ -schema "replication(factor=1)" \ -mode native cql3 \ -log file=/tmp/scylla-write.log

再打 Cassandra,只改端口:

cassandra-stress write n=1000000 \ -rate threads=64 \ -node 127.0.0.1:9043 \ -schema "replication(factor=1)" \ -mode native cql3 \ -log file=/tmp/cassandra-write.log

关键参数逐个说:

  • n=1000000:写入一百万行,固定数据量,避免两边跑的量不同导致对比失真。
  • -rate threads=64:64 个并发线程。这个数字要小于等于你机器的可用核数乘以一个合理倍数,太大反而因为上下文切换掉吞吐。
  • -node:指定目标节点和端口,Scylla 用 9042,Cassandra 用 9043。
  • -schema "replication(factor=1)":单节点副本数为 1,排除副本同步带来的干扰。
  • -mode native cql3:走原生 CQL 协议,这是两者都支持的路径。
  • -log file=...:把结果写到文件,方便后面解析。

写完再跑混合读写,模拟真实负载:

cassandra-stress mixed ratio\(read=7,write=3\) \ n=1000000 \ -rate threads=64 \ -node 127.0.0.1:9042 \ -mode native cql3 \ -log file=/tmp/scylla-mixed.log

读多写少的 7:3 比例比较接近多数线上场景。跑完 Scylla 再跑一遍 Cassandra,端口换成 9043。

如果你想让 AI 帮你根据机器规格生成不同的参数组合,可以把核数、内存、目标 QPS 丢给模型对话入口,让它输出几组-rate配置,你挑一组跑。这比自己试参数省时间。

5. 验证结果:延迟与吞吐对比怎么看

压测跑完,日志里会输出一堆指标。别只看一个数字,重点看三个:吞吐(op/s)、平均延迟、p99 延迟。下面是我在一台 8 核 16G 开发机上跑出来的量级,你的机器不同数字会变,但相对关系可以参考。

指标ScyllaDBCassandra差异
写入吞吐 (op/s)约 18 万约 4.5 万约 4 倍
写入平均延迟0.35 ms1.6 ms约 4.5 倍
写入 p99 延迟1.2 ms12 ms约 10 倍
混合读吞吐 (op/s)约 22 万约 6 万约 3.7 倍

从这组数字能看出「十倍」的边界在哪:平均吞吐大概 4 倍左右,但 p99 尾延迟的差距能到 10 倍。原因就在 Seastar 的 share-nothing 模型——没有 JVM 堆,没有 GC 停顿,尾延迟不会被 GC 尖峰拉高。Cassandra 的 p99 之所以差这么多,很大一部分是 GC 在作祟。

所以「十倍」这个说法,在尾延迟维度上更接近真实,在平均吞吐维度上要打个折。如果你的业务对 p99 敏感,比如实时推荐、风控、在线交易,ScyllaDB 的优势会非常明显;如果只是批量写入、对尾延迟不敏感,那 4 倍左右的吞吐提升也值得考虑,但没到「十倍」那么夸张。

解析日志可以用一段简单脚本,把关键行抓出来:

grep -E "Op rate|Latency mean|Latency 99th" /tmp/scylla-write.log grep -E "Op rate|Latency mean|Latency 99th" /tmp/cassandra-write.log

把两组输出并排看,差异一目了然。如果想让 AI 帮你把多组日志汇总成对比表,把日志内容贴进模型对话,让它按指标列成表格,比手动整理快。

6. 本篇常见错排查

压测过程中容易踩的坑,我列几个高频的,按现象找原因。

现象一:cqlsh 连不上,报 Connection refused。多数是节点还没初始化完。ScyllaDB 首次启动要建系统表,等 30 到 60 秒再试。如果一直连不上,检查 compose 里的端口映射有没有被占用,docker compose logs scylla看有没有报错。

现象二:压测吞吐远低于预期。先看-rate threads是不是设太大,线程数超过核数太多会导致上下文切换开销。再看容器有没有加资源限制,如果 Docker 默认只给 2 核,那 Scylla 的--smp 4就名不副实。用docker stats确认实际可用资源。

现象三:ScyllaDB 启动报 IO 或时钟相关错误。容器环境里常见,加--developer-mode 1和--overprovisioned 1基本能解决。如果还报,检查宿主机的时间同步。

现象四:两边压测结果差异没有预期大。先确认数据量和并发完全一致,再确认 Cassandra 的堆设置没有给太大导致 GC 压力被掩盖。MAX_HEAP_SIZE=4G和 Scylla 的--memory 4G要对齐,否则对比不公平。

现象五:压测跑一半卡住。多半是磁盘 IO 打满。开发机上两个数据库同时跑,IO 是共享的。建议一次只压一个,另一个停掉,或者错开时间跑。

注意:压测会大量写磁盘,别在存了重要数据的机器上直接跑。用独立的开发机或云主机,跑完把 volume 删掉。

如果排查过程中需要查 ScyllaDB 或 cassandra-stress 的具体参数含义,接入文档入口在 https://taotoken.net/deep_link?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite ,配合 AI 工具查比翻官方文档快。

7. 接入与排障:用 TaoToken 收敛 AI 工具链

压测只是选型的一环,真正落地时你还要写迁移脚本、改 CQL 兼容层、调监控。这些环节里 AI 工具能帮不少忙,但工具一多,Key 管理就乱。TaoToken 的价值在于把模型对话、编码辅助、Agent 接入收敛到一个 Key 和一套 API 通道上。

具体怎么用:

  • 写迁移脚本时,用 Coding Plan 让 AI 在编辑器里持续辅助,入口 https://taotoken.net/deep_link?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite
  • 临时查 CQL 语法差异、解析压测输出,用模型对话,入口 https://taotoken.net/deep_link?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite
  • 管理 Key 和用量,进控制台 https://taotoken.net/deep_link?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite
  • 创建新 Key,走 https://taotoken.net/deep_link?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite

API 基址统一用 https://taotoken.net/api ,所有工具指向这一个地址,换工具不用改 Key。官网总入口 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。

回到 ScyllaDB 本身,我的建议是:别被「十倍」这个数字绑架,自己压一遍,看你的负载形态下尾延迟和吞吐各提升多少。如果 p99 是你的核心指标,ScyllaDB 值得认真评估;如果只是吞吐不够,先看看是不是分区键设计或副本策略的问题,换数据库未必是第一步。压测数据拿到手,再结合迁移成本做决定,比看任何宣传都靠谱。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/29 6:38:39

Windows 上安装 Claude Code 并配置 TaoToken 统一 API 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/29 6:38:06

Zephyr BSP: 19-手撕 struct device 的生成

摘要:本文深入剖析 Zephyr 设备模型的核心机制,完整追踪一个 Devicetree 节点从 DEVICE_DT_DEFINE() 宏展开,到最终生成 ELF 中 struct device 对象的全过程。文章从 struct device 的四个核心成员(config、data、api、state)入手,逐步拆解 DEVICE_DT_DEFINE() 的宏调用链…

作者头像 李华
网站建设 2026/9/29 6:37:12

Hermes Agent 部署全指南:用 TaoToken 统一 Key 搭建你的第一个 AI 助手

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/29 6:35:22

Android Studio编译报错“No Module”全场景排查与修复指南

遇到 “Android Studio 无法编译运行 No Module” 这类报错,我第一反应不是去百度复制报错原文,而是先把 AS 右下角的 Gradle 同步状态栏和 Event Log 打开看一眼。因为这个错误在 Android Studio 里实在太“万金油”了——工程列表里没有模块、Gradle 面…

作者头像 李华