Kibotos

存储池

本页介绍如何查看存储池与其中的对象、设置池容量、在池之间搬迁对象,以及宣告池丢失。存储池的概念、声明与初始化见NFS 上的存储池。

写命令的幂等键与期望版本见幂等键与期望版本。

查看与设置容量

用 kibo storage-pool list 查看 ctrl 已知的每个存储池,用 kibo storage-pool get <pool> 查看一个池的详情,用 kibo storage-pool objects <pool> 列出池里的对象,用 kibo storage-pool set-capacity <pool> <capacity> 设置池容量:

kibo storage-pool list --page-size 20
kibo storage-pool get shared
kibo storage-pool objects shared --all
kibo storage-pool set-capacity shared 4T

list 每行一个池:

列内容
POOL存储池 ID
DEFAULT是否至少有一个 node 把它声明为自己的默认池
CAPACITY池容量,即放置新对象时据以判断的容量。显示 - 表示还没有设置容量,池不接收新对象
RESERVED已预留量:池里未删除的 Volume 与保留的可写层的声明容量之和,加上正在搬进这个池的对象,括号里是它占池容量的比例。超过 100% 时池不再接收新对象,已有对象照常使用
NODES可用数/声明数:现在能用这个池的 node 数与声明它的 node 数。前者小于后者时有 node 拒绝了这个池,用 get 查看原因
VOLUMES、RETAINED_LAYERS这个池里的 Volume 与保留的可写层数量

get 在上面各项之外给出剩余容量、Awaiting removal,并逐行列出声明这个池的 node。Awaiting removal 是池里还留着、等 node 删除的副本数:对象搬走之后的源副本,以及搬迁失败时写进目标池的部分。它们占用存储空间,但不计入预留。

Nodes
  node-a (default, holds 12): available
  node-b: available
  node-c (holds 3): unavailable: storage pool marker is missing
  • default 表示这个 node 把它当作自己的默认池。共享池的各 node 应声明相同的默认池。
  • holds N 是这个 node 持有使用权的对象数,即它正在使用的 Volume 与可写层。为零时不显示。隔离 node 后归零。
  • unavailable 后面是 node 报告的原因。
  • kibo node get <node> 的 Storage pools 一节从 node 一侧给出同样的信息。

get 还给出池的 Version。set-capacity 以它做比较:

  • 不给 --expected-version 时,先读当前版本再提交。版本已被别人改动时退出 13 且不重试,重新查看后再设置。
  • 池不存在时退出 12。ctrl 只知道已经有 node 声明过的池。
  • 显式 --command-id 时必须同时给 --expected-version;同一对重放返回当前的池,不再改动。
  • 设置成功后输出与 get 相同的视图,下一次放置就按新容量判断,不需要重启 node。

Awaiting removal 不为零而池没有可用的 node 时,等 node 接入后自动删除。删除 Workspace 或 Volume 时池没有可用的 node、对象也没有 node 持有使用权,删除立即完成,块文件计入这个数,kibo workspace cleanup-status 把这些对象报告为 PENDING。node 可用后删除文件,状态变为 RELEASED。

池容量

池容量是池在 ctrl 上的属性,不写在 node 配置里,按上文用 set-capacity 设置。

  • 在设置容量之前,池不接收新的 Volume 与保留的可写层。
  • 共享池只有这一个容量,接入它的每台 node 都按它判断。
  • 扩容与缩容是同一条命令。调到已预留量以下时,已有对象照常使用,池只是不再接收新对象。

ctrl 按池计算存储占用。Volume 与保留的可写层从创建起就按声明容量计入所在的池,直到对象被删除;停止 Workspace 或解绑 Volume 不会释放这部分容量。

  • 块文件是稀疏文件,但计入的是声明容量,不是实际占用的块。容量应按池所在存储愿意承诺的空间设置。
  • 请求没有指定容量时,按 node 上存储的默认容量计入,与 node 实际创建的大小一致。

池里的对象

objects 每行一个对象:

列内容
OBJECTVolume ID;可写层用所属的 Workspace ID
KINDVolume 或 writable layer
WORKSPACE可写层所属的 Workspace,或 Volume 绑定的 Workspace
CAPACITY声明容量,即它在池里的预留
MOVING_TO正在搬往的池;没有在搬迁时为 -

行数与 get 的 Volumes、Retained layers 之和一致。正在搬进来的对象在搬迁结算之前列在源池里。

在池之间搬迁对象

