Copy Slice 用于在同一 Collection 中,将源 Slice 的可复制文档复制到新的或空的目标 Slice,保留源 Slice 及其数据。目标 Slice 会按自身 Backing 的分片配置重新建立索引,因此可以让同一份数据使用不同的主分片数或路由分区,以适应数据量或查询负载变化。应用仍通过 Collection 和 Slice 访问,分片调整对调用方透明。它通过完整复制准备一份数据拷贝,不是时间点快照、备份或原子切流工具。
Copy 需要逐文档重新写入,复制耗时和读写开销随数据量增长。
调整目标分片配置(可选)
无需调整分片配置时,可以直接启动 Copy。如果需要让目标 Slice 使用不同的主分片数或路由分区,请先通过更新 Collection 设置后续 Backing 的参数,再预创建 Backing。预创建多个 Backing 后,系统会把新 Slice 的分配策略切换为 random;如果目标必须使用刚创建的 Backing,请在预创建后将策略改回 last,再注册目标 Slice。注册目标 Slice 后,先确认其 backing_index 使用了新 Backing,再启动 Copy;Copy API 不能直接指定目标 Backing。
启动 Copy
先确认源数据已经可搜索,目标使用新 Slice 或没有可搜索文档的 Slice;源文档必须符合本文 Copy 数据语义中的 _source 和 Mapping 要求。Copy 会读取源数据并写入目标,持续写入的增量不会自动同步,切换流量前需要另行处理。
POST /_slice_collection/{collection}/slices/{source}/_copy/{target}查询参数:
参数 | 默认值 | 说明 |
|
| 是否等待 Copy 进入完成状态。设置为 |
|
| 当前 HTTP 请求的等待预算。超时不会停止后台 Copy。 |
请求体参数均为可选:
参数 | 默认值 | 取值范围或说明 |
| 执行节点处理器数的一半,向上取整,并限制在 | 并行复制的工作任务数;不支持在运行中动态调整。 |
|
| 每批复制的文档数上限,取值范围 1~10000。内存压力触发熔断时,服务端会自动将批次减半后重试,最低为 1;因此实际批次可能小于设置值,持续降到 1 仍失败时 Copy 转为 |
|
| 整个 Copy 的目标文档处理速率,单位为文档/秒,由各 worker 分摊;按批次节流,并非 HTTP 请求数/秒。 |
以下示例从 1 个 worker、每批 500 条、总速率 500 条/秒开始。这些是便于控制初始负载的示例值,不是默认值或吞吐保证;应根据文档大小、源查询开销和目标写入负载评估后调整。
POST /_slice_collection/knowledge-chunks/slices/tenant-a/_copy/tenant-a-copy?wait_for_completion=false
{
"workers": 1,
"batch_size": 500,
"requests_per_second": 500
}异步请求返回 HTTP 202 Accepted。请保存响应中的 copy_id,并优先使用服务端返回的 status_url 和 cancel_url;响应头 Location 也提供状态查询地址。响应示例:
{
"copy_id": "opaque-copy-id",
"completed": false,
"timed_out": false,
"state": "RUNNING",
"source": "tenant-a",
"target": "tenant-a-copy",
"progress": { "total": 0, "created": 0, "version_conflicts": 0 },
"status_url": "/_slice_collection/knowledge-chunks/_copy/opaque-copy-id",
"cancel_url": "/_slice_collection/knowledge-chunks/_copy/opaque-copy-id/_cancel"
}workers 仅在执行并行度已确定且大于 0 时返回,调用方不能假设刚提交的响应一定包含该字段。失败时还会返回 error,用于说明失败原因。
copy_id 是不透明标识,可能包含冒号等 URL 保留字符。自行拼接状态查询地址时需要进行 URL 编码,建议直接使用响应返回的 status_url 和 cancel_url。
运行中的响应包含 progress 对象;只有 state=SUCCEEDED 时使用 result。FAILED 和 CANCELLED 仍使用 progress,表示结束前已完成的工作。三种结束状态均包含 completed=true 和耗时 took(毫秒)。version_conflicts 位于相应的 progress 或 result 中。
使用默认的 wait_for_completion=true 时,如果 Copy 在 timeout 内进入终态,接口返回 HTTP 200;等待超时则返回 HTTP 202 和 timed_out=true,后台 Copy 继续运行。客户端断开也不会自动取消 Copy。
HTTP 200 只表示 Copy 已进入终态,也可能是 FAILED 或 CANCELLED。
查询 Copy 状态
GET /_slice_collection/knowledge-chunks/_copy/<copy_id>状态 | 含义 |
| 正在复制或等待自动恢复。 |
| 已接受取消请求,正在停止。 |
| Copy 成功完成。 |
| Copy 无法继续,响应包含 |
| Copy 已取消,目标 Slice 和已复制数据保留。 |
状态查询成功时固定返回 HTTP 200,包括 state=FAILED。调用方必须检查 state 和 error,不能只看 HTTP 状态码。
按有间隔的方式查询状态,进入终态后停止轮询。SUCCEEDED 表示复制任务完成,不等于目标数据已全部可搜索;验证或切流前还需等待后台刷新,再检查目标查询结果;对冷查询延迟敏感时,提前预热即将访问的 Slice。Copy 长时间处于 RUNNING 且进度缓慢时,可能是服务端因内存压力自动调小了批次,属于自我保护行为;先继续按间隔查询,不要立即取消并重试。
调整状态保留时长(可选)
完成状态默认至少保留 1d,之后查询可能返回 HTTP 404。调用方不应把 Copy 状态接口作为长期审计存储。保留时长由动态集群设置 apack.slice_collection.copy.reservation_retention 控制,最小值为 1h:
PUT /_cluster/settings
{
"persistent": {
"apack.slice_collection.copy.reservation_retention": "1d"
}
}取消 Copy
POST /_slice_collection/knowledge-chunks/_copy/<copy_id>/_cancel取消操作不会删除目标 Slice 或已经复制的文档。接受异步取消时,接口返回 HTTP 202 和 state=CANCELLING;继续轮询,直到 completed=true,通常会看到 state=CANCELLED。如果 Copy 在取消生效前已成功或失败,会返回对应的结束状态。结束后 cancel_url 消失;重复取消已结束的 Copy 返回当前状态和 HTTP 200。
Copy 数据语义
Copy 创建一份新的数据副本,源 Slice 的位置保持不变。以下说明目标如何分配,以及复制时如何处理文档。
源 Slice 和目标 Slice 必须属于同一个 Collection,且名称不能相同。
启动时,目标 Slice 必须没有可搜索文档;已有可搜索文档时返回
target_not_empty。该检查不会锁定目标,后续并发写入仍可能产生同 ID 冲突。目标 Slice 不存在时,按 Collection 当前的普通 Slice 分配规则自动注册,即使
auto_create_slice=false;目标已存在时,沿用其 Backing 和分片位置。后续准入失败不会自动删除刚注册的目标 Slice。Copy 可以跨 Backing 或分片复制,支持源、目标采用不同的分片数和路由分区配置,文档按目标的配置重新建立索引。
Copy API 不提供指定目标 Backing 或分片的参数,也不保证新目标与源位于不同分片。若为后续 Backing 调整了分片数或路由分区配置,只有之后新建的 Backing 才会使用新配置;Copy 不会修改已有目标的分片布局,见后续生效设置。
Copy 使用 create-only 写入,不覆盖目标 Slice 中已有的同
_id文档;冲突计入version_conflicts,其他文档继续复制。Copy 完成后应检查该字段,并根据业务需要处理同 ID 数据。Copy 保留文档内容,包括
routing_field指向的字段。例如,routing_field=cluster_id时,将cluster-a复制到cluster-b后,目标文档中的cluster_id仍为cluster-a。后续通过 Index 或 Bulk 向目标写回文档时,应显式指定_slice=cluster-b,并把文档的cluster_id改为cluster-b。原样写回且省略_slice或routing会按字段值写入源 Slice;显式指定目标但保留源字段值,默认校验会返回 HTTP 400。不要通过关闭校验规避,应在应用切流前调整写入逻辑。向量簇模式下,Copy 只复制文档,不复制 Slice 的中心向量;目标自动注册时没有中心向量,因此不会参与自动选片。目标要参与自动选片时,应单独注册中心向量,也可以先注册带中心向量的空目标,再执行 Copy。
Copy 期间源 Slice 和目标 Slice 都可以读写,因此结果不是源 Slice 的原子时间点快照。
源 Slice 必须保留能够重建文档的完整
_source。关闭_source、使用 synthetic_source、配置非空_source.includes,或通过_source.excludes排除了仍用于索引、排序、copy_to或多字段的内容时,Copy 会被拒绝。仅排除可由索引安全恢复的字段可能可用,最终以服务端校验结果为准。源 Slice 的 Mapping 包含
semantic_text等推理字段时,当前不支持 Copy。default/final ingest pipeline 不会在 Copy 时重复执行。
文档会按目标当前 Mapping 重新应用,例如新增 multi-field 会在目标中生成。Copy 期间应避免会影响结果解释的 Mapping 变更。
常见启动错误:
HTTP | error.type | 处理建议 |
|
| 使用保留了完整可复制内容的 |
|
| 检查 synthetic |
|
| 目标 Slice 已经可以搜索到数据。确认目标名称,通常应改用新的目标 Slice。 |
|
| 目标 Slice 正被其他 Copy 或删除操作占用。如响应包含 |
如果需要在 Copy 完成后切换业务流量,请在应用层检查 Copy 状态和结果,再通过业务配置切换到目标 Slice。
有关 Copy 与 Branch 的选型,参阅可写数据分支:Branch Slice(Beta)。