Ceph T版速率限制如何实现控制?
摘要:前言 ceph T版本支持了比较完善的服务端流控。支持以下速率限制: 读取操作 (max-read-ops):控制 GET 请求频率 写入操作 (max-write-ops):限制 PUT 请求速率 读取带宽 (max-read-bytes
前言
ceph T版本支持了比较完善的服务端流控。支持以下速率限制:
读取操作 (max-read-ops):控制 GET 请求频率
写入操作 (max-write-ops):限制 PUT 请求速率
读取带宽 (max-read-bytes):限制数据流出 (egress)
写入带宽 (max-write-bytes):控制数据流入 (ingress)
这些限制在可配置的时间窗口内运行(由 rgw_ratelimit_interval 选项控制),传统上默认为 60 秒。系统使用令牌桶算法来跟踪资源消耗,当超过限制时,RGW 返回 HTTP 503 响应以节流客户端。
速率限制可以应用于多个范围:
用户范围:限制适用于特定用户在所有桶中的操作
桶范围:限制适用于特定桶中的操作
全局范围:限制适用于整个集群中所有用户和桶的操作
匿名范围:针对未通过身份验证的请求的限制
Ceph 对象网关的速率限制功能并不是一个完整的 QoS 系统。关键点包括:
基于 RGW 实例的执行:限制是在每个 RGW 实例上执行的,而不是集群范围。
如果有 2 个 RGW 且期望限制为 10 ops/min,则应将每个 RGW 配置为 5 ops/min。
如果客户端请求负载在端点之间分布不均,所需的限制可能需要设得比预期更低。
限制交集:必须同时满足用户级和桶级限制。如果超过其中任何一个限制,请求都将被拒绝。
无流量整形:被节流的请求会被立即拒绝 (503),而不是排队等待。
无请求中途节流:带宽是在请求完成后计算的,而不是在进行过程中。超过限制的用户会进入“debt”状态(最大为限制的 2 倍),并在接下来的时间间隔偿还“debt”之前被阻止发起新请求。
之前的局限性在于LIST 操作(使用 GET/HEAD HTTP 方法)被计入 max-read-ops 限制下的读取操作,这使得无法将 LIST 操作与常规的 GET 操作分开控制。
在6个月前,进行了进一步优化,支持了list/delete操作的频控。这是十分重要的功能。因为对于对象存储(可以说任何实现的对象存储),都有一个共性问题:list对象操作造成的性能瓶颈。有不少故障现场都是单桶对象数目过大,业务频繁list对象造成的压力导致的。而delete对象一般实现为将头部分直接删除,而尾部分的大头交给gc来处理,也有一些场景下用户在短时间内大量删除,加上大量list对象操作,可能还后台配有lifecycle,也有可能导致索引操作超时,甚至osd down掉。
因此实际上需要在服务端实现对list/delete的频控功能,来避免整个集群被打垮。
主要MR
ratelimit框架:https://github.com/ceph/ceph/commit/71ffbaee08c0a1d31e3f6676ebdf2a2c22cc8950
list操作限流:https://github.com/ceph/ceph/commit/dae572d50080609c77d7131cfc99b1fb3f16d31b
RGW Ratelimit 机制深度分析
一、实现原理——基于令牌桶的固定精度限速算法
1.1 核心数据结构
整个限速机制由三层类构成:
ActiveRateLimiter (双缓冲管理)
├── RateLimiter[0] (活跃实例)
│ └── unordered_map<string, RateLimiterEntry> // 200 万预分配 hash 表
│ ├── "uuser1" → RateLimiterEntry { read, write, list, del 计数器 }
│ ├── "bbucket-marker-xxx" → RateLimiterEntry { ... }
│ └── ...
└── RateLimiter[1] (备用实例)
1.2 令牌桶算法(Token Bucket)
RateLimiterEntry 实现了一个带固定精度的令牌桶。以读操作为例:
96:147:src/rgw/rgw_ratelimit.h
关键设计——固定精度放大因子 fixed_point_rgw_ratelimit = 1000:
问题:用户配置每分钟 1 次操作,1 秒后请求到来。
正常计算:tokens += 1/60 = 0(整数截断),令牌永远攒不起来。
解决:所有计数器放大 1000 倍存储。
tokens += 1000/60 = 16,积累到 1000 后才等于 1 个真实令牌。
