ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

ES 快照从本地盘搬到 RustFS:三处配置不写对就通不了

ES 快照从本地盘搬到 RustFS:三处配置不写对就通不了 Elasticsearch 8.x 的repository-s3插件是内置的8.0 之前要自己装理论上PUT _snapshot一条命令就能把索引快照打到 S3。但当后端从 AWS 换成自建的 S3 兼容存储时默认配置基本跑不通。不是权限问题而是有三个默认值在 AWS 上成立、在自建端点上不成立的地方region必须手动给值。Elastic 官方文档原话是使用 S3 兼容服务时AWS SDK 不太可能自动确定正确的 region因此必须手动设置。这个值不必是真实存在的 AWS 区域但必须和服务端签名时预期的值一致。path_style_access要看部署方式。默认值是false即由 AWS SDK 自动判断访问风格SDK 对 IP 加端口这类端点的自动判断会走虚拟主机风格然后解析失败。access_key/secret_key属于安全设置不能写进elasticsearch.yml当明文必须进 keystore否则节点启动会报安全警告。下面把完整链路走一遍从建桶到验证快照可恢复。客户端和仓库是两层配置repository-s3用 AWS Java SDK 连接 S3配置分两层客户端层s3.client.CLIENT_NAME.*控制连接方式包括端点、协议、region、认证、超时。大部分放elasticsearch.yml敏感项放 keystore。仓库层PUT _snapshotJSON 里的settings控制这个仓库用哪个桶、哪个客户端、路径前缀、压缩等。一个客户端可以被多个仓库复用。配好一个叫default的客户端指向存储端点之后建十个仓库都引用client: default不用每个仓库重复写端点和密钥。先把桶和最小权限身份建好服务端先准备好基础设施。用 rc 客户端rcaliassetlocalrustfs http://127.0.0.1:9000$RUSTFS_ACCESS_KEY$RUSTFS_SECRET_KEYrc mb localrustfs/es-snapshots rc admin useraddlocalrustfs es-backupChangeMe-Strong-Secretcates-policy.jsonEOF { Version: 2012-10-17, Statement: [ { Effect: Allow, Action: [s3:ListBucket, s3:GetBucketLocation], Resource: [arn:aws:s3:::es-snapshots] }, { Effect: Allow, Action: [s3:GetObject, s3:PutObject, s3:DeleteObject, s3:ListMultipartUploadParts], Resource: [arn:aws:s3:::es-snapshots/*] } ] } EOFrc admin policy create localrustfs es-backup-policy es-policy.json rc admin policy attach localrustfs es-backup-policy es-backups3:ListMultipartUploadParts这条别漏。ES 快照上传大 segment 时会用 multipart upload缺了这条权限快照跑到一半会报AccessDenied。ES 快照对存储的要求很明确扛得住大文件顺序写索引合并后的 segment 动辄几百 MB 到几 GB、支持分片上传、删除操作及时释放空间。RustFS 底层是纠删码架构这类负载下空间效率和重建能力都有保障1.0.0 已于 2026 年 9 月 16 日 GA。客户端设置三处必须显式写在elasticsearch.yml里加这些是非安全设置直接写 ymls3.client.default.endpoint:http://127.0.0.1:9000s3.client.default.region:us-east-1s3.client.default.path_style_access:true注意这里没有写protocol。官方文档已把这个设置标记为废弃8.19 起建议直接把 endpoint 写成带http://或https://前缀的全 URL协议跟着 scheme 走。然后是安全设置密钥必须走 keystorebin/elasticsearch-keystoreadds3.client.default.access_key bin/elasticsearch-keystoreadds3.client.default.secret_key改完之后有两种生效方式重启节点最稳首次配置推荐。不重启的话调一次 reload API 让节点重新读 keystorePOST _nodes/reload_secure_settings官方文档的口径是API 返回后后续的快照操作会使用新值但正在进行中的操作可能仍使用旧值。所以轮换密钥时避开快照窗口。几个容易漏的边界注记时间得先对齐。snapshot 的请求是 AWS 签名算法带x-amz-date签出去的ES 节点系统时间和存储端偏差过大签名校验直接失败页面上看到的是SignatureDoesNotMatch或者RequestTimeTooSkewed跟桶权限没关系。ES 节点和存储主机都挂上时间同步再谈备份# ES 节点和存储节点都要跑timedatectl set-ntptruechronyc sources自签证书要显式信任。存储端点前面套了 TLS 反代比如 Nginx时把 endpoint 改成https://your-rustfs-proxyJVM 默认校验证书链CA 是自己签的话用 keytool 导进 truststore否则握手阶段就失败keytool-import-trustcacerts-noprompt\-aliasrustfs-ca-fileca.crt\-keystore$ES_HOME/config/elasticsearch.keystore这一条是可选的内网走 http 时完全不涉及证书。改完照前面说的方式 reload 或重启才生效文件也要分发到每个节点。region 的值要和服务端一致。自建服务通常不校验具体值但签名过程里 region 参与计算两端不一致会直接SignatureDoesNotMatch。注册仓库立刻验证客户端设置好了注册仓库就一行 APIPUT_snapshot/rustfs-repo{type:s3,settings:{bucket:es-snapshots,client:default,base_path:production/cluster-a,compress:true}}几个字段说明字段说明bucket桶名必须提前建好遵守 S3 命名规则client引用 yml 里配的客户端名默认defaultbase_path桶内路径前缀默认空串桶根目录值不要以/开头或结尾compress压缩元数据文件默认true不影响本已压缩的 segment注册完立刻验证这一步不要跳过POST _snapshot/rustfs-repo/_verify_verify会检查当前节点能不能连上端点、有没有桶的读写权限、能不能在base_path下创建临时文件再删掉。三项任意一项不过后续快照一定会失败。与其等凌晨定时任务报错不如注册时就验一遍。快照放上对象存储之后桶里是海量小对象索引元数据文件通常几 KB 到几十 KB一个中等索引就是几百到几千个键。恢复和_verify背后都是反复调 ListObjectsV2一次 List 只返回 1000 个键扫完一个前缀要翻很多页。所以把 List 的延迟和调用量放进监控比盯快照任务本身更早发现问题List 一慢恢复就会从十几分钟变成卡在一半不动而快照任务本身还显示正常。验证通过后跑一个最小的功能测试// 1. 对一个小索引做快照PUT_snapshot/rustfs-repo/test-snapshot-001{indices:.security-7,include_global_state:false}// 2. 等它完成状态从 IN_PROGRESS 变 SUCCESSGET_snapshot/rustfs-repo/test-snapshot-001// 3. 关闭原索引然后恢复到新索引POST.security-7/_closePOST_snapshot/rustfs-repo/test-snapshot-001/_restore{indices:.security-7,rename_pattern:(.),rename_replacement:restored_$1}恢复出来的restored_.security-7能正常查询说明整条链路ES → AWS SDK → S3 API → 对象落盘 → 读回是通的。让 SLM 接管定时快照ES 7.4 起 SLMSnapshot Lifecycle Management内置不用再靠外部 cron 调_snapshotAPI。配一条策略让它自动按计划拍、自动清过期快照PUT_slm/policy/daily-backup{schedule:0 30 2 * * ?,name:daily-backup-{now/d},repository:rustfs-repo,config:{indices:*,ignore_unavailable:false,include_global_state:true},retention:{expire_after:30d,min_count:5,max_count:50}}SLM 的 retention 清理依赖s3:DeleteObject权限这就是前面策略里一定要加这条的原因。权限缺了的话SLM 只会标记该删实际对象还在桶里占空间。查看执行历史GET _slm/policy/daily-backup GET _slm/history?sort_orderdesc同一仓库在多集群场景还有另一半用法旧集群的快照要迁到新集群读回来时在新集群上注册同一个仓库但设成只读PUT_snapshot/rustfs-repo-migrate{type:s3,settings:{bucket:es-snapshots,client:default,base_path:production/cluster-a,readonly:true}}官方文档对readonly的要求很直接只有持有写权限的集群才能在该仓库创建快照所有其他接入同一仓库的集群都应设readonly: true。这防止两个集群同时往同一个base_path写导致数据冲突。旧集群那边保持可写继续正常拍。等迁移窗口结束把新集群的仓库改成可写、切 SLM 指向新仓库切换就完成了。最后把整套流程收成一份清单按这个顺序做从零到自动快照大概半天存储侧建es-snapshots桶开es-backup身份策略包含s3:ListMultipartUploadParts。每个 ES 节点的elasticsearch.yml写全 URL 形式的endpoint、region、path_style_access。每个节点用elasticsearch-keystore add写入access_key和secret_key重启或调_nodes/reload_secure_settings。PUT _snapshot注册仓库立刻跑_verify不等定时任务来探路。对一个小索引做一次完整的 snapshot 加 restore 往返确认数据可查。配 SLM 策略设好 retention确认删除权限存在。多集群场景用readonly: true隔离写权限避免并发冲突。ES 接 S3 兼容存储这件事本身不难配置参考在 elastic.co 的 S3 repository settings。卡住的地方几乎都是那三个在 AWS 上成立的默认值。把 region、path_style_access、keystore 三件事一次性搞定后面就是常规运维了。RustFS 1.0.0 已于 2026 年 9 月 16 日 GA源码和 issue 在 github.com/rustfs/rustfs部署前固定版本标签、按需调整纠删码参数即可。
返回列表