Volume 与保留的可写层所在的池在第一次放置时定下。要换到另一个池,例如启用共享池之后把 node 私有池里的对象搬过去,用 operator 的搬迁命令。对象 ID、内容与容量不变,Volume 的绑定也不变;之后 Workspace 在能接入新池的 node 上启动。

kibo storage-pool objects local-a --all
kibo workspace stop ws-01k6…
kibo workspace move-layer ws-01k6… --storage-pool shared
kibo volume move vol-01k6… --storage-pool shared

前提

不满足下面任何一条,搬迁都被拒绝,对象不动:

  • 对象没有在用:Volume 是 AVAILABLE,所属或绑定它的 Workspace 已经停止(STOPPED,或启动失败、执行已释放的 FAILED)。
  • 至少一台可用的 node 同时接入源池与目标池。复制在这台 node 上进行。
  • 搬完之后,仍有一台 node 能同时接入这个 Workspace 的 Volume 与可写层。否则 Workspace 再也无法启动。两个对象分在不同的池时,先搬能让它们重新落在同一台 node 上的那一个。
  • 目标池的剩余容量容得下对象的声明容量。搬迁期间,对象在两个池里各占一份预留。

对象或它的 Workspace 正有别的命令在处理时,搬迁返回可重试的 unavailable,等那条命令结束后再搬。

过程

  1. ctrl 在目标池预留容量,把对象记为搬迁中。
  2. 执行复制的 node 先回放源文件系统里尚未回放的日志,再按块位图只复制已用的块,写进目标池的临时文件,校验后改名到位。
  3. ctrl 把对象的位置改到目标池,Volume 的 storage_pool 随之改变。
  4. 源池里的旧副本随后由接入源池的 node 删除。kibo storage-pool get 的 Awaiting removal 是还没删的副本数,删完之前对象不能搬回这个池。

复制耗时只随已用的数据增长,与声明容量无关。在写入约 385 MB/s 的 NFSv3 链路上,10 GiB 已用数据约 22 秒。

等待

  • 两个搬迁命令都等到搬迁结算。ctrl 每次最多等 1 分钟,kibo 用同一个命令 ID 再发,直到结算或到 --wait-timeout(默认 2 小时)。
  • Ctrl-C 或 --wait-timeout 只结束等待,不取消搬迁,kibo 退出 16。用同一个 --command-id 再运行,接着等它结算。
  • 对象已在目标池时,命令直接成功,不复制。

搬迁期间,下面的操作返回可重试的 unavailable,消息说明对象正在搬迁:启动所属或绑定它的 Workspace、绑定或解绑 Volume、扩容、删除 Volume 或 Workspace、导出。

失败

情形结果
node 拒绝复制:源文件系统损坏、目标池写入失败搬迁失败,命令返回 node 给出的原因。对象留在源池,内容不变;目标池里写下的部分随后被删除
复制的结果未知:node 失联或重启对象保持搬迁中,ctrl 只向同一台 node 用原命令重试
搬迁超过 2 小时仍未完成搬迁失败,对象留在源池
执行复制的 node 被隔离搬迁以可重试的失败结束,对象留在源池。目标池里写下的部分在隔离之后由目标池的其他 node 删除

宣告池丢失

池的存储再也取不回来时,用 kibo storage-pool declare-lost 宣告它丢失。

警告

ctrl 不能验证存储确实已经丢失,宣告之后不能撤销。

kibo storage-pool declare-lost local-a
  • 池的每个成员当前的启动序号都已被 isolate,或者池没有成员时才接受。否则返回 failed_precondition,退出码 13,错误信息列出还在的成员。isolate 它们,或让它们不再声明这个池,再宣告。
  • 执行前要在终端确认;没有终端时加 --yes。同一个 --command-id 重放返回同一结果。

宣告之后:

对象结果
池里的 Volume状态变为 LOST,可以查询和删除。删除立即完成,不访问 node。扩容、绑定、搬迁、导出返回 failed_precondition
绑定 LOST Volume 的 Workspace启动失败,错误码 failed_precondition,原因 VOLUME_LOST,不可重试。换绑到别的 Volume,或删除 Workspace。不会挂空盘
可写层在这个池的 Workspace下一次启动放到别的池,从新的可写层开始,报告 RESET 与 LAYER_UNAVAILABLE
等待删除的副本丢弃,Awaiting removal 归零
池get 显示 Lost,预留量归零,不再接受新对象。请求指名它的新 Volume、导入和搬迁返回 failed_precondition
仍声明这个池的 node这个池显示 unavailable,原因写明已宣告丢失

池 ID 不再启用。旧盘即使找回来、标记相同,也只是不可用。新存储用新的池 ID。

本页内容