- 存储
- 分布式文件系统
- 对象存储
- 后端
- 高可用
【免费下载链接】ceph
Ceph is a distributed object, block, and file storage platform
导读
Ceph Object Gateway(RGW)对外提供与 Amazon S3 API 兼容的 RESTful 接口,任何遵循 S3 协议的客户端(包括 Ruby 生态中的aws-sdk与aws-s3两个 gem)都可以直接对接。本文以 Ceph 官方文档 doc/radosgw/s3/ruby.rst 为骨架,系统讲解用 Ruby 完成连接配置、桶的增删查、对象的上传下载与 ACL 管理、签名/未签名 URL 生成等完整操作,并结合仓库中的 RGW 源码(如 src/rgw/rgw_acl_s3.cc)与配套文档(如 doc/radosgw/s3/authentication.rst、doc/radosgw/s3/commons.rst)补充底层原理与实操细节。读完本文,你将能够用两种主流 Ruby SDK 快速接入 Ceph RGW,并理解其认证、ACL 与路径访问模式的实现机制。
适用前提:本文示例面向 Ceph RGW 的 S3 兼容接口,文中出现的
objects.dreamhost.com为官方文档沿用的示例主机名,实际使用时请替换为你的 RGW 网关地址(如rgw.example.com),并替换为自己的access_key_id/secret_access_key。两种 SDK 的适用版本分别为aws-sdk gem ~>2与aws-s3 gem(老一代 gem)。
一、Ceph RGW 的 S3 兼容接口与 Ruby 生态选型
Ceph 通过 RGW 组件暴露一套与 Amazon S3 API 基本数据访问模型兼容的 RESTful API,其功能支持清单(List Buckets、Create/Delete Bucket、Put/Get/Delete Object、Object ACL、Multipart Uploads、Object/Bucket Tagging、Bucket Policy、S3-select 等)详见 doc/radosgw/s3.rst 中的特性支持表。Ruby 开发者对接 RGW 主要有两条技术路线:
| 路线 | gem | 适用场景 |
|---|---|---|
| 现代 SDK | aws-sdk(~> 2) | 官方文档 doc/radosgw/s3/ruby.rst 前半部分示例,面向Aws::S3::Client接口,推荐新项目使用 |
| 经典 gem | aws-s3 | 官方文档后半部分示例,面向AWS::S3命名空间,接口更贴近早期 S3 REST 语义 |
两种 SDK 均通过 HTTP 调用 RGW 的 S3 端点,认证依赖 AWS 签名(Signature v2/v4),因此只要是合法的 S3 凭据即可工作,无需任何 Ceph 专用客户端库。
二、现代 SDK(aws-sdk gem ~>2):连接配置与客户端初始化
2.1 全局连接设置
官方推荐使用Aws.config.update进行全局配置,一次性声明端点、凭据与访问模式:
Aws.config.update( endpoint: 'https://objects.dreamhost.com.', access_key_id: 'my-access-key', secret_access_key: 'my-secret-key', force_path_style: true, region: 'us-east-1' )参数含义与注意事项:
endpoint:RGW 网关地址。必须显式指定,否则 SDK 会默认指向 AWS 官方 S3 服务。access_key_id/secret_access_key:S3 凭据,可由radosgw-admin user create创建用户时生成(详见下文"准备凭据"小节)。force_path_style: true:强制使用path-style访问模式(GET /mybucket)。这几乎总是对接 RGW 的正确选择——因为 RGW 默认并未为每个桶分配子域名,virtual-hosted-style(GET /,Host: mybucket.cname.domain.com)需要额外配置rgw_dns_name或 zonegroup 的hostnames。两种访问模式的差异与配置方法参见 doc/radosgw/s3/commons.rst。region:RGW 对 region 值不做强制校验,填写任意值(如us-east-1)即可满足签名计算要求。
2.2 实例化客户端
s3_client = Aws::S3::Client.new之后所有桶与对象操作均通过s3_client完成。
2.3 准备凭据(对接 RGW 前的账号准备)
在真实环境中,你需要先在 RGW 中创建 S3 用户并获取访问密钥,这属于 RGW 管理面操作,可参考 doc/radosgw/adminops.rst 中的用户管理章节,典型命令形如:
radosgw-admin user create --uid=ruby-user --display-name="Ruby User" --gen-access-key --gen-secret-key创建成功后命令会返回access_key与secret_key,将其填入上面的Aws.config.update即可。RGW 对请求的认证基于 AWS 签名(v2/v4),SDK 会自动完成签名计算;只有手工构造原始 HTTP 请求时才需要自行计算签名,详见 doc/radosgw/s3/authentication.rst。
三、桶操作:列出、创建、清空与删除
3.1 列出自己拥有的桶(List Owned Buckets)
s3_client.list_buckets.buckets.each do |bucket| puts "#{bucket.name}\t#{bucket.creation_date}" end输出形如:
mahbuckat1 2011-04-21T18:05:39.000Z mahbuckat2 2011-04-21T18:05:48.000Z mahbuckat3 2011-04-21T18:07:18.000Z该操作对应 S3 的GET /服务级请求(Service Ops),在 RGW 侧由s3:ListAllMyBuckets权限控制。
3.2 创建桶(Create Bucket)
s3_client.create_bucket(bucket: 'my-new-bucket')若希望桶默认为私有,可显式传入acl选项:
s3_client.create_bucket(bucket: 'my-new-bucket', acl: 'private')acl选项(canned ACL)支持以下取值:
private:仅所有者可读写(默认)public-read:公开可读public-read-write:公开读写(慎用)authenticated-read:仅已认证用户可读
这四个 canned ACL 值与 RGW 服务端实现一一对应,见 src/rgw/rgw_acl_s3.cc 中的解析逻辑(private/public-read/public-read-write/authenticated-read)。需要注意的是,官方文档 doc/radosgw/s3.rst 明确指出 RGW 对桶的 canned ACL 集合与 AWS 存在差异("Different set of canned ACLs")。
3.3 列出桶内容(List a Bucket's Content)
s3_client.get_objects(bucket: 'my-new-bucket').contents.each do |object| puts "#{object.key}\t#{object.size}\t#{object.last-modified}" end输出形如:
myphoto1.jpg 251262 2011-08-08T21:35:48.000Z myphoto2.jpg 262518 2011-08-08T21:38:01.000Z注意:官方文档此处写的是
get_objects,实际现代aws-sdk(v2+)中列出对象的标准方法是list_objects或list_objects_v2,返回结构均为contents数组,字段key、size、last_modified一致。若你的 SDK 版本提示找不到get_objects,请改用:
s3_client.list_objects(bucket: 'my-new-bucket').contents.each do |object| puts "#{object.key}\t#{object.size}\t#{object.last_modified}" end3.4 删除桶(Delete Bucket)
⚠️ 注意:桶必须为空才能删除成功,否则操作会失败!
s3_client.delete_bucket(bucket: 'my-new-bucket')3.5 非空桶的强制删除
删除非空桶前必须先清空桶,SDK 提供了便捷方法:
Aws::S3::Bucket.new('my-new-bucket', client: s3_client).clear!清空之后即可删除桶:
s3_client.delete_bucket(bucket: 'my-new-bucket')clear!会遍历桶内对象并逐个调用delete_object,等效于先list_objects再循环删除,因此数据量极大时建议评估耗时与请求配额。
四、对象操作:上传、ACL 管理、下载与删除
4.1 创建对象(Put Object)
在桶my-new-bucket中创建hello.txt,内容为字符串"Hello World!":
s3_client.put_object( key: 'hello.txt', body: 'Hello World!', bucket: 'my-new-bucket', content_type: 'text/plain' )content_type显式指定Content-Type元数据;若省略,SDK 会根据body类型推断。上传大文件时可改用put_object的文件流形式,或使用 Multipart Upload(RGW 支持,见 doc/radosgw/s3.rst 功能表)。
4.2 修改对象 ACL
使hello.txt公开可读、secret_plans.txt私有:
s3_client.put_object_acl(bucket: 'my-new-bucket', key: 'hello.txt', acl: 'public-read') s3_client.put_object_acl(bucket: 'my-new-bucket', key: 'private.txt', acl: 'private')RGW 的 ACL 模型包含READ、WRITE、READ_ACP、WRITE_ACP、FULL_CONTROL五种权限,作用于桶与对象时语义不同(例如READ在桶上表示"可列出桶内对象",在对象上表示"可读取该对象"),完整权限对照与 S3 操作到 ACL 权限的映射表见 doc/radosgw/s3/authentication.rst。
4.3 下载对象到本地文件(Get Object)
将对象poetry.pdf下载并保存到本地目录:
s3_client.get_object( bucket: 'my-new-bucket', key: 'poetry.pdf', response_target: '/home/larry/documents/poetry.pdf' )response_target指定本地保存路径,SDK 会以文件流方式落盘,避免将大对象整体读入内存。
4.4 删除对象(Delete Object)
s3_client.delete_object(key: 'goodbye.txt', bucket: 'my-new-bucket')RGW 侧由s3:DeleteObject权限控制,对应WRITE级 ACL 权限。
五、生成对象下载 URL:未签名(公开)与预签名(限时)
对于公开对象(已通过 ACL 设为public-read),可以生成无需签名的直接访问 URL:
puts Aws::S3::Object.new( key: 'hello.txt', bucket_name: 'my-new-bucket', client: s3_client ).public_url对于私有对象(如secret_plans.txt),生成预签名 URL(presigned URL),在有效期内任何人都可通过该 URL 下载,即使对象本身是私有的;有效期过后 URL 立即失效:
puts Aws::S3::Object.new( key: 'secret_plans.txt', bucket_name: 'hermes_ceph_gem', client: s3_client ).presigned_url(:get, expires_in: 60 * 60)expires_in单位为秒,上例为 1 小时(60 * 60)。输出形如:
http://objects.dreamhost.com/my-bucket-name/hello.txt http://objects.dreamhost.com/my-bucket-name/secret_plans.txt?Signature=XXXXXXXXXXXXXXXXXXXXXXXXXXX&Expires=1316027075&AWSAccessKeyId=XXXXXXXXXXXXXXXXXXX预签名 URL 的本质是将签名作为查询参数(Signature、Expires、AWSAccessKeyId)附加到 URL 上,RGW 在收到请求时会校验签名与有效期。这是临时授权下载最常用的手段,适合"限时分享私有文件"场景。
小提示:示例中第二个 URL 的桶名为
hermes_ceph_gem,这是官方文档的历史笔误,实际应为你自己的桶名(如my-new-bucket),请按需替换。
六、经典 gem(aws-s3):老一代 SDK 的对应操作
aws-s3gem 提供与aws-sdk平行的操作集合,接口风格更接近早期 S3 REST 语义,适合维护旧项目。以下逐一给出对应实现。
6.1 建立连接
AWS::S3::Base.establish_connection!( :server => 'objects.dreamhost.com', :use_ssl => true, :access_key_id => 'my-access-key', :secret_access_key => 'my-secret-key' )establish_connection!建立全局连接;use_ssl决定是否走 HTTPS。注意该接口没有force_path_style参数,若 RGW 未配置桶子域名,需要注意主机名与路径的解析方式。
6.2 列出自己拥有的桶
AWS::S3::Service.buckets.each do |bucket| puts "#{bucket.name}\t#{bucket.creation_date}" end输出同上(mahbuckat1 ...)。
6.3 创建桶
AWS::S3::Bucket.create('my-new-bucket')6.4 列出桶内容
new_bucket = AWS::S3::Bucket.find('my-new-bucket') new_bucket.each do |object| puts "#{object.key}\t#{object.about['content-length']}\t#{object.about['last-modified']}" endobject.about返回对象的元数据哈希,包含content-length(字节数)与last-modified。
6.5 删除桶
⚠️ 同样要求桶为空,否则失败!
AWS::S3::Bucket.delete('my-new-bucket')6.6 非空桶强制删除
aws-s3直接支持:force => true,一步完成清空与删除:
AWS::S3::Bucket.delete('my-new-bucket', :force => true)这是与aws-sdk实现(先clear!再delete_bucket)最明显的 API 差异。
6.7 创建对象
AWS::S3::S3Object.store( 'hello.txt', 'Hello World!', 'my-new-bucket', :content_type => 'text/plain' )6.8 修改对象 ACL
通过 Grant 列表改写 ACL:公开hello.txt、私有化secret_plans.txt:
policy = AWS::S3::S3Object.acl('hello.txt', 'my-new-bucket') policy.grants = [ AWS::S3::ACL::Grant.grant(:public_read) ] AWS::S3::S3Object.acl('hello.txt', 'my-new-bucket', policy) policy = AWS::S3::S3Object.acl('secret_plans.txt', 'my-new-bucket') policy.grants = [] AWS::S3::S3Object.acl('secret_plans.txt', 'my-new-bucket', policy)这里先读取对象当前 ACL,再整体替换grants列表(空列表即私有),最后回写。
6.9 下载对象到本地文件
aws-s3以流式分块方式下载并写入文件:
open('/home/larry/documents/poetry.pdf', 'w') do |file| AWS::S3::S3Object.stream('poetry.pdf', 'my-new-bucket') do |chunk| file.write(chunk) end end6.10 删除对象
AWS::S3::S3Object.delete('goodbye.txt', 'my-new-bucket')6.11 生成下载 URL(签名/未签名)
# 未签名(公开对象)URL puts AWS::S3::S3Object.url_for( 'hello.txt', 'my-new-bucket', :authenticated => false ) # 预签名(限时 1 小时)URL puts AWS::S3::S3Object.url_for( 'secret_plans.txt', 'my-new-bucket', :expires_in => 60 * 60 ):authenticated => false生成不带签名的公开 URL;:expires_in生成带签名的限时 URL。输出格式与aws-sdk示例一致。
七、两种 SDK 操作对照一览
| 操作 | aws-sdk(~>2) | aws-s3 |
|---|---|---|
| 连接配置 | Aws.config.update+Aws::S3::Client.new | AWS::S3::Base.establish_connection! |
| 列出桶 | s3_client.list_buckets.buckets | AWS::S3::Service.buckets |
| 创建桶 | s3_client.create_bucket(bucket: ...) | AWS::S3::Bucket.create(...) |
| 列出桶内容 | list_objects(bucket: ...).contents | Bucket.find(...)后迭代 |
| 删除桶(空) | s3_client.delete_bucket(bucket: ...) | AWS::S3::Bucket.delete(...) |
| 强制删除 | Bucket.new(...).clear!后删除 | AWS::S3::Bucket.delete(..., :force => true) |
| 创建对象 | put_object(key:, body:, bucket:, content_type:) | S3Object.store(key, value, bucket, :content_type => ...) |
| 修改 ACL | put_object_acl(bucket:, key:, acl:) | 读写S3Object.acl+policy.grants |
| 下载对象 | get_object(bucket:, key:, response_target:) | S3Object.stream分块写文件 |
| 删除对象 | delete_object(key:, bucket:) | S3Object.delete(key, bucket) |
| 未签名 URL | Object#public_url | url_for(..., :authenticated => false) |
| 预签名 URL | Object#presigned_url(:get, expires_in:) | url_for(..., :expires_in => ...) |
八、背后的实现要点(结合 RGW 源码)
- canned ACL 的服务端解析:
create_bucket与put_object_acl传入的acl字符串在 RGW 服务端由 src/rgw/rgw_acl_s3.cc 解析并映射为具体的 grant 集合,支持private、public-read、public-read-write、authenticated-read四种取值;非法取值会返回参数错误。 - 认证机制:RGW 支持 AWS Signature v4 与 v2 两种签名算法,SDK 自动完成签名;
x-amz-content-sha256头支持实际负载校验值、UNSIGNED-PAYLOAD以及多种流式负载模式,详见 doc/radosgw/s3/authentication.rst。 - 访问模式:
force_path_style: true对应 path-style 请求(GET /mybucket),是 RGW 部署的常见形态;如需 virtual-hosted-style(Host: mybucket.cname.domain.com),需通过rgw_dns_name配置或在 zonegroup 中声明hostnames,参见 doc/radosgw/s3/commons.rst。 - 签名 URL 的校验:预签名 URL 通过查询参数携带签名与过期时间,RGW 校验通过后放行匿名下载,因此时效性与签名完整性由 RGW 统一保障,客户端无需额外处理。
九、常见问题与排错建议
endpoint忘记配置:SDK 会默认连向 AWS 官方 S3,请求将失败或指向错误服务;务必显式设置 RGW 地址。- 桶删除失败:检查桶是否为空。非空桶需先
clear!(或:force => true)。 - 403 AccessDenied:确认
access_key_id/secret_access_key正确,且该用户对目标桶/对象拥有相应 ACL 或桶策略权限;RGW 支持桶策略与 ACL 两种授权模型,官方建议优先使用桶策略,见 doc/radosgw/s3/authentication.rst 末尾说明。 - URL 上出现异常主机名:检查是否启用了 virtual-hosted-style 而 RGW 未配置桶子域名;保持
force_path_style: true通常是更稳妥的选择。 - 对象上传大文件:
put_object直接上传适合中小文件,超大对象建议使用 Multipart Upload API(RGW 支持,见 doc/radosgw/s3.rst 特性表)。
- 存储
- 分布式文件系统
- 对象存储
- 后端
- 高可用
【免费下载链接】ceph
Ceph is a distributed object, block, and file storage platform
相关推荐
使用 C AWS SDK 对接 Ceph RGW S3 网关:从连接建立、桶与对象操作到预签名 URL 的完整实践
使用 C AWS SDK 对接 Ceph RGW S3 网关:从连接建立、桶与对象操作到预签名 URL 的完整实践 本文以 Ceph RADOS Gateway
存储分布式文件系统对象存储后端高可用如何用 start-cluster.sh 为 LibreChat 本地搭建三节点 Redis Cluster 并通过 .env 连接验证
如何用 start cluster.sh 为 LibreChat 本地搭建三节点 Redis Cluster 并通过 .env 连接验证 LibreChat 本
存储分布式文件系统对象存储后端高可用Ceph 对象存储 Java S3 开发实战:基于 AWS Java SDK 2.17 的完整操作指南
Ceph 对象存储 Java S3 开发实战:基于 AWS Java SDK 2.17 的完整操作指南 本指南以 Ceph 对象网关(RADOS Gateway
存储分布式文件系统对象存储后端高可用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考