多写存储指南
本指南介绍如何配置 OpenViking 的多写存储能力。多写存储允许一个 primary 后端同时复制写入多个 backup 后端,用于高可用、跨区域副本、读加速和存储迁移。
多写能力位于 RAGFS 内部。OpenViking 的 Python SDK、HTTP API 和 CLI 使用方式保持不变。
前置条件
- 已有可用的
ov.conf。 - 已确认 primary backend 可以正常读写。
- 如果要接入 S3 兼容存储,已准备好 bucket、endpoint 和访问凭据。
- 如果要迁移已有数据,先完成存量数据迁移,再启用多写。
最小配置
下面示例使用本地目录作为 primary,并把写入复制到另一个本地目录。
{
"storage": {
"workspace": "./data",
"agfs": {
"backend": "local",
"backups": {
"sync_type": "async",
"items": [
{
"name": "local-backup",
"backend": "local",
"local": {
"local_dir": "./data/backup"
}
}
]
}
}
}
}说明:
- 顶层
backend是 primary。 backups.items[]是 backup 列表。name是 backup 的稳定身份,后续同步元数据会引用它。sync_type不配置时默认按异步模式理解。
多 Backup 配置
可以配置多个 backup。下面示例同时写入本地副本和 S3 兼容对象存储。
{
"storage": {
"workspace": "./data",
"agfs": {
"backend": "local",
"backups": {
"sync_type": "async",
"items": [
{
"name": "local-az2",
"backend": "local",
"local": {
"local_dir": "./data/local-az2"
}
},
{
"name": "object-store",
"backend": "s3",
"s3": {
"bucket": "openviking-backup",
"region": "us-east-1",
"endpoint": "https://s3.example.com",
"access_key": "your-access-key",
"secret_key": "your-secret-key",
"prefix": "openviking"
}
}
]
}
}
}
}建议:
name不要使用会频繁变化的机器名或临时编号。- backup 的底层路径或 bucket 应避免与 primary 指向同一物理位置。
- 修改 backup
name会影响历史同步元数据的识别,生产环境应谨慎变更。
同步模式选择
异步模式
异步模式适合大多数场景。
{
"backups": {
"sync_type": "async",
"items": []
}
}特点:
- primary 写入成功后立即返回。
- backup 写入在后台执行。
- 写入延迟低。
- backup 可能短暂落后。
适合:
- 写入吞吐优先。
- backup 主要用于灾备。
- 可以接受最终一致性。
同步模式
同步模式会等待 backup 确认。
{
"backups": {
"sync_type": "sync",
"write_ack_count": 1,
"write_ack_timeout_ms": 5000,
"items": []
}
}参数说明:
| 参数 | 说明 |
|---|---|
write_ack_count | 写入返回前至少需要多少个 backup 确认 |
write_ack_timeout_ms | 等待 backup 确认的超时时间,单位毫秒 |
特点:
- 写入确认更强。
- 写入延迟受 backup 影响。
- 未确认的 backup 会继续由后台重试修复。
- primary 已写成功但 backup 未达确认数时,客户端可能收到错误;此时 primary 中可能已经存在数据。
适合:
- 希望尽量减少 primary 与 backup 的确认窗口。
- backup 延迟可控。
- 调用方能接受同步写入带来的额外延迟。
配置读加速
backup 默认不参与读取。要让 backup 服务读取,需要显式配置 operations。
{
"name": "cache-backend",
"backend": "memfs",
"operations": [
{
"operation": "read",
"priority": 10
}
]
}读取优先级规则:
priority越小越优先。- 只有声明
read的 backup 才参与读取。 - primary 始终作为最终兜底。
- 冷备 backup 不建议配置读能力。
如果一个 backup 只配置了 read,没有配置 write,它不会接收普通多写复制。只有在你明确知道该 backend 的数据来源时,才应使用这种配置。
Redirect 配置
Redirect 用于把匹配的文件写入指定 backup,而不是写入 primary。
按扩展名重定向:
{
"storage": {
"agfs": {
"backend": "local",
"redirects": [
{
"type": "FileExtensionPolicy",
"extensions": ["(pdf|ppt|zip)"],
"target": ["object-store"]
}
],
"backups": {
"items": [
{
"name": "object-store",
"backend": "s3",
"s3": {
"bucket": "openviking-large-files",
"endpoint": "https://s3.example.com"
}
}
]
}
}
}
}按大小重定向:
{
"type": "FileOverSizePolicy",
"max_size_mb": 100,
"target": ["object-store"]
}注意:
target必须引用已有 backup 的name。- redirect 文件仍会通过普通 API 呈现为可读、可列举、可查询状态。
- redirect 映射保存在 primary 的内部元数据中。
Exclude 配置
Exclude 用于让某个 backup 跳过匹配文件。
{
"name": "cache-backend",
"backend": "memfs",
"excludes": [
{
"type": "FileOverSizePolicy",
"max_size_mb": 50
},
{
"type": "FileExtensionPolicy",
"extensions": ["(mp4|zip)"]
}
]
}常见用法:
- 缓存 backend 排除大文件。
- 低成本备份排除无需保存的文件类型。
- 某个 backup 只保存文本或配置类资源。
如果 redirect 的目标 backup 同时 exclude 了该文件,说明配置互相冲突。请优先修正配置,不要依赖系统自动猜测其他目标。
加密配置
多写存储复用 OpenViking 的透明静态加密能力。
全局加密开启示例:
{
"encryption": {
"enabled": true,
"provider": "local",
"local": {
"key_file": "~/.openviking/master.key"
}
},
"storage": {
"workspace": "./data",
"agfs": {
"backend": "local",
"backups": {
"items": [
{
"name": "plain-cache",
"backend": "memfs",
"encryption": {
"enabled": false
}
},
{
"name": "encrypted-backup",
"backend": "local",
"local": {
"local_dir": "./data/encrypted-backup"
},
"encryption": {
"enabled": true
}
}
]
}
}
}
}规则:
- 全局
encryption.enabled=true时,primary 必须加密。 - backup 可以通过
encryption.enabled单独控制是否加密。 - Python SDK、HTTP API 和 CLI 不需要处理加解密。
.redirect.json和.sync_log.json等内部元数据会跟随 primary 加密策略。
存量数据迁移
多写只复制启用之后的新写入,不会自动复制历史文件。
推荐迁移流程:
- 停止或冻结写入窗口。
- 使用 OVPack 或其他受控工具把存量数据迁移到目标 backup。
- 校验目标 backend 的数据完整性。
- 配置并启用
storage.agfs.backups。 - 恢复写入。
- 观察同步状态和错误日志。
如果无法冻结写入,可以先做一次全量迁移,再短暂停写做增量校验,最后启用多写。
验证配置
启动前建议运行:
openviking-server doctor启动后可以用普通文件 API 验证:
openviking write viking://resources/multiwrite-check.txt \
--content "multi-write check" \
--wait
openviking read viking://resources/multiwrite-check.txt如果使用本地 backup,可以直接检查 backup 目录中是否出现对应文件。生产环境更推荐使用系统健康检查和同步状态命令。
常见问题
为什么 backup 没有参与读取?
backup 默认只参与写入,不参与读取。需要在 backup 上显式配置:
{
"operations": [
{
"operation": "read",
"priority": 10
}
]
}为什么启用多写后历史文件没有出现在 backup?
多写只处理启用后的新写入。历史文件需要先通过 OVPack、对象存储复制或后续 backfill 能力迁移。
异步模式下能否保证立即读到 backup 的最新数据?
不能。异步模式只保证最终一致。需要强读一致时,应让读取回退到 primary,或避免让可能滞后的 backup 参与读路由。
内部元数据文件会出现在用户列表里吗?
不会。.redirect.json 和 .sync_log.json 是内部文件,会被普通目录列表隐藏。
sync 模式返回失败是否表示 primary 一定没写入?
不是。primary 写成功但 backup 未达到确认数时,客户端可能收到失败。此时 primary 数据可能已经存在,落后的 backup 会由后台重试修复。
