多存储后端

Seafile 支持为不同资料库分配不同的存储后端。例如,可以将日常使用的资料库存储在本地磁盘或 SSD 上,将归档资料库存储在其他存储系统中;也可以通过多个存储后端分担数据量,降低单一 NFS 卷或 S3 存储桶的容量、性能压力。
多存储后端以 资料库 为单位分配存储位置。一个资料库关联一个存储类(storage class),其存储类与资料库之间的映射关系保存在数据库中。同一存储类中的 commits 、 fs 和 blocks 可以分别使用文件系统、S3、Swift 或 Ceph 等存储方式。
配置多存储后端需要完成以下操作:
  1. 在 .env 中启用多存储后端模式。
  2. 在 seafile.conf 中指定存储类配置文件。
  3. 在 JSON 文件中定义存储类。
  4. 在 seahub_settings.py 中启用存储类,并选择资料库映射策略。
以下以 Docker 部署为例。Seafile 14.0 和 13.0 均可使用此配置方式;如果自定义过数据卷或使用非 Docker 部署,请按照实际目录调整路径。
启用多存储后端
1. 设置环境变量
打开 Seafile 的 .env 文件(默认位于 /opt/seafile/.env ),设置:
            
                
                
SEAF_SERVER_STORAGE_TYPE=multiple
不要将其设置为 s3 或 disk ,否则不能按照下文的存储类配置使用多个存储后端。
2. 创建存储类配置文件
建议将存储类文件与 Seafile 的其他配置文件放在同一持久化目录中。在默认 Docker 部署中,宿主机的配置文件目录为:
            
                
                
/opt/seafile-data/seafile/conf/
创建文件:
            
                
                
nano /opt/seafile-data/seafile/conf/seafile_storage_classes.json
按照下文的示例填写存储类定义。注意,JSON 文件中不能包含注释。
路径说明: 默认 Docker 数据卷将宿主机的 /opt/seafile-data 挂载为容器内的 /shared ,因此上面的文件在容器内对应:
            
                
                
/shared/seafile/conf/seafile_storage_classes.json
如果修改过数据卷映射,请使用容器 实际可访问的绝对路径 。可通过以下命令检查文件是否已经映射到容器中:
            
                
                
docker exec seafile ls -l /shared/seafile/conf/seafile_storage_classes.json
3. 修改 seafile.conf
打开宿主机上的配置文件:
            
                
                
nano /opt/seafile-data/seafile/conf/seafile.conf
添加或更新 [storage] 配置段:
            
                
                
[storage]
enable_storage_classes = true
storage_classes_file = /shared/seafile/conf/seafile_storage_classes.json
配置项
说明
enable_storage_classes
设置为 true ,启用存储类功能。
storage_classes_file
存储类 JSON 文件在 Seafile 运行环境(容器)内 的绝对路径。
确保已为 Seafile 配置缓存服务。使用默认 Docker 部署时,Redis 已集成到 Seafile 13.0 和 14.0 的部署配置中;如果使用外部缓存或非 Docker 部署,请检查缓存配置。相关参数请参阅 Seafile 配置项 。
定义存储类
存储类在 seafile_storage_classes.json 文件中定义。文件内容是一个 JSON 数组,每个对象代表一个存储类。
字段
说明
storage_id
存储类的唯一内部标识,不向普通用户显示。已投入使用的标识不应随意修改。
name
用户可见的存储类名称。
is_default
是否为默认存储类。通常应有一个适用的默认存储类。
commits
存放 commit 对象的后端配置。
fs
存放文件系统元数据(fs 对象)的后端配置。
blocks
存放文件块(block 对象)的后端配置。
is_default 主要在以下情况下生效:
  • 使用用户选择策略时,如果用户未选择可用存储类,资料库使用默认存储类。
  • 对于其他映射策略,在启用多存储后端前创建、尚无存储类映射记录的资料库,使用默认存储类。
存储类配置示例
以下示例定义四个存储类,分别使用 S3、本地文件系统、Swift 和 Ceph。 只保留实际使用的存储类 ,并替换密钥、存储桶、容器路径及其他占位符。
            
                
                
