尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Ceph RGW速率限制实战:多租户对象存储的限流配置与运维

发布时间:2026/9/9 23:24:29

资讯中心
01
ARTICLE

Ceph RGW速率限制实战:多租户对象存储的限流配置与运维

Ceph RGW速率限制实战:多租户对象存储的限流配置与运维
做存储运维这些年凡是跑过Ceph对象存储的人迟早都会遇到同一个问题某个业务方疯狂往RGW里面灌数据或者批量拉取把OSD的队列直接拉满整个集群延迟飙升隔壁业务跟着遭殃。你去找业务方沟通对方一脸无辜说我们也没干什么啊——这种场景我见得太多了。Ceph RGW的速率限制就是为了解决这种吵闹邻居问题设计的它允许你按用户或者按bucket精确限制每秒请求数和读写带宽从根本上避免单个租户把集群资源吃干抹净。这篇文章我会从设计思路、版本要求、配置方法、参数计算到常见问题排查完整走一遍我实际把RGW限流落地到生产环境的过程。如果你正在维护多租户共享的Ceph集群或者准备给对象存储网关加上一层资源隔离控制这篇文章可以直接拿来当作操作手册参考。1. 为什么需要RGW速率限制场景与核心设计思路1.1 多租户场景下的资源争抢问题先还原一个我遇到过的真实场景。当时集群上有三个业务部门共享一套Ceph RGW平时相安无事。结果某个部门上线了一个数据迁移任务用几十个并发进程往bucket里写小文件每个文件只有几十KB。这几个进程瞬间把RGW的CPU打满同时大量小文件的写放大效应让OSD的IOPS火箭式上升最终导致整个集群的操作延迟从几毫秒恶化到几百毫秒另外两个部门的线上业务直接告警。集群层面你有不少手段可以缓解比如OSD的backfill限速、mclock调度、客户端IOPS限制等但那些都是针对块存储RBD或者底层OSD的。对于RGW对象网关来说客户端通过HTTP协议访问你没法直接控制它发起的请求数量所以必须在网关层做请求的入口控制——这就是RGW速率限制的核心价值。RGW速率限制的另一个好处是可以在用户维度和bucket维度两个层级上分别设置阈值。比如你可以限制A租户的所有bucket总带宽不能超过200MB/s也可以针对某个特定业务bucket限制每秒最多100个写请求。这种灵活的控制粒度让运维人员不用在集群层面一刀切业务之间互相隔离的同时又能充分利用硬件资源。1.2 两种限制维度请求速率与带宽的逻辑RGW的速率限制从功能上分两条线一个是ops限制每秒请求数一个是bytes限制每秒字节数。这两个维度解决的是不同的问题。ops限制管的是请求密度。假设一个bucket里全是几KB的小对象即使带宽总量不高每秒成千上万的请求也会把RGW的前端线程池和OSD的IOPS打满。限制每秒请求数能有效防止这类高频小IO请求把网关CPU拖垮。bytes限制管的是吞吐带宽。如果业务方做的是大文件传输比如单个对象几十GB每秒请求数可能只有几个但瞬间吞吐量能把你千兆网卡直接跑满。这时候限制每秒字节数才是最有效的。实际配置中这两个维度通常要同时设置形成一个二维约束。简单来说ops限制防止请求风暴bytes限制防止带宽挤占两者配合才能覆盖绝大多数场景。1.3 三种限制粒度与优先级规则RGW速率限制支持三个级别的配置全局所有请求、用户某个UID、bucket某个存储桶另外还有一个匿名请求anon的控制选项。它们的优先级从高到低是bucket限制 用户限制 全局限制。也就是说如果某个bucket设置了自身的限制则以bucket的配置为准如果bucket没设置但所属用户设置了就用用户的配置用户也没设置才轮到全局配置。这个设计很合理。全局配置相当于一个兜底基线保证整个网关不会出现完全失控的情况用户配置用于租户级别的资源配额bucket配置则是对某些核心业务或者异常业务做精确管控。需要注意的是默认情况下这些开关是关闭的你需要显式启用。2. 动手前必须确认的版本与环境2.1 版本要求Quincy之前的版本怎么办RGW速率限制功能在Ceph社区中酝酿了挺长时间真正变得可用是从Quincy17.x开始。到了Reef18.x功能基本稳定配置项和命令接口也比较完整。如果你的集群还在Pacific16.2.x或者更老的版本直接翻配置手册是找不到这些参数和radosgw-admin子命令的。如果你跑的是老版本历史上常见的替代方案是在RGW前面挂一层Nginx或HAProxy做请求限流或者写Lua脚本在RGW的请求处理流程里拦截。这两种方案我都试过Nginx限流的问题在于它只能限制到IP或URL级别做不到按S3用户和bucket维度精细控制而Lua脚本的查询和计数逻辑如果写得不好在高并发下还会变成RGW的额外瓶颈。所以如果确实有强需求我的建议是优先考虑升级到Reef LTS版本使用官方原生的限流能力。确认版本的方法很简单ceph --version ceph versions第二条命令会列出集群中所有节点的ceph版本号确保mon、mgr、osd、rgw各组件版本一致特别是所有RGW节点都要在支持限流功能的版本上。2.2 多RGW实例的部署拓扑确认这里有个非常容易踩的坑RGW的速率限制是单实例级别生效的不是整个集群全局共享一个计数器。换句话说如果你部署了3个RGW实例每个实例都会独立维护自己的令牌桶和计数器。你要限制某个bucket总带宽100MB/s实际操作中三个RGW各放行100MB/s整体最多可能跑到300MB/s。因此你需要先梳理清楚自己的架构。如果前面有负载均衡器最简单的方式是确认所有RGW实例的限流配置完全一致让总限流上限大约等于单实例限制 × 实例数。如果你希望全局严格限制到某一个阈值那就得靠负载均衡层来做汇总限流或者在客户端侧控制并发度。这也是很多初次接触RGW限流的人最容易产生误解的地方。2.3 别和RBD QoS、池容量配额搞混在Ceph生态里限流相关的概念有几个容易混淆。RGW速率限制管的是对象网关的HTTP请求RBD块存储有自己的一套QoS参数IOPS和带宽限制两者的配置入口和机制完全不同不要指望给RBD设置的参数能影响RGW。另外热词里提到的限制池容量对应的是Ceph的pool quota存储池配额它限制的是一个pool里面可以写入的对象数量或总字节数超过后写入会报错跟请求速率限制完全是两码事。池容量配额是总量控制速率限制是速度控制两者通常配合使用池配额防止存储空间被塞满速率限制防止资源被瞬间打爆。3. 核心配置方法与参数设计3.1 通过ceph.conf配置文件的静态方式最基础也最直观的配置方式是在ceph.conf的RGW实例配置段中添加参数。下面是一个我在Reef集群上验证过的配置示例限制每个bucket默认的读写请求数和带宽[client.rgw.rgw1] rgw_ratelimit_type ratelimit rgw_ratelimit_enabled true rgw_ratelimit_user_enabled true rgw_ratelimit_bucket_enabled true rgw_ratelimit_anon_enabled false rgw_ratelimit_bucket_max_read_ops 500 rgw_ratelimit_bucket_max_write_ops 200 rgw_ratelimit_bucket_max_read_bytes 104857600 rgw_ratelimit_bucket_max_write_bytes 52428800逐项说明一下这些参数的含义rgw_ratelimit_type限流模式可选ratelimit速率限制或concurrent并发连接数限制。默认是ratelimit实际上线中用这个就够了。rgw_ratelimit_enabled总开关。这个不打开下面所有配置都不会生效。rgw_ratelimit_user_enabled是否启用用户级别的限流。rgw_ratelimit_bucket_enabled是否启用bucket级别的限流。rgw_ratelimit_anon_enabled是否限制匿名请求。如果集群允许匿名访问建议开启否则匿名请求会绕过所有限制。rgw_ratelimit_bucket_max_read_ops每个bucket每秒最大读请求数。rgw_ratelimit_bucket_max_write_ops每个bucket每秒最大写请求数。rgw_ratelimit_bucket_max_read_bytes每个bucket每秒最大读字节数单位是字节。rgw_ratelimit_bucket_max_write_bytes每个bucket每秒最大写字节数。前面配置里的104857600字节就是100MB/s52428800字节就是50MB/s。修改完配置后需要重启RGW服务才能生效。如果你用的是cephadm部署的集群命令通常是ceph orch restart rgw.realm.zone如果是手工部署的systemd方式则是systemctl restart ceph-radosgwrgw.$(hostname)注意重启RGW会导致当前实例的客户端连接短暂中断建议放在业务低峰期操作。3.2 通过radosgw-admin命令的动态配置方式静态配置虽然可靠但每次调整都要改文件、重启服务比较繁琐。在Reef版本中radosgw-admin提供了一组动态管理限流配置的子命令可以在线调整、无需重启。设置bucket级别的限制radosgw-admin ratelimit set --ratelimit-scopebucket --bucketmybucket --max-read-ops200 --max-write-ops100 --max-read-bytes52428800 --max-write-bytes26214400查看目前生效的配置radosgw-admin ratelimit get --ratelimit-scopebucket --bucketmybucket清除这条限制radosgw-admin ratelimit clear --ratelimit-scopebucket --bucketmybucket用户级别的操作把--ratelimit-scope换成user加--uid参数即可。不同小版本的命令参数可能有细微差别拿不准的时候先执行radosgw-admin ratelimit set --help确认一下再操作。这里必须强调一个关键细节通过radosgw-admin设置的限流配置只保存在RGW进程的内存中不会写入ceph.conf也不做持久化存储。一旦RGW实例重启这些动态配置就会全部丢失。你在生产环境使用动态配置时一定要把操作命令记录成脚本或者在Ceph的配置管理系统中同步一份否则下次节点重启后限流规则就悄悄消失了这个问题我后面还会详细讲。3.3 参数计算如何确定合理的QPS和带宽阈值配置限流最核心的技术活其实是阈值设多少。设得太大会失去保护意义设得太小又会影响业务正常使用。这里我提供一个简单的估算方法。第一步确定业务可接受的单bucket带宽上限。假设你希望单个bucket最多占用100MB/s的带宽那么max_read_bytes 100 * 1024 * 1024 104857600 B/s第二步估算平均对象大小反推ops限制。假设这个bucket中业务对象的平均大小是2MB那么如果你限制带宽100MB/s理论上每秒只需要处理50个请求即max_read_ops 104857600 / (2 * 1024 * 1024) 50 ops/s但实际业务中对象大小不可能均匀分布。如果存在大量小于64KB的小对象你按平均大小算出的ops限制就挡不住小对象请求的攻击性。更稳妥的做法是先明确业务里最小对象大小大概是多少用最小对象大小来计算ops上限的参考值。比如最小对象64KB100MB/s带宽对应的QPS上限是1600但保守起见实际设置的ops限制可以远低于这个值比如200~300防止请求风暴。最终ops和bytes两个限制会形成一个互相制约的双维度约束。第三步留足余量。我给生产环境配置的经验值是建议的阈值是业务正常峰值流量的1.2~1.5倍。例如业务正常峰值是70MB/s那么限流阈值设置在85~105MB/s之间比较合理。设置得太接近峰值业务一旦出现正常的瞬时波动就会被卡住产生大量请求延迟设置得太宽则保护效果不足。3.4 令牌桶机制与突发流量说明官方RGW速率限制的实现基于令牌桶算法这是RGW限流能够平滑处理突发流量的关键。你可以把令牌桶想象成一个收费站令牌以固定的速率产生每隔一段时间就往桶里放一张票请求要进入高速口必须先拿一张票如果桶里的票被拿光了后面的请求只能排队等下一批票发放。之所以说它能应对突发流量是因为桶本身有个容量。如果业务长时间空闲桶里会积攒不少令牌当一次突发请求到来时只要桶里还有存量令牌这波请求就能直接通过不会瞬间被限流卡死。但一旦令牌消耗速度超过补充速度限流就开始生效请求会被延迟排队处理。这种削峰填谷的效果比直接拒绝请求对业务友好得多。用一句话总结令牌桶允许短时间冲高但不允许长时间超速。4. 实操全过程记录与验证4.1 环境信息与配置操作步骤下面记录一次完整的实操过程。我的测试环境是三节点Ceph Reef 18.2.4集群RGW采用cephadm部署两个RGW实例。我需要给一个名叫>读带宽阈值80MB/s - 80 * 1024 * 1024 83886080 B/s 读ops阈值120 ops/s 写带宽阈值40MB/s - 40 * 1024 * 1024 41943040 B/s 写ops阈值60 ops/s由于我使用的是Reef版本优先用动态命令配置方便验证效果后再固化到配置文件。执行radosgw-admin ratelimit set --ratelimit-scopebucket --bucketdata-bucket --max-read-ops120 --max-write-ops60 --max-read-bytes83886080 --max-write-bytes41943040随后用get命令确认配置已经生效radosgw-admin ratelimit get --ratelimit-scopebucket --bucketdata-bucket输出会显示当前bucket限流的详细配置确认各项参数与预期一致。4.2 针对多个RGW实例的同步处理前面强调过动态配置只作用于当前连接的RGW实例。我的环境里有两个RGW实例如果只对其中一个执行上面的命令另一个实例仍不会限流。此时需要确认请求实际被分发到哪个实例或者干脆两个实例都执行一次同样的命令。更稳妥的做法是先通过动态命令快速验证效果验证完毕后把同样的配置写入ceph.conf确保后续实例重启时配置依然存在。配置文件方式下radosgw-admin ratelimit get查到的动态配置与配置文件中的静态配置是两套并存的东西实际生效时取限制更严格的那一方所以动态配置和静态配置不要设置成明显冲突的大小否则排查问题时容易晕。4.3 从客户端实际验证限流效果配置完成后需要从客户端验证一下限流是否真的在工作。我用了一个承载在>aws --endpoint-url http://rgw.example.com s3 cp s3://data-bucket/testfile-2gb.bin /dev/null客户端会实时显示传输进度和平均速度。实测下来在没有其他瓶颈的情况下下载速度稳定在75~82MB/s附近和设置的80MB/s基本吻合。这说明限流已经生效。为了验证ops限制我改用小对象并发读取来测试。用Python脚本发起100个并发的小对象GET请求观察请求的吞吐量。令牌桶的排队效果体现得非常明显刚开始的一瞬间请求可以全部涌入随后请求的响应时间明显上升整体请求速率被压到120 ops/s左右。这里有一点需要留意如果你的客户端到RGW之间链路本身带宽就小于限流阈值比如你的客户端只有50MB/s的带宽那你是测不出80MB/s限制效果的。验证限流效果之前先确认链路带宽高于限流阈值。4.4 日常监控与限流状态确认上线限流之后运维人员需要知道限流是否在频繁触发。一个简单的办法是看RGW的访问日志被延迟处理的请求其响应时间会明显高于平时如果限流配置异常比如把某个业务卡的太死客户端侧的体现是上传或下载速度异常稳定地贴着阈值上限走同时请求延迟显著增加。官方perf信息中有与ratelimit相关的计数器可以进一步观察限流具体拦截了多少请求。如果使用cephadm部署可以通过以下命令查看RGW的perf信息cephadm shell -- ceph --admin-daemon /var/run/ceph/ceph-client.rgw.*.asok perf dump输出中会包含与限流相关的指标。日常巡检时关注这些计数器的增量如果某个bucket的限流请求数量长期居高不下就要考虑是不是阈值设置太低影响了正常业务。5. 常见问题与排查技巧实录5.1 配置不生效请求完全不受限制这个问题出现频率最高。按我的排查经验原因基本跑不出下面三个第一配置项的名字拼错了。RGW的限流参数名称比较长比如rgw_ratelimit_bucket_max_read_ops少写一个字母、大小写不一致ceph都不会报错只是静默地不识别这条配置。排查时用ceph config dump | grep ratelimit确认配置是否真的被ceph加载了。第二rgw_ratelimit_enabled总开关没打开。很多人只设置了rgw_ratelimit_bucket_enabled和一堆阈值参数偏偏漏掉了最上面那个总开关结果所有配置都不生效。第三多实例环境只配置了其中一个RGW。我遇到过一个案例三个RGW节点只改了第一台另外两台没有同步配置结果负载均衡把流量轮询到未配置的实例上时限流形同虚设。所以一定要确认所有RGW实例的配置保持一致。5.2 动态配置重启后全部丢失前面已经提过用radosgw-admin ratelimit set设置的规则是内存态进程重启就没了。这在生产环境中确实埋过雷某次RGW节点例行重启后原本限制得好好的bucket突然不受控了直到业务方反馈带宽异常才排查出来。解决方案是把动态配置固化为脚本并纳入节点初始化流程。比如写一个简单的bash脚本在RGW服务启动后自动执行所有的ratelimit set命令或者更直接一点把阈值参数写入ceph.conf的静态配置。两种方式结合最稳妥静态配置管基本盘动态命令用于临时调整。5.3 RGW限流与前端负载均衡限流的冲突有些架构里RGW前面挂了Nginx或者HAProxy做TLS终止和负载均衡同时这些负载均衡器自身也带有请求限流模块。如果你在Nginx和RGW两层都配置了限流实际生效的限制取两者中较小的一方这会导致业务方反映带宽比设定值低很多。排查这种问题的方法很简单先在负载均衡层临时放行看看RGW自身的限流是否正常再恢复负载均衡限制对比两层的实际阈值差异。两层同时配置限流并非不可但需要明确各自的定位负载均衡层管IP维度的粗粒度限流RGW层管用户和bucket维度的精细限流。5.4 限制粒度太大或太小不同业务方都来投诉限流粒度太粗比如只限制到用户级别那就无法防止用户内部某个业务bucket占用全部配额粒度太细比如每个bucket都设置独立的限制维护成本会成倍增加特别是bucket数量超过几千个时限流模块需要维护大量的计数器会带来额外的内存和CPU开销。我的建议是先设置用户级别的兜底限制保证一个租户最多占用多少资源然后对有特殊要求的核心bucket单独设置bucket级别限制。对于创建后掉线的临时bucket、测试bucket直接沿用用户或者全局配置即可不需要逐一设置。5.5 常见问题速查表现象可能原因排查方法解决办法限流不生效总开关未开启或配置名拼错ceph config dump | grep ratelimit修正配置并重启RGW重启后限流消失动态配置为内存态radosgw-admin ratelimit get确认固化为启动脚本或写入ceph.conf实测带宽明显低于阈值前端LB也有限流在LB层临时放行对比明确两层限流定位统一规划阈值部分请求绕过了限流多RGW实例配置不一致逐台检查配置和实例版本同步所有RGW实例配置bucket过多后网关性能下降限流计数器开销过大查看RGW进程内存与CPU只对核心bucket设置独立限制5.6 限流在对象存储故障恢复场景下的表现最后补充一个和热词ceph osd恢复相关的点。当集群某个OSD掉盘进入数据恢复流程时底层恢复流量本身会占用大量磁盘IO。这时候如果RGW的业务流量还是全速运行两者叠加可能会让OSD长时间处于高负载状态拖慢恢复进度。在这种场景下RGW限流能起到业务避让的作用。你可以在OSD恢复期间临时给核心业务bucket降低读写带宽限制让出磁盘IO给恢复进程恢复完成后再把限流阈值调回正常值。这比直接停业务要优雅得多也是限流功能的另一个实用价值。动态命令在这里就非常方便不需要改配置重启一条命令即可完成限流阈值的临时调整。根据我个人的实际操作体会RGW速率限制这个功能配置本身其实不太复杂真正的难点在于两个方面一是设计合理的阈值需要了解业务的正常峰值、对象大小分布、集群的实际吞吐能力二是建立一套有效的运维习惯多实例配置同步、动态配置固化、限流触发监控。只要这两点做到位RGW限流就能成为多租户集群中非常可靠的一道资源隔离保障。最后再分享一个小技巧正式上线限流之前先用一个测试bucket压上真实业务流量跑一天观察业务在限流边缘的表现再决定最终阈值这样比单纯凭估算参数上线稳妥得多。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。