ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ScyllaDB 性能隔离机制:调度组、控制器与跨节点 RPC 隔离的实现解析

ScyllaDB 性能隔离机制:调度组、控制器与跨节点 RPC 隔离的实现解析 ScyllaDB 性能隔离机制调度组、控制器与跨节点 RPC 隔离的实现解析【免费下载链接】scylladbNoSQL data store using the Seastar framework, compatible with Apache Cassandra and Amazon DynamoDB项目地址: https://gitcode.com/GitHub_Trending/sc/scylladbScyllaDB 的每个 shard 在同一时刻并行承担多种职责作为协调节点处理 CQL 请求并分发给副本作为副本执行读写将 memtable 刷入 SSTable执行 compaction以及运行 repair、gossip 等后台任务。本文基于官方设计文档 docs/dev/isolation.md讲解 ScyllaDB 如何利用 Seastar 的调度组scheduling groups实现 CPU 与 I/O 层面的性能隔离、如何通过控制器controllers动态调节各组件的资源份额以及如何在跨节点 RPC 调用中保持隔离语义并结合仓库源码给出可验证的实现细节。为什么 shard 内部需要性能隔离ScyllaDB 是共享架构shared-everything设计一个 shard 内协调路径、副本读写路径、内存表刷盘、SSTable 合并、repair 与 gossip 等所有工作都运行在同一组 reactor 线程上。如果不做资源划分就会出现典型的相互干扰问题后台 compaction 跑得越快用户查询的吞吐和延迟波动越大compaction 进行中查询性能下降结束后又回升形成锯齿状曲线但盲目放慢 compaction 又会积累 compaction backlog反过来拖累后续读性能。因此官方文档为性能隔离机制确立了两个目标隔离isolate每个组件的吞吐与延迟不应依赖其他组件的实现细节如其并行度、I/O 量可控controlScylla 能够主动决定每个组件分得多大的资源份额而不是写死一个静态比例。以 compaction 为例理想状态是后台合并刚好够用既要保证新任务出现之前完成旧任务又不能比必要速度更快否则用户查询性能会被周期性拉低。实现上ScyllaDB 复用了 Seastar 现有的隔离特性——调度组用于 CPU 时间隔离与 I/O 调度用于 I/O 带宽隔离。本文聚焦于 ScyllaDB 如何组织这些 Seastar 特性而非 Seastar 本身的调度算法细节。调度组CPU 调度器全局资源份额的划分ScyllaDB 定义了一批 Seastar 调度组作用域是全局的不是 per-table、per-keyspace。这些组在 main.cc 的启动流程中创建并保存到 database 对象的database_config结构中定义见 replica/database.hh。官方文档中列出的调度组及初始份额shares如下名称database_config::*_scheduling_group初始份额default即 system1000memtable1000memtable_to_cache1000compaction1000memory_compaction1000statement1000gossip1000streaming即 maintenance200从源码看实际创建的调度组比文档表格更多当前版本的 main.cc 中实际创建的调度组名称、缩写、初始份额包括compaction缩写comp1000 份额——常规 compactionmaintenance_compactionmanc200隶属 maintenance supergroup——低优先级的维护性合并mem_compaction1000——内存 compactionlogstor_compaction1000——log 型存储logstor段的合并streamingstrm200隶属 maintenance supergroup——数据流传输同时用于 repair 等维护场景maintenancemant200——maintenance 超级组supergroup总量 200 份额下的通用后台任务组statementstmt1000隶属 user supergroup——CQL 语句执行memtablemt1000——内存表刷盘memtable_to_cachemt2c200——写入行缓存的路径gossipgms1000commitlogclog1000与schema_commitlogsclg1000——提交日志落盘backupbckp200隶属 maintenance supergroup——SSTable 备份/克隆此外还有一个低份额的background_reclaimbgre50见 main.cc专门用于空闲时的 LSA 内存回收/碎片整理。值得注意的是源码中已经引入了调度组超级组scheduling supergroupmaintenance_supergroup create_scheduling_supergroup(200)main.ccmaintenance、streaming、backup、maintenance_compaction 等低优先级组都嵌套在其中——即这些组之间的份额竞争先发生在 200 份额的总量内部再以 200 份额的总量与前台组竞争。这正是官方文档Additional notes一节中提到的方向嵌套组让两个 statement 类的组彼此竞争而不与 compaction 竞争。各调度组的用途与份额的动态调节文档对每个组的用途留有说明性注释结合源码可以确认其归属defaultsystem未显式指定调度组的通用工作如 gossip 心跳之外的系统路径使用的兜底组memtablememtable 刷盘flush到 SSTable 的工作statementCQL 语句在 replica 侧的执行上下文streaming / maintenanceSSTable 流式传输与 repair 等维护操作共享的低优先级路径compaction / memory_compaction / logstor_compaction三类不同对象常规 SSTable、内存 compaction、logstor 段的合并工作。初始份额只是启动时的值。这些组的 shares 之后会被**控制器controllers**动态修改当某个组件落 behind如 compaction backlog 增长时调高其份额当它完成得比必要更快引起查询性能波动时调低其份额。份额是 Seastar 调度器的配额份额更高的组分得更多 CPU 时间片与 I/O 带宽。另外I/O 隔离与 CPU 隔离是成对配置的例如 main.cc 中为 compaction 组挂了io_throughput_updater(compaction, ..., cfg-compaction_throughput_mb_per_sec)main.cc 为 streaming 组挂了stream_io_throughput_mb_per_sec限速——I/O 调度器的带宽上限与 CPU 调度组的份额共同构成一条组件的完整资源边界。控制器Controllers动态份额调节官方文档的 Controllers 一节指向 compaction_controller.md其核心思想是在控制器出现之前各组份额在启动时静态确定——能公平但不能最优每个 compaction 策略SizeTiered、TimeWindow 等各自定义backlog待完成合并工作量的估计值每张表维护自己的 backlog汇总成系统级 backlog控制器根据 backlog 的大小周期性调整 compaction 组的份额backlog 增长 → 提份额追进度backlog 被快速清零 → 降份额把快速峰值 空档拉平为稳定高原减少对前台查询的干扰。实现上backlog 的跟踪与份额更新分别落在 compaction/compaction_backlog_manager.hh、compaction/compaction_manager.cc 与顶层的 backlog_controller.hhdatabase在 replica/database.cc 中创建 flush 控制器make_flush_controller说明同一套backlog 驱动份额的思路也被用于 memtable 刷盘路径。用户级隔离、多租户与 RPC 路径Per-user 性能隔离与多租户官方文档明确了两个边界Per user 性能隔离文档中该节标记为 TODO尚未形成完整设计多租户Multi-tenancy当前版本不支持同一服务器内不同租户之间相互隔离的性能保证若未来支持将在此文档补充。也就是说当前的隔离是组件级statement 对 compaction、对 streaming 等而非租户级的不同租户的请求共享 statement 组的份额。跨 RPC 调用保持隔离verb 到调度组的映射ScyllaDB 节点间通信大量依赖基于 verb 的 RPC每个 RPC 调用对应一个 verbverb 关联一个 C 处理函数并绑定一个固定的调度组。远端节点收到该 verb 后在与之关联的调度组上下文中执行。这样隔离语义不会在节点边界处丢失例如 replica 发出的MUTATIONverb在接收方同样跑在 statement 组的上下文里而STREAM_BLOB、REPAIR_*系列 verb 则跑在 maintenance/streaming 组的上下文里。verb 到连接池进而到执行上下文的映射由 message/messaging_service.cc 中的do_get_rpc_client_idx()静态确定从源码可以看到当前划分idx 0拓扑无关连接组gossip 系列GOSSIP_DIGEST_SYN/ACK/ACK2、GOSSIP_SHUTDOWN等、GET_SCHEMA_VERSION、Raft 系列RAFT_APPEND_ENTRIES、RAFT_VOTE_REQUEST等、JOIN_NODE_*、DIRECT_FD_PING等稀有且廉价的 verb。注释特别强调此组禁止放入数据路径上的热 verb且 gossip verb 永远留在组内需要低延迟tcp_nodelayidx 1streaming、repair 系列 verbSTREAM_BLOB、REPAIR_*、HINT_MUTATION、NODE_OPS_CMD、tablet 流式与克隆等idx 2数据路径 verb——MUTATION、READ_DATA、READ_DIGEST、TRUNCATE、Paxos 轻量事务系列PAXOS_PREPARE/ACCEPT/LEARN/PRUNE、FORWARD_CQL_EXECUTE等idx 3MUTATION_DONE/MUTATION_FAILED回执idx 4MAPREDUCE_REQUESTrepair 的 map-reduce 阶段。编译期断言SCYLLA_ASSERT(tab[i] PER_TENANT_CONNECTION_COUNT PER_SHARD_CONNECTION_COUNT)message/messaging_service.cc保证新增 verb 必须显式归组防止新 verb 落入错误的连接/调度上下文。statement 组的 tenants 机制有一类 RPC verb——statement 组——可以从多个调度组的上下文中发出。为支持这一点statement RPC verb 引入了 tenants 概念租户清单在 main.cc 配置从源码可见$system对应 default 组、$maintenance对应 streaming 组等每个 tenant 有自己的调度组与唯一标识并拥有独立的 RPC 连接建立连接时tenant 标识会告知远端节点这条连接上的 statement verb 应该在哪个调度组中执行发送侧在自己的调度组上下文内选择对应 tenant 的连接发出请求接收侧按连接绑定的 tenant 还原执行上下文。这套机制让隔离在 coordinator → replica 的 RPC 边界上得以保持由不同调度组发起的语句转发即使走同一批 verb也会在接收节点落入各自的调度组与连接避免低优先级的转发请求挤占高优先级的队列同时GET_SCHEMA_VERSION单独归入 idx 0就是为了避免与读写 verb 同连接产生死锁见 message/messaging_service.cc 的注释。设计权衡与已知限制组数量与最坏延迟官方文档指出调度组越多最坏情况延迟越高轮转调度下每个组的唤醒间隔被拉长。缓解方向是嵌套组结构supergroup让低优先级组先在组内竞争——当前源码中的maintenance_supergroup与usersupergroup 正是这一思路的落地main.cc。隔离粒度是组件级而非租户级per-user 隔离与多租户性能保证尚未实现当前所有前台请求共享 statement 组份额。份额是全局初始值表中数字是启动时的默认值运行期会被控制器按 backlog 等指标调整因此观察到的实际份额分配会与表格不同。小结ScyllaDB 的性能隔离体系可以概括为三层静态划分在 main.cc 创建一组全局调度组及 I/O 带宽上限覆盖 statement、memtable、compaction、streaming/maintenance、gossip、commitlog、backup 等所有工作类别并通过 replica/database.hh 的database_config注入各服务动态调节控制器如 compaction controller依据各组件 backlog 周期性修改份额在追得上进度与不打扰前台查询之间寻找平衡点跨节点保持RPC verb 静态绑定连接池与执行调度组statement verb 通过 tenant 机制在多调度组场景下仍能保持上下文一致。这套机制使 ScyllaDB 能够在共享 shard 的架构下为协调、副本执行与各类后台任务之间提供可预测、可调度的资源边界。【免费下载链接】scylladbNoSQL data store using the Seastar framework, compatible with Apache Cassandra and Amazon DynamoDB项目地址: https://gitcode.com/GitHub_Trending/sc/scylladb创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表