[
{
"storage_id": "hot_storage",
"name": "Hot Storage",
"is_default": true,
"commits": {
"backend": "s3",
"bucket": "seafile-commits",
"key_id": "<your-key-id>",
"key": "<your-secret-key>"
},
"fs": {
"backend": "s3",
"bucket": "seafile-fs",
"key_id": "<your-key-id>",
"key": "<your-secret-key>"
},
"blocks": {
"backend": "s3",
"bucket": "seafile-blocks",
"key_id": "<your-key-id>",
"key": "<your-secret-key>"
}
},
{
"storage_id": "cold_storage",
"name": "Cold Storage",
"is_default": false,
"commits": {
"backend": "fs",
"dir": "/storage/seafile/cold-data"
},
"fs": {
"backend": "fs",
"dir": "/storage/seafile/cold-data"
},
"blocks": {
"backend": "fs",
"dir": "/storage/seafile/cold-data"
}
},
{
"storage_id": "swift_storage",
"name": "Swift Storage",
"is_default": false,
"commits": {
"backend": "swift",
"tenant": "<your-tenant>",
"user_name": "<your-username>",
"password": "<your-password>",
"container": "seafile-commits",
"auth_host": "<swift-auth-host>:5000",
"auth_ver": "v3.0"
},
"fs": {
"backend": "swift",
"tenant": "<your-tenant>",
"user_name": "<your-username>",
"password": "<your-password>",
"container": "seafile-fs",
"auth_host": "<swift-auth-host>:5000",
"auth_ver": "v3.0"
},
"blocks": {
"backend": "swift",
"tenant": "<your-tenant>",
"user_name": "<your-username>",
"password": "<your-password>",
"container": "seafile-blocks",
"auth_host": "<swift-auth-host>:5000",
"auth_ver": "v3.0",
"region": "RegionTwo"
}
},
{
"storage_id": "ceph_storage",
"name": "Ceph Storage",
"is_default": false,
"commits": {
"backend": "ceph",
"ceph_config": "/etc/ceph/ceph.conf",
"pool": "seafile-commits"
},
"fs": {
"backend": "ceph",
"ceph_config": "/etc/ceph/ceph.conf",
"pool": "seafile-fs"
},
"blocks": {
"backend": "ceph",
"ceph_config": "/etc/ceph/ceph.conf",
"pool": "seafile-blocks"
}
}
]
使用上述配置时,还需注意:
  • S3: 应分别准备存储 commits 、 fs 、 blocks 的存储桶。使用非 AWS 的 S3 兼容服务时,还可能需要配置 host 、 path_style_request 等参数。参阅 使用 S3 存储后端 。
  • 文件系统: dir 必须填写 Seafile 容器内 可访问的 seafile-data 基础目录。对象实际保存在该目录下的 storage/commits 、 storage/fs 和 storage/blocks 子目录中。上例的 /storage/seafile/cold-data 仅为示例路径,必须事先将相应存储挂载到容器内,并确认 Seafile 具有读写权限。
commits 、 fs 和 blocks 的具体参数与单存储后端模式下 seafile.conf 中的 [commit_object_backend] 、 [fs_object_backend] 和 [block_backend] 类似。
资料库映射策略
资料库映射策略决定 新建资料库 使用哪个存储类。Seafile 提供以下三种策略:用户选择、基于角色映射、基于资料库 ID 映射。
资料库创建时,系统会确定其存储类并将映射关系保存在数据库中。 之后修改映射策略,不会自动迁移已存在资料库的数据。
首先,在宿主机 /opt/seafile-data/seafile/conf/seahub_settings.py 中启用存储类功能:
            
                
                
ENABLE_STORAGE_CLASSES = True
随后选择下面一种映射策略。
用户选择( USER_SELECT )
用户创建资料库时,可以从有权限使用的存储类中选择存储位置。
在 seahub_settings.py 中添加:
            
                
                
STORAGE_CLASS_MAPPING_POLICY = 'USER_SELECT'
开启 ENABLE_STORAGE_CLASSES 后,如果没有显式指定映射策略,默认使用用户选择策略。
基于角色映射( ROLE_BASED )
可以根据用户角色限制其可使用的存储类。例如,允许普通用户使用热存储和冷存储,而访客仅能使用冷存储。
在 seahub_settings.py 中配置:
            
                
                
ENABLE_STORAGE_CLASSES = True
STORAGE_CLASS_MAPPING_POLICY = 'ROLE_BASED'
ENABLED_ROLE_PERMISSIONS = {
'default': {
'can_add_repo': True,
'can_add_group': True,
'can_view_org': True,
'can_use_global_address_book': True,
'can_generate_share_link': True,
'can_generate_upload_link': True,
'can_invite_guest': True,
'can_connect_with_android_clients': True,
'can_connect_with_ios_clients': True,
'can_connect_with_desktop_clients': True,
'storage_ids': ['hot_storage', 'cold_storage'],
},
'guest': {
'can_add_repo': True,
'can_add_group': False,
'can_view_org': False,
'can_use_global_address_book': False,
'can_generate_share_link': False,
'can_generate_upload_link': False,
'can_invite_guest': False,
'can_connect_with_android_clients': False,
'can_connect_with_ios_clients': False,
'can_connect_with_desktop_clients': False,
'storage_ids': ['cold_storage'],
},
}
上面是完整示例。如果已有 ENABLED_ROLE_PERMISSIONS 配置,应在现有角色配置中加入 storage_ids ,不要直接覆盖原有角色权限。
  • 一个角色只有一个可用存储类时,该角色下的用户无法选择其他存储类。
  • 一个角色分配了多个存储类时,用户创建资料库时可以从中选择。
  • 没有为角色分配存储类时,使用 JSON 文件中指定的默认存储类。
storage_ids 中的值必须与存储类 JSON 文件中的 storage_id 一致。
基于资料库 ID 映射( REPO_ID_MAPPING )
该策略根据资料库的 UUID 为新资料库分配存储类,可以将资料库分散到多个存储后端。
在 seahub_settings.py 中设置:
            
                
                
