JuiceFS S3 网关(Gateway)实战指南:架构原理、部署配置与高级功能详解
【免费下载链接】juicefsJuiceFS is a distributed POSIX file system built on top of Redis and S3.项目地址: https://gitcode.com/GitHub_Trending/ju/juicefs
JuiceFS S3 网关是 JuiceFS 提供的多种访问方式之一,它把 JuiceFS 文件系统以 Amazon S3 兼容协议对外暴露,让任何支持 S3 API 的 SDK、命令行工具和应用程序都可以直接读写 JuiceFS 上存储的文件。本文以 docs/zh_cn/guide/gateway.md 为主线,结合仓库内 cmd/gateway.go、pkg/gateway/gateway.go 与 deploy/juicefs-s3-gateway.yaml 等源码,完整讲解 S3 网关的架构原理、快速启动、客户端接入、常用与高级功能(IAM 访问控制、桶事件通知等),帮助你把它用起来、用好、用对。
架构与原理
JuiceFS 中的文件以对象形式分块存储到底层对象存储中,元数据则由独立的元数据引擎(如 Redis)管理。JuiceFS 提供了 FUSE POSIX、WebDAV、S3 网关、CSI 驱动等多种访问方式,其中 S3 网关是较为常用的一种:
JuiceFS S3 网关功能是通过 MinIO S3 Gateway 实现的:利用 MinIO 的object接口将 JuiceFS 文件系统作为 MinIO 服务器的后端存储,从而提供接近原生 MinIO 的使用体验,同时继承 MinIO 的许多高级功能。在这种架构中,JuiceFS 就相当于 MinIO 实例的一块本地磁盘,原理与minio server /data1命令类似。
从源码看,这一设计在 pkg/gateway/gateway.go 中实现为jfsObjects结构体,它实现了 MinIO 的ObjectLayer接口(NewJFSGateway返回minio.ObjectLayer),网关启动时由 cmd/gateway.go 将 JuiceFS 文件系统实例jfs包装为jfsGateway并交给 MinIO 服务进程处理 S3 请求。
JuiceFS S3 网关的常见使用场景有:
- 为 JuiceFS 开放 S3 接口:应用可以通过 S3 SDK 访问 JuiceFS 上存储的文件;
- 使用 S3 客户端:使用 s3cmd、AWS CLI、MinIO 客户端(mc)方便地访问和操作 JuiceFS 上存储的文件;
- 管理 JuiceFS 中的文件:S3 网关提供了基于网页的文件管理器,可以在浏览器中直接管理 JuiceFS 中的文件;
- 集群复制:在跨集群复制数据的场景下,作为集群的统一数据出口,避免跨区访问元数据以提升数据传输性能,详见「使用 S3 网关进行跨区域数据同步」。
快速开始
启动 S3 网关需要一个已经创建完毕的 JuiceFS 文件系统,如果尚不存在,请参考独立使用文档创建。下方假定元数据引擎 URL 为redis://localhost:6379/1。
设置管理员凭证
由于网关基于 MinIO 开发,因此需要先设置MINIO_ROOT_USER和MINIO_ROOT_PASSWORD两个环境变量,它们会成为访问 S3 API 时认证身份用的 Access Key 和 Secret Key,是拥有最高权限的管理员凭证:
export MINIO_ROOT_USER=admin export MINIO_ROOT_PASSWORD=12345678 # Windows 用户请改用 set 命令设置环境变量 set MINIO_ROOT_USER=admin注意:MINIO_ROOT_USER的长度至少 3 个字符,MINIO_ROOT_PASSWORD的长度至少 8 个字符。这一限制在源码 cmd/gateway.go 中有明确校验——未正确设置时会直接报错退出,例如MINIO_ROOT_USER should be specified as an environment variable with at least 3 characters,注意排查。
启动 S3 网关
# 第一个参数是元数据引擎的 URL,第二个是 S3 网关监听的地址和端口 juicefs gateway redis://localhost:6379/1 localhost:9000 # 从 v1.2 开始,S3 网关支持后台启动,追加 --background 或 -d 参数均可 # 后台运行场景下,使用 --log 指定日志输出文件路径 juicefs gateway redis://localhost:6379 localhost:9000 -d --log=/var/log/juicefs-s3-gateway.logS3 Gateway 默认没有启用多桶支持,可以添加--multi-buckets选项开启。还可以添加其他选项优化 S3 网关,比如将默认的本地缓存设置为 20 GiB(--cache-size单位为 MiB,20480 MiB ≈ 20 GiB):
juicefs gateway --cache-size 20480 redis://localhost:6379/1 localhost:9000在这个例子中,假设 JuiceFS 文件系统使用的是本地 Redis 数据库。当 S3 网关启用后,在当前主机上可以使用http://localhost:9000访问 S3 网关的管理界面(一个基于网页的文件管理器):
如果你希望通过局域网或互联网上的其他主机访问 S3 网关,则需要调整监听地址,例如:
juicefs gateway redis://localhost:6379/1 0.0.0.0:9000这样一来,S3 网关将默认接受所有网络请求。不同位置的 S3 客户端可以使用不同的地址访问:
- S3 网关所在主机中的第三方客户端可使用
http://127.0.0.1:9000或http://localhost:9000访问; - 与 S3 网关所在主机处于同一局域网的第三方客户端可使用
http://192.168.1.8:9000访问(假设网关主机内网 IP 为 192.168.1.8); - 通过互联网访问可使用
http://110.220.110.220:9000(假设网关主机公网 IP 为 110.220.110.220)。
访问 S3 网关
各类支持 S3 API 的客户端、桌面程序、Web 程序都可以访问 JuiceFS S3 网关。使用时请注意 S3 网关监听的地址和端口。以下示例均假设使用第三方客户端访问本地主机上运行的 S3 网关,实际场景请根据情况调整访问地址。
使用 AWS CLI
下载并安装 AWS CLI 后执行配置:
$ aws configure AWS Access Key ID [None]: admin AWS Secret Access Key [None]: 12345678 Default region name [None]: Default output format [None]:程序会以交互方式引导你完成新配置的添加,其中Access Key ID与MINIO_ROOT_USER相同,Secret Access Key与MINIO_ROOT_PASSWORD相同,区域名称和输出格式留空即可。
之后即可使用aws s3命令访问 JuiceFS 存储,例如:
# 列出所有 bucket $ aws --endpoint-url http://localhost:9000 s3 ls # 列出 bucket 中的对象 $ aws --endpoint-url http://localhost:9000 s3 ls s3://<bucket>使用 MinIO 客户端(mc)
为避免兼容性问题,推荐使用RELEASE.2021-04-22T17-40-00Z版本的 mc。下载安装完成后添加一个新的 alias:
mc alias set juicefs http://localhost:9000 admin 12345678然后可以通过 mc 客户端在本地磁盘、JuiceFS 存储以及其他云存储之间自由进行文件和文件夹的复制、移动、增删等管理操作:
$ mc ls juicefs/jfs [2021-10-20 11:59:00 CST] 130KiB avatar-2191932_1920.png [2021-10-20 11:59:00 CST] 4.9KiB box-1297327.svg [2021-10-20 11:59:00 CST] 21KiB cloud-4273197.svg [2021-10-20 11:59:05 CST] 17KiB hero.svg [2021-10-20 11:59:06 CST] 1.7MiB hugo-rocha-qFpnvZ_j9HU-unsplash.jpg常用功能
多桶支持
默认情况下,juicefs gateway只允许一个 bucket,bucket 名字为文件系统名字。如果需要多个桶,可以在启动时添加--multi-buckets开启多桶支持,该参数会把 JuiceFS 文件系统顶级目录下的每个子目录都导出为一个 bucket;创建 bucket 的行为在文件系统上的反映就是顶级目录下创建了一个同名子目录:
juicefs gateway redis://localhost:6379/1 localhost:9000 --multi-buckets这一行为在源码 pkg/gateway/gateway.go 的MakeBucketWithLocation中实现:开启MultiBucket时创建 bucket 会直接调用n.fs.Mkdir在文件系统顶级目录下建立同名目录;isValidBucketName(pkg/gateway/gateway.go)则保证在未开启多桶时,只有文件系统名对应的 bucket 合法。
保留 ETag
默认 S3 网关不会保存和返回对象的 ETag 信息,可以通过--keep-etag开启:
juicefs gateway myjfs localhost:9000 --keep-etag开启后,通过网关上传到 JuiceFS 的文件就可以用 S3 API 的head-object获取 ETag 了:
aws s3api --endpoint=http://localhost:9000 head-object --bucket myjfs --key test123/test.etag { "AcceptRanges": "bytes", "LastModified": "Wed, 23 Apr 2025 00:17:16 GMT", "ContentLength": 7, "ETag": "\"d2fde576f44a6601b73201234b491904\"", "ContentType": "application/octet-stream", "Metadata": {} }这个 ETag 通过 MD5 算法生成,并以 key 为s3-etag的扩展属性(xattr)写入文件——对应源码中的常量const s3Etag = "s3-etag"(pkg/gateway/gateway.go)。如果你使用--enable-xattr挂载 JuiceFS,也可以用getfattr获取这个 ETag:
getfattr -n s3-etag test.etag # file: test.etag s3-etag="d2fde576f44a6601b73201234b491904"开启对象标签
默认不支持对象标签,可以通过--object-tag开启。标签数据同样以 xattr(key 为s3-tags,对应源码 pkg/gateway/gateway.go)保存在文件中,并在上传、分片合并等环节被读写(见 pkg/gateway/gateway.go 的PutObjectTags/GetObjectTags/DeleteObjectTags实现)。
开启对象元数据(v1.3 起)
默认不支持对象元数据,可以通过--object-meta开启。源码中对象元数据以s3-meta为 xattr key(pkg/gateway/gateway.go)保存,存储时仅保留x-amz-meta-前缀的用户自定义元数据以及cache-control、content-disposition、content-type这几个系统元数据(见s3UserControlledSystemMeta与setObjMeta,pkg/gateway/gateway.go)。
启用虚拟主机风格请求
默认情况下,S3 网关支持格式为http://mydomain.com/bucket/object的路径类型请求。MINIO_DOMAIN环境变量用于启用虚拟主机类型请求:如果请求的Host头信息匹配(.+).mydomain.com,则匹配的模式$1被用作 bucket,路径被用作 object。例如:
export MINIO_DOMAIN=mydomain.com命令行也提供了等价的--domain参数,启动时如果设置了该参数,cmd/gateway.go 会把它写入MINIO_DOMAIN环境变量再启动 MinIO 服务。
调整 IAM 刷新时间
默认 IAM 缓存的刷新时间为 5 分钟(对应 cmd/gateway.go 中--refresh-iam-interval的默认值"5m"),可以通过--refresh-iam-interval调整。该参数的值是一个带单位的时间字符串,例如"300ms"、"-1.5h"或"2h45m",有效时间单位是"ns"、"us"(或"µs")、"ms"、"s"、"m"、"h"。设置后会被写入MINIO_REFRESH_IAM_INTERVAL环境变量(cmd/gateway.go)。例如设置 1 分钟刷新:
juicefs gateway xxxx xxxx --refresh-iam-interval 1m多 Gateway 实例
JuiceFS 的分布式特性使得可以在多个节点上同时启动多个 S3 网关实例,以提高可用性和性能。这种情况下,每个 S3 网关实例独立处理请求,但它们都访问同一个 JuiceFS 文件系统,需要注意以下几点:
- 所有实例启动时需要使用相同的用户,其 UID 和 GID 相同;
- 节点之间 IAM 刷新时间可以不同,但要保证 IAM 刷新时间不要太短,以免对 JuiceFS 造成过大压力;
- 每个实例的监听地址和端口可以自由设置,如果在同一台机器上启动多个实例,需要确保端口不冲突。
以守护进程的形式运行
S3 网关可以通过 systemd 以 Linux 守护进程的形式在后台运行:
cat > /lib/systemd/system/juicefs-gateway.service<<EOF [Unit] Description=Juicefs S3 Gateway Requires=network.target After=multi-user.target StartLimitIntervalSec=0 [Service] Type=simple User=root Environment="MINIO_ROOT_USER=admin" Environment="MINIO_ROOT_PASSWORD=12345678" ExecStart=/usr/local/bin/juicefs gateway redis://localhost:6379 localhost:9000 Restart=on-failure RestartSec=60 [Install] WantedBy=multi-user.target EOF设置进程开机自启动:
systemctl daemon-reload systemctl enable juicefs-gateway --now systemctl status juicefs-gateway检阅进程日志:
journalctl -xefu juicefs-gateway.service在 Kubernetes 上部署 S3 网关
安装需要 Helm 3.1.0 及以上版本:
helm repo add juicefs https://juicedata.github.io/charts/ helm repo updateHelm chart 同时支持 JuiceFS 社区版和企业版,通过填写 values 中不同的字段来区分使用的版本。编辑values-mycluster.yaml:
secret: name: "<name>" metaurl: "<meta-url>" storage: "<storage-type>" accessKey: "<access-key>" secretKey: "<secret-key>" bucket: "<bucket>"建议把values-mycluster.yaml纳入 Git(或其他的源码管理方式)管理,这样即使 values 配置不断变化,也能对其进行追溯和回滚。填写完毕保存后即可部署:
# 不论是初次安装,还是后续调整配置重新上线,都可以使用下方命令 helm upgrade --install -f values-mycluster.yaml s3-gateway juicefs/juicefs-s3-gateway部署完毕后,按照输出文本的提示获取 Kubernetes Service 的地址并测试访问:
$ kubectl -n kube-system get svc -l app.kubernetes.io/name=juicefs-s3-gateway NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE juicefs-s3-gateway ClusterIP 10.101.108.42 <none> 9000/TCP 142m部署完成后会启动一个名为juicefs-s3-gateway的 Deployment,查看其 Pod:
$ kubectl -n kube-system get po -l app.kubernetes.io/name=juicefs-s3-gateway NAME READY STATUS RESTARTS AGE juicefs-s3-gateway-5c69d574cc-t92b6 1/1 Running 0 136m仓库中还提供了一个不依赖 Helm 的 Kubernetes 部署清单 deploy/juicefs-s3-gateway.yaml,它使用initContainers先执行juicefs format初始化文件系统,再以juicefs gateway ${METAURL} ${NODE_IP}:9000启动网关,同时暴露 9000 端口(S3 服务)与 9567 端口(监控指标),凭证通过 Secret 注入,可作为参考模板。
高级功能
JuiceFS S3 网关的核心功能是对外提供 S3 接口,目前对 S3 协议的支持已经比较完善。在 v1.2 版本中,又添加了身份和访问控制(IAM)和桶事件通知的支持。这些高级功能要求 mc 客户端的版本为RELEASE.2021-04-22T17-40-00Z。如果你不知道有哪些功能或某个功能如何使用,可以在子命令后加-h查看帮助说明。
身份和访问控制(IAM)
普通用户
在 v1.2 版本之前,juicefs gateway只在启动时创建一个超级用户,该超级用户只属于这个进程——即使多个 gateway 背后是同一个文件系统,其用户也是进程间隔离的(可以为每个 gateway 进程设置不同的超级用户,相互独立、互不影响)。
在 v1.2 版本之后,juicefs gateway启动时仍需要设置超级用户(仍为进程隔离),但允许使用mc admin user add添加新的用户,新添加的用户将是同文件系统共享的。可以使用mc admin user进行管理,支持添加、关闭、启用、删除用户,也支持查看所有用户、展示用户信息以及查看用户的策略:
$ mc admin user -h NAME: mc admin user - manage users USAGE: mc admin user COMMAND [COMMAND FLAGS | -h] [ARGUMENTS...] COMMANDS: add add a new user disable disable user enable enable user remove remove user list list all users info display info of a user policy export user policies in JSON format svcacct manage service accounts例如,添加用户:
# 添加新用户 $ mc admin user add myjfs user1 admin123 # 查看当前用户 $ mc admin user list myjfs enabled user1 # 以 JSON 格式查看用户信息 $ mc admin user list myjfs --json { "status": "success", "accessKey": "user1", "userStatus": "enabled" }服务账户
服务账户(service accounts)的作用是为现有用户创建一个相同权限的副本,让不同的应用可以使用独立的访问密钥。服务账户的权限继承自父用户,可以通过mc admin user svcacct命令管理:
$ mc admin user svcacct -h NAME: mc admin user svcacct - manage service accounts USAGE: mc admin user svcacct COMMAND [COMMAND FLAGS | -h] [ARGUMENTS...] COMMANDS: add add a new service account ls List services accounts rm Remove a service account info Get a service account info set edit an existing service account enable Enable a service account disable Disable a services account服务账户会从主账户继承权限并保持与主账户权限一致,且服务账户不可以直接附加权限策略。比如,为名为user1的用户创建一个名为svcacct1的服务账户:
mc admin user svcacct add myjfs user1 --access-key svcacct1 --secret-key 123456abc如果user1是只读权限,那么svcacct1也是只读权限;若想让svcacct1拥有其他权限,需要调整user1的权限。
AssumeRole 安全令牌服务
S3 网关安全令牌服务(STS)可让客户端请求临时凭证访问网关资源。临时凭证的工作原理与默认管理员凭证几乎相同,但有两个不同点:
- 临时凭证是短期的:可以配置为持续几分钟到几小时不等,过期后 S3 网关不再识别它们,不允许使用它们进行任何 API 请求访问;
- 临时凭证不需要与应用程序一起存储:它们动态生成并在请求时提供给应用程序,过期后应用可以请求新的凭证。
AssumeRole需要现有网关用户的授权凭据,返回的临时安全凭证包括访问密钥、秘密密钥和安全令牌;应用于这些临时凭据的策略继承自网关用户凭据。默认有效期为 1 小时,可通过可选参数DurationSeconds指定,取值范围 900(15 分钟)到 604800(7 天)。
API 请求参数
- Version:指示 STS API 版本信息,唯一支持的值是
'2011-06-15'(出于兼容性原因借用自 AWS STS API 文档)。类型为 String,必填。 - AUTHPARAMS:指示 STS API 授权信息,支持 AWS Signature V4 签名授权。
- DurationSeconds:持续时间(秒),取值范围 900(15 分钟)至 604800(7 天),超出则操作失败,默认 3600 秒。类型为 Integer,可选。
- Policy:JSON 格式的 IAM 内联会话策略,可选。生成会话的权限是预设策略名称和此处设置的策略集合的交集,不能用该策略授予比被假定预设策略名称允许的更多权限。最小长度为 1,最大长度为 2048。
POST 请求示例
http://minio:9000/?Action=AssumeRole&DurationSeconds=3600&Version=2011-06-15&Policy={"Version":"2012-10-17","Statement":[{"Sid":"Stmt1","Effect":"Allow","Action":"s3:*","Resource":"arn:aws:s3:::*"}]}&AUTHPARAMS响应示例
<?xml version="1.0" encoding="UTF-8"?> <AssumeRoleResponse xmlns="https://sts.amazonaws.com/doc/2011-06-15/"> <AssumeRoleResult> <AssumedRoleUser> <Arn/> <AssumeRoleId/> </AssumedRoleUser> <Credentials> <AccessKeyId>Y4RJU1RNFGK48LGO9I2S</AccessKeyId> <SecretAccessKey>sYLRKS1Z7hSjluf6gEbb9066hnx315wHTiACPAjg</SecretAccessKey> <Expiration>2019-08-08T20:26:12Z</Expiration> <SessionToken>eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9...</SessionToken> </Credentials> </AssumeRoleResult> <ResponseMetadata> <RequestId>c6104cbe-af31-11e0-8154-cbc7ccf896c7</RequestId> </ResponseMetadata> </AssumeRoleResponse>使用 AWS CLI 请求 AssumeRole
启动 S3 网关并创建名为
foobar的用户;配置 AWS CLI:
[foobar] region = us-east-1 aws_access_key_id = foobar aws_secret_access_key = foo12345使用 AWS CLI 请求 AssumeRole API。注意:
--role-arn和--role-session-name对 S3 网关没有意义,可以设置为满足命令行要求的任意值:$ aws --profile foobar --endpoint-url http://localhost:9000 sts assume-role --policy '{"Version":"2012-10-17","Statement":[{"Sid":"Stmt1","Effect":"Allow","Action":"s3:*","Resource":"arn:aws:s3:::*"}]}' --role-arn arn:xxx:xxx:xxx:xxxx --role-session-name anything { "AssumedRoleUser": { "Arn": "" }, "Credentials": { "SecretAccessKey": "xbnWUoNKgFxi+uv3RI9UgqP3tULQMdI+Hj+4psd4", "SessionToken": "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9...", "Expiration": "2019-02-20T19:56:59-08:00", "AccessKeyId": "K9DTIMUVZXEXJL3ATUOY" } }
Go 应用程序可参考 MinIO 官方的 assume-role 示例程序实现。
注意:环境变量设置的超级用户无法使用 AssumeRole API,只有通过mc admin user add添加的用户才能使用。
权限管理
默认新创建的用户没有任何权限,需要使用mc admin policy赋权后才可使用。该命令支持权限的增删改查,以及为用户添加、删除、更新权限:
$ mc admin policy -h NAME: mc admin policy - manage policies defined in the MinIO server USAGE: mc admin policy COMMAND [COMMAND FLAGS | -h] [ARGUMENTS...] COMMANDS: add add new policy remove remove policy list list all policies info show info on a policy set set IAM policy on a user or group unset unset an IAM policy for a user or group update Attach new IAM policy to a user or groupS3 网关内置了以下 4 种常用策略:
- readonly:只读用户;
- readwrite:可读写用户;
- writeonly:只写用户;
- consoleAdmin:可读可写可管理,可管理指可以调用管理 API,比如创建用户等。
例如,设置某个用户为只读:
# 设置 user1 为只读 $ mc admin policy set myjfs readonly user=user1 # 查看用户策略 $ mc admin user list myjfs enabled user1 readonly如需自定义策略,可以使用mc admin policy add:
$ mc admin policy add -h NAME: mc admin policy add - add new policy USAGE: mc admin policy add TARGET POLICYNAME POLICYFILE POLICYNAME: Name of the canned policy on MinIO server. POLICYFILE: Name of the policy file associated with the policy name. EXAMPLES: 1. Add a new canned policy 'writeonly'. $ mc admin policy add myjfs writeonly /tmp/writeonly.json策略文件必须是 JSON 格式、具有 IAM 兼容语法,且不超过 2048 个字符。该语法可以实现更精细化的访问控制;如果不熟悉,可以先用下面的命令查看内置策略并在此基础上修改:
$ mc admin policy info myjfs readonly { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetBucketLocation", "s3:GetObject" ], "Resource": [ "arn:aws:s3:::*" ] } ] }用户组管理
JuiceFS S3 网关支持创建用户组(类似于 Linux 用户组的概念),使用mc admin group管理。可以把一个或多个用户设置为一个组,然后为组统一赋权,用法与用户管理类似:
$ mc admin group -h NAME: mc admin group - manage groups USAGE: mc admin group COMMAND [COMMAND FLAGS | -h] [ARGUMENTS...] COMMANDS: add add users to a new or existing group remove remove group or members from a group info display group info list display list of groups enable enable a group disable disable a group匿名访问管理
如果希望特定的对象或桶可以被任何人访问,可以使用mc policy命令配置匿名访问策略:
Name: mc policy - manage anonymous access to buckets and objects USAGE: mc policy [FLAGS] set PERMISSION TARGET mc policy [FLAGS] set-json FILE TARGET mc policy [FLAGS] get TARGET mc policy [FLAGS] get-json TARGET mc policy [FLAGS] list TARGET PERMISSION: Allowed policies are: [none, download, upload, public]. FILE: A valid S3 policy JSON filepath.S3 网关默认内置 4 种匿名权限:
- none:不允许匿名访问(一般用来清除已有权限);
- download:允许任何人读取;
- upload:允许任何人写入;
- public:允许任何人读写。
例如,设置一个允许匿名下载的对象:
# 设置 testbucket1/afile 为匿名访问 mc policy set download useradmin/testbucket1/afile # 查看具体权限 mc policy get-json useradmin/testbucket1/afile $ mc policy --recursive links useradmin/testbucket1/ http://127.0.0.1:9001/testbucket1/afile # 直接下载该对象 wget http://127.0.0.1:9001/testbucket1/afile # 清除 afile 的 download 权限 mc policy set none useradmin/testbucket1/afile配置生效时间
JuiceFS S3 网关的所有管理 API 更新操作都会立即生效并持久化到 JuiceFS 文件系统中,接受该 API 请求的客户端也会立即生效。但多机运行时情况有所不同:S3 网关在处理请求鉴权时会直接采用内存缓存信息作为校验基准,避免每次请求都读取配置带来的不可接受的性能问题。
目前缓存刷新策略是每 5 分钟强制更新内存缓存(部分操作也会触发缓存更新),保证多机情况下配置生效最长不超过 5 分钟,可以通过--refresh-iam-interval参数调整。如果希望某个 S3 网关立即生效,可以手动重启它。
生成预签名 URL
JuiceFS S3 网关支持使用mc share命令管理存储桶上对象的预签名 URL,用于下载和上传对象。使用详情可参考 mc 命令的帮助信息。
桶事件通知
桶事件通知功能可以用来监视存储桶中对象上发生的事件,从而触发一些行为。目前支持的对象事件类型有:
s3:ObjectCreated:Puts3:ObjectCreated:CompleteMultipartUploads3:ObjectAccessed:Heads3:ObjectCreated:Posts3:ObjectRemoved:Deletes3:ObjectCreated:Copys3:ObjectAccessed:Get
支持的全局事件有:
s3:BucketCreateds3:BucketRemoved
可以使用 mc 客户端工具通过 event 子命令设置和监听事件通知。MinIO 发送的用于发布事件的通知消息是 JSON 格式的。JuiceFS S3 网关为减少依赖,裁剪了部分事件目标类型,目前存储桶事件支持发布到以下目标:
- Redis
- MySQL
- PostgreSQL
- WebHooks
$ mc admin config get myjfs | grep notify notify_webhook publish bucket notifications to webhook endpoints notify_mysql publish bucket notifications to MySQL databases notify_postgres publish bucket notifications to Postgres databases notify_redis publish bucket notifications to Redis datastores以下示例假设 JuiceFS 文件系统名为images,启用 S3 Gateway 服务后在 mc 中定义其别名为myjfs。对于 S3 Gateway 而言,JuiceFS 文件系统名images就是一个存储桶名。
使用 Redis 发布事件
Redis 事件目标支持两种格式:namespace和access。
- 使用
namespace格式时,S3 网关将存储桶里的对象同步成 Redis hash 中的条目:每个条目对应存储桶里的一个对象,key 设为"存储桶名称/对象名称",value 是该网关对象的 JSON 格式事件数据。对象更新或删除时,hash 中对应条目也会相应更新或删除。 - 使用
access格式时,网关使用RPUSH将事件添加到 list 中:每个元素是一个 JSON 格式的 list,包含两个元素——时间戳字符串,以及含有该存储桶操作事件数据的 JSON 对象。此格式下 list 中的元素不会更新或删除。
配置与验证步骤:
配置 Redis 到 S3 网关:使用
mc admin config set命令配置 Redis 为事件通知目标:# 命令行参数 # mc admin config set myjfs notify_redis[:name] address="xxx" format="namespace|access" key="xxxx" password="xxxx" queue_dir="" queue_limit="0" # 具体举例 $ mc admin config set myjfs notify_redis:1 address="127.0.0.1:6379/1" format="namespace" key="bucketevents" password="yoursecret" queue_dir="" queue_limit="0"可通过
mc admin config get myjfs notify_redis查看配置项:$ mc admin config get myjfs notify_redis notify_redis enable=off format=namespace address= key= password= queue_dir= queue_limit=0各配置项含义:
notify_redis[:name] 支持设置多个 redis,只需 name 不同即可 address* (address) Redis 服务器的地址。例如:localhost:6379 key* (string) 存储/更新事件的 Redis key,key 会自动创建 format* (namespace*|access) 是 namespace 还是 access,默认是 'namespace' password (string) Redis 服务器的密码 queue_dir (path) 未发送消息的暂存目录,例如 '/home/events' queue_limit (number) 未发送消息的最大限制,默认是 '100000' comment (sentence) 可选的注释说明S3 网关支持持久事件存储:持久存储会在 Redis broker 离线时备份事件,并在其恢复在线时重播事件。事件存储目录通过
queue_dir设置,最大限制通过queue_limit设置。更新配置前可先用mc admin config get获取当前配置;更新后需要手动重启JuiceFS S3 网关使配置生效(mc admin service restart暂不受支持)。重启后网关启动时会输出类似SQS ARNs: arn:minio:sqs::1:redis的信息。可以添加任意多个 Redis 目标,只需为每个实例提供不同的标识符(如上例notify_redis:1中的 "1")。启用 bucket 通知:在名为
images的存储桶上开启事件通知,需要使用上一步输出的 ARN 信息:mc event add myjfs/images arn:minio:sqs::1:redis --suffix .jpg mc event list myjfs/images arn:minio:sqs::1:redis s3:ObjectCreated:*,s3:ObjectRemoved:*,s3:ObjectAccessed:* Filter: suffix=".jpg"验证 Redis:启动
redis-cli并运行 monitor 命令查看网关在 Redis 上执行的操作:redis-cli -a yoursecret 127.0.0.1:6379> monitor OK上传一个名为
myphoto.jpg的文件到images存储桶:mc cp myphoto.jpg myjfs/images回到 monitor 终端即可看到
namespace格式下的 HSET 操作:127.0.0.1:6379> monitor OK 1712562516.867831 [1 192.168.65.1:59280] "hset" "bucketevents" "images/myphoto.jpg" "{\"Records\":[...]}"如果使用
access格式,则看到的是 RPUSH 操作:127.0.0.1:6379> monitor OK 1712562751.922469 [1 192.168.65.1:61102] "rpush" "aceesseventskey" "[{\"Event\":[...]}]"
使用 MySQL 发布事件
MySQL 通知目标支持namespace和access两种格式:
namespace格式下,S3 网关将存储桶里的对象同步成数据库表中的行,每行有两列:key_name(存储桶名加对象名)和value(JSON 格式事件数据);对象更新或删除时,表中相应行也会更新或删除。access格式下,网关将事件添加到表中,行有两列:event_time(事件发生时间)和event_data(JSON 格式事件数据);此格式下不会有行被删除或修改。
配置步骤(以namespace为例):
确保 MySQL 版本满足最低要求:JuiceFS S3 网关要求 MySQL 5.7.8 及以上,因为使用了该版本引入的 JSON 数据类型。
配置 MySQL 到 S3 网关:
mc admin config set myjfs notify_mysql:myinstance table="minio_images" dsn_string="root:123456@tcp(172.17.0.1:3306)/miniodb"查看配置项:
$ mc admin config get myjfs notify_mysql format=namespace dsn_string= table= queue_dir= queue_limit=0 max_open_connections=2各配置项含义:
notify_mysql[:name] 发布存储桶通知到 MySQL 数据库;需要多个 endpoint 时可为每个配置添加用户指定的 name(如 "notify_mysql:myinstance") ARGS: dsn_string* (string) MySQL 数据源名称连接字符串,格式为 "<user>:<password>@tcp(<host>:<port>)/<database>"(必填) table* (string) 存储/更新事件的数据库表名,表会自动创建 format* (namespace*|access) 'namespace' 或 'access',默认是 'namespace' queue_dir (path) 未发送消息的暂存目录,例如 '/home/events' queue_limit (number) 未发送消息的最大限制,默认是 '100000' comment (sentence) 可选的注释说明同样支持持久事件存储。更新配置并重启网关后,启动时会输出类似
SQS ARNs: arn:minio:sqs::myinstance:mysql的信息。启用 bucket 通知:
# 使用 MySQL ARN 在 "images" 存储桶上添加通知配置,--suffix 参数用于过滤事件 mc event add myjfs/images arn:minio:sqs::myinstance:mysql --suffix .jpg # 打印 "images" 存储桶上的通知配置 mc event list myjfs/images arn:minio:sqs::myinstance:mysql s3:ObjectCreated:*,s3:ObjectRemoved:*,s3:ObjectAccessed:* Filter: suffix=".jpg"验证 MySQL:上传一张 JPEG 图片到
images存储桶,然后在 MySQL 终端列出minio_images表的所有记录,即可看到刚插入的记录。
使用 PostgreSQL 发布事件
整体方法与使用 MySQL 相同,不再赘述。需要注意的是,该功能要求 PostgreSQL 9.5 及以上版本:S3 网关使用了 PostgreSQL 9.5 引入的INSERT ON CONFLICT(即 UPSERT)特性,以及 9.4 引入的jsonb数据类型。
使用 Webhook 发布事件
Webhook 采用"推"的方式获取数据,而不是一直去拉取。
配置 webhook 到 S3 网关:
notify_webhook[:name] 发布存储桶通知到 webhook endpoints ARGS: endpoint* (url) webhook server endpoint,例如 http://localhost:8080/minio/events auth_token (string) opaque token 或者 JWT authorization token queue_dir (path) 未发送消息的暂存目录,例如 '/home/events' queue_limit (number) 未发送消息的最大限制,默认是 '100000' client_cert (string) Webhook 的 mTLS 身份验证的客户端证书 client_key (string) Webhook 的 mTLS 身份验证的客户端证书密钥 comment (sentence) 可选的注释说明用
mc admin config set更新配置,endpoint 是监听 webhook 通知的服务地址:mc admin config set myjfs notify_webhook:1 queue_limit="0" endpoint="http://localhost:3000" queue_dir=""保存配置并重启服务让配置生效,重启时 endpoint 必须是启动且可访问的。
启用 bucket 通知:此处 ARN 值为
arn:minio:sqs::1:webhook:mc mb myjfs/images-thumbnail mc event add myjfs/images arn:minio:sqs::1:webhook --event put --suffix .jpg如果 mc 报告无法创建 Bucket,请检查 S3 Gateway 是否启用了多桶支持。
采用 Thumbnailer 进行验证:Thumbnailer 是一个使用 MinIO
listenBucketNotificationAPI 的缩略图生成器示例项目,JuiceFS 用它监听 S3 网关通知——文件上传到网关后,Thumbnailer 监听到该通知、生成缩略图并上传回网关。安装并启动 Thumbnailer:git clone https://github.com/minio/thumbnailer/ npm install打开其
config/webhook.json配置文件添加 MinIO server 配置,然后启动:NODE_ENV=webhook node thumbnail-webhook.jsThumbnailer 运行在
http://localhost:3000/。按前述步骤配置好 webhook 通知后上传一张图片:mc cp ~/images.jpg myjfs/images .../images.jpg: 8.31 KB / 8.31 KB ┃▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓┃ 100.00% 59.42 KB/s 0s稍等片刻后用
mc ls检查存储桶内容,即可看到生成的缩略图:mc ls myjfs/images-thumbnail [2017-02-08 11:39:40 IST] 992B images-thumbnail.jpg
小结
JuiceFS S3 网关基于 MinIO S3 Gateway 构建,把 JuiceFS 文件系统以标准 S3 协议暴露给任意 S3 客户端,兼顾了 POSIX 语义与对象存储生态的兼容性。本文覆盖了从架构原理、快速启动、AWS CLI / mc 客户端接入,到多桶、ETag、对象标签与元数据、虚拟主机风格请求、IAM 刷新时间、多实例与 systemd / Kubernetes 部署等常用功能,并深入讲解了 v1.2 起提供的 IAM 访问控制(用户、服务账户、AssumeRole STS、策略、用户组、匿名访问)与桶事件通知(Redis / MySQL / PostgreSQL / Webhook)等高级能力。相关底层实现可在 cmd/gateway.go 与 pkg/gateway/gateway.go 中进一步研读。
【免费下载链接】juicefsJuiceFS is a distributed POSIX file system built on top of Redis and S3.项目地址: https://gitcode.com/GitHub_Trending/ju/juicefs
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考