news 2026/9/14 19:22:53

JuiceFS S3 网关(Gateway)实战指南:架构原理、部署配置与高级功能详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JuiceFS S3 网关(Gateway)实战指南:架构原理、部署配置与高级功能详解

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_USERMINIO_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.log

S3 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:9000http://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 IDMINIO_ROOT_USER相同,Secret Access KeyMINIO_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-controlcontent-dispositioncontent-type这几个系统元数据(见s3UserControlledSystemMetasetObjMeta,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 文件系统,需要注意以下几点:

  1. 所有实例启动时需要使用相同的用户,其 UID 和 GID 相同;
  2. 节点之间 IAM 刷新时间可以不同,但要保证 IAM 刷新时间不要太短,以免对 JuiceFS 造成过大压力;
  3. 每个实例的监听地址和端口可以自由设置,如果在同一台机器上启动多个实例,需要确保端口不冲突。

以守护进程的形式运行

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 update

Helm 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
  1. 启动 S3 网关并创建名为foobar的用户;

  2. 配置 AWS CLI:

    [foobar] region = us-east-1 aws_access_key_id = foobar aws_secret_access_key = foo12345
  3. 使用 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 group

S3 网关内置了以下 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:Put
  • s3:ObjectCreated:CompleteMultipartUpload
  • s3:ObjectAccessed:Head
  • s3:ObjectCreated:Post
  • s3:ObjectRemoved:Delete
  • s3:ObjectCreated:Copy
  • s3:ObjectAccessed:Get

支持的全局事件有:

  • s3:BucketCreated
  • s3: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 事件目标支持两种格式:namespaceaccess

  • 使用namespace格式时,S3 网关将存储桶里的对象同步成 Redis hash 中的条目:每个条目对应存储桶里的一个对象,key 设为"存储桶名称/对象名称",value 是该网关对象的 JSON 格式事件数据。对象更新或删除时,hash 中对应条目也会相应更新或删除。
  • 使用access格式时,网关使用RPUSH将事件添加到 list 中:每个元素是一个 JSON 格式的 list,包含两个元素——时间戳字符串,以及含有该存储桶操作事件数据的 JSON 对象。此格式下 list 中的元素不会更新或删除。

配置与验证步骤:

  1. 配置 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")。

  2. 启用 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"
  3. 验证 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 通知目标支持namespaceaccess两种格式:

  • namespace格式下,S3 网关将存储桶里的对象同步成数据库表中的行,每行有两列:key_name(存储桶名加对象名)和value(JSON 格式事件数据);对象更新或删除时,表中相应行也会更新或删除。
  • access格式下,网关将事件添加到表中,行有两列:event_time(事件发生时间)和event_data(JSON 格式事件数据);此格式下不会有行被删除或修改。

配置步骤(以namespace为例):

  1. 确保 MySQL 版本满足最低要求:JuiceFS S3 网关要求 MySQL 5.7.8 及以上,因为使用了该版本引入的 JSON 数据类型。

  2. 配置 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的信息。

  3. 启用 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"
  4. 验证 MySQL:上传一张 JPEG 图片到images存储桶,然后在 MySQL 终端列出minio_images表的所有记录,即可看到刚插入的记录。

使用 PostgreSQL 发布事件

整体方法与使用 MySQL 相同,不再赘述。需要注意的是,该功能要求 PostgreSQL 9.5 及以上版本:S3 网关使用了 PostgreSQL 9.5 引入的INSERT ON CONFLICT(即 UPSERT)特性,以及 9.4 引入的jsonb数据类型。

使用 Webhook 发布事件

Webhook 采用"推"的方式获取数据,而不是一直去拉取。

  1. 配置 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 必须是启动且可访问的。

  2. 启用 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 是否启用了多桶支持。

  3. 采用 Thumbnailer 进行验证:Thumbnailer 是一个使用 MinIOlistenBucketNotificationAPI 的缩略图生成器示例项目,JuiceFS 用它监听 S3 网关通知——文件上传到网关后,Thumbnailer 监听到该通知、生成缩略图并上传回网关。安装并启动 Thumbnailer:

    git clone https://github.com/minio/thumbnailer/ npm install

    打开其config/webhook.json配置文件添加 MinIO server 配置,然后启动:

    NODE_ENV=webhook node thumbnail-webhook.js

    Thumbnailer 运行在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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 19:22:27

Flutter+鸿蒙开发社区团购记账应用实践

1. 项目背景与核心价值社区团购作为近几年兴起的零售模式&#xff0c;已经渗透到全国各个居民小区。作为一名长期参与社区团购运营的开发者&#xff0c;我深刻理解团长们面临的实际痛点&#xff1a;手工记账效率低下、利润计算容易出错、订单状态管理混乱。这正是我们选择用Flu…

作者头像 李华