STORAGE_CLASS_MAPPING_POLICY = 'REPO_ID_MAPPING'
若希望某个存储类参与 新建资料库 的分配,可在相应存储类对象中添加 for_new_library :
            
                
                
{
"storage_id": "new_backend",
"name": "New Store",
"for_new_library": true,
"is_default": false,
"commits": {
"backend": "fs",
"dir": "/storage/seafile/new-data"
},
"fs": {
"backend": "fs",
"dir": "/storage/seafile/new-data"
},
"blocks": {
"backend": "fs",
"dir": "/storage/seafile/new-data"
}
}
上述 JSON 对象应添加到存储类配置文件的数组中,不要用单个对象替换整个数组。 /storage/seafile/new-data 是示例路径,使用前必须确保其存在于 Seafile 容器内。
注意: 此策略不是完整的分布式存储或自动数据迁移方案。以后新增存储类时,已有资料库仍保留在原存储类中;只有新建资料库会按当前策略分配。部署前应规划各存储后端的容量。
使配置生效
确认 .env 、 seafile.conf 、 seahub_settings.py 以及 JSON 文件均已保存,且存储服务、存储桶和容器挂载均可正常访问。
在默认 Docker 部署的 Compose 目录运行:
            
                
                
cd /opt/seafile
docker compose up -d
如果仅修改已有的 Seafile 配置文件,可按部署情况重启 Seafile 服务。检查启动日志:
            
                
                
docker logs seafile --follow
若启动失败,应首先检查 storage_classes_file 指定的路径是否确实存在于容器中,以及 JSON 格式、存储类名称和后端访问权限是否正确。
多存储后端数据迁移
Seafile 提供 migrate-repo.sh 脚本,将资料库数据从一个存储类迁移到另一个存储类。
迁移前请备份数据库和相关存储数据,并在维护窗口执行。 迁移脚本操作的是现有资料库数据,不能将改变映射策略当作迁移的替代方法。
迁移资料库
在能访问 Seafile 迁移脚本及其配置的运行环境中,进入脚本所在目录,执行:
            
                
                
./migrate-repo.sh [repo_id] origin_storage_id destination_storage_id
参数说明:
参数
说明
repo_id
需要迁移的资料库 ID,可省略。方括号表示可选参数,执行命令时不输入方括号。
origin_storage_id
源存储类的 storage_id 。
destination_storage_id
目标存储类的 storage_id 。
例如,将指定资料库从 hot_storage 迁移至 cold_storage :
            
                
                
./migrate-repo.sh 4c731e5c-f589-4eaa-889f-14c00d4893cb hot_storage cold_storage
不指定 repo_id 时,脚本将迁移源存储类上的全部资料库。执行前应确认源、目标存储类标识和迁移范围。
从 S3 迁移到其他存储时,应使用 S3 V4 签名认证协议。 使用旧版 V2 认证可能导致脚本无法正常列出对象。
保存迁移对象清单
运行迁移脚本前,可以通过 OBJECT_LIST_FILE_PATH 指定迁移对象清单的文件名前缀:
            
                
                
export OBJECT_LIST_FILE_PATH=/opt/test
例如,迁移资料库 4c731e5c-f589-4eaa-889f-14c00d4893cb 后,会在 /opt 目录下生成类似以下文件:
            
                
                
test_4c731e5c-f589-4eaa-889f-14c00d4893cb.fs
test_4c731e5c-f589-4eaa-889f-14c00d4893cb.commits
test_4c731e5c-f589-4eaa-889f-14c00d4893cb.blocks
保存对象清单有两个作用:
  1. 大型资料库需要分多次运行迁移脚本时,可以跳过此前已经迁移的对象。
  2. 如果迁移完成后需要删除源存储中的对象,则必须在迁移前设置 OBJECT_LIST_FILE_PATH 。
文件名前缀应位于脚本运行环境中可写、可保留的目录。请勿在迁移完成之前删除这些清单文件。
删除源存储中的对象
确认迁移成功且目标存储中的资料库可以正常访问后,可使用 remove-objs.sh 删除源存储类中指定资料库的对象:
            
                
                
./remove-objs.sh repo_id storage_id
其中 repo_id 为资料库 ID, storage_id 为需要清理的 源 存储类 ID。
此操作涉及数据删除,必须在迁移前设置并保留 OBJECT_LIST_FILE_PATH 生成的对象清单。执行前请再次确认备份、目标数据完整性及源存储类,避免误删仍在使用的对象。
迁移整个存储类
需要将某个存储类上的资料库全部迁移到其他存储类时,可以按以下顺序操作:
  1. 将目标存储类加入 seafile_storage_classes.json ,并确认其可以正常访问。
  2. 避免新的资料库继续分配到源存储类:使用基于角色的映射策略时,调整各角色的 storage_ids ;使用基于资料库 ID 的映射策略时,将源存储类的 for_new_library 设为 false ,并为目标存储类设置适当的值。
  3. 在维护窗口执行迁移脚本, 不指定 repo_id ,迁移该源存储类中的全部资料库。
  4. 验证迁移结果和业务访问正常后,再决定是否清理源存储对象。
不要仅通过删除 JSON 文件中的旧存储类定义来替代数据迁移。