# venus-worker 的配置解析
venus-worker 是数据封装的执行主体,我们来了解一下它的配置文件结构和配置方式。
venus-worker
的配置文件采用了 toml
格式,需要注意的是,这种格式中,以 #
开头的行将被视为注释,不会生效。
以 mock 实例为例,一份基础的配置大概会是这样:
[worker]
# name = "worker-#1"
# rpc_server.host = "192.168.1.100"
# rpc_server.port = 17891
[sector_manager]
rpc_client.addr = "/ip4/127.0.0.1/tcp/1789"
# rpc_client.headers = { User-Agent = "jsonrpc-core-client" }
# piece_token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiMS0xMjUiLCJwZXJtIjoic2lnbiIsImV4dCI6IiJ9.JenwgK0JZcxFDin3cyhBUN41VXNvYw-_0UUT2ZOohM0"
[sealing]
# allowed_miners = [10123, 10124, 10125]
# allowed_sizes = ["32GiB", "64GiB"]
enable_deals = true
# max_deals = 3
max_retries = 3
# seal_interval = "30s"
# recover_interval = "60s"
# rpc_polling_interval = "180s"
# ignore_proof_check = false
[[sealing_thread]]
location = "./mock-tmp/store1"
# plan = "snapup"
# sealing.allowed_miners = [10123, 10124, 10125]
# sealing.allowed_sizes = ["32GiB", "64GiB"]
# sealing.enable_deals = true
# sealing.max_deals = 3
# sealing.max_retries = 3
# sealing.seal_interval = "30s"
# sealing.recover_interval = "60s"
# sealing.rpc_polling_interval = "180s"
# sealing.ignore_proof_check = false
[[sealing_thread]]
location = "./mock-tmp/store2"
[[sealing_thread]]
location = "./mock-tmp/store3"
# deprecated
# [remote_store]
# name = "persist-store1"
# location = "./mock-tmp/remote"
[[attached]]
# name = "persist-store1"
location = "./mock-tmp/remote"
[attached_selection]
# enable_space_weighted = false
[processors.limit]
# pc1 = 3
# pc2 = 2
# c2 = 1
[processors.ext_locks]
# gpu1 = 1
[processors.static_tree_d]
# 2KiB = "./tmp/2k/sc-02-data-tree-d.dat"
# fields for tree_d processor
[[processors.tree_d]]
# fields for pc1 processors
[[processors.pc1]]
# bin = "./dist/bin/venus-worker-plugin-pc1"
# args = ["--args-1", "1", --"args-2", "2"]
numa_preferred = 0
cgroup.cpuset = "4-5"
envs = { RUST_LOG = "info" }
[[processors.pc1]]
numa_preferred = 0
cgroup.cpuset = "6-7"
[[processors.pc1]]
numa_preferred = 1
cgroup.cpuset = "12-13"
# fields for pc2 processors
[[processors.pc2]]
# cgroup.cpuset = "24-27"
[[processors.pc2]]
cgroup.cpuset = "28-31"
# fields for c2 processor
[[processors.c2]]
cgroup.cpuset = "32-47"
下面我们将逐一分析其中的可配置项。
# [worker]
worker
配置项用于配置本实例的一些基础信息。
# 基础配置范例
[worker]
# 实例名,选填项,字符串类型
# 默认以连接 `venus-sector-manager` 所使用的网卡 IP 地址作为实例名
# name = "worker-#1"
# rpc 服务监听地址,选填项,字符串类型
# 默认为 "0.0.0.0",即监听本机所有地址
# rpc_server.host = "192.168.1.100"
# rpc 服务监听端口,选填项,数字类型
# 默认为 17890
# rpc_server.port = 17891
绝大多数情况下,本配置项内的各个字段无需手工配置。
仅在一些特殊情况,诸如:
- 希望按照自己的编排习惯命名每个
venus-worker
实例 - 不希望监听所有网卡IP,仅允许本地的 rpc 请求
- 一台机器上部署了多个
venus-worker
,为避免端口冲突,需要进行区分
等场景,需要按需手动配置这里的选项。
# [sector_manager]
sector_manager
用于配置 venus-sector-manager
相关的信息,以使得 venus-worker
可以正确的连接到对应的服务。
# 基础配置范例
[sector_manager]
# 构造 rpc 客户端时使用的连接地址,必填项,字符串类型
# 可以接受 `multiaddr` 格式,也可以接受诸如 `http://127.0.0.1:1789`,`ws://127.0.0.1:1789` 这样的 url 格式
# 通常情况下,使用 `multiaddr` 格式以和其他组件保持一致
rpc_client.addr = "/ip4/127.0.0.1/tcp/1789"
# 构造 rpc 客户端时使用的 http 头信息,选填项,字典类型
# 默认为 null
# rpc_client.headers = { User-Agent = "jsonrpc-core-client" }
# 请求订单 piece 数据时携带的校验 token, 选填项,字符串类型
# 默认为 null
# 当本实例允许封装带有订单数据的扇区时,通常需要设置此项
# 此项的值通常即为所使用的 venus 系列服务的 token 值
# piece_token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiMS0xMjUiLCJwZXJtIjoic2lnbiIsImV4dCI6IiJ9.JenwgK0JZcxFDin3cyhBUN41VXNvYw-_0UUT2ZOohM0"
# [sealing]
sealing
用于配置封装过程中的通用参数选项。
# 基础配置范例
[sealing]
# 允许的`SP`,选填项,数字数组格式
# 默认为 null,允许来自任何 `SP` 的任务
# 配置后,仅可执行来自数组中罗列的 `SP` 的封装任务
# allowed_miners = [10123, 10124, 10125]
# 允许的扇区大小,选填项,字符串数组格式
# 默认为 null, 允许任意大小的扇区任务
# 配置后,仅可执行符合数组中罗列的扇区大小的任务
# allowed_sizes = ["32GiB", "64GiB"]
# 是否允许向扇区内添加订单,选填项,布尔类型
# 默认为 false
# 当设置为 true 时,通常需要同时设置 `sector_manager` 中的 `piece_token` 项
# enable_deals = true
# 允许向扇区内添加的最大订单数量,选填项,数字类型
# 默认为 null
# max_deals = 3
# 封装过程中遇到 temp 类型的错误时,重试的次数,选填项,数字格式
# 默认为 5
# max_retries = 3
# 封装过程中遇到 temp 类型的错误时,重试的间隔,选填项,时间字符串格式
# 默认为 "30s", 即30秒
# recover_interval = "30s"
# 空闲的 `sealing_store` 申请封装任务的间隔, 选填项,时间字符串格式
# 默认为 "30s", 即30秒
# seal_interval = "30s"
# rpc 状态轮询请求的间隔,选填项,时间字符串格式
# 默认为 "180s", 即180秒
# 封装过程中,部分环节使用了轮询方式来获取非实时的信息,如消息上链等。
# 这个值有助于避免过于频繁的请求占用网络资源
# rpc_polling_interval = "180s"
# 是否跳过 proof 的本地校验环节,选填项,布尔格式
# 默认为 false
# 通常只在诸如测试之类的情况下设置此项
# ignore_proof_check = false
sealing
中的配置项通常有根据经验预设的默认项,这使得我们在绝大多数情况下无需自行配置。
# 特殊配置范例
# 1. 测试网络,仅为特定 SP
提供服务
allowed_miners = [2234, 2236, 2238]
# 2. 大规模集群,降低网络占用
# 在可恢复的异常中,有相当一部分是网络抖动带来的,增大自动恢复的间隔时间降低请求频率
recover_interval = "90s"
# 正常过程中的轮询请求也增大间隔时间降低请求频率
rpc_polling_interval = "300s"
# 3. 增大扇区异常自愈的可能性
# 增大自动恢复的尝试次数
max_retries = 10
# 增大自动恢复的间隔时间
recover_interval = "60s"
# [[sealing_thread]]
sealing_thread
用于为每个扇区工作线程进行配置。一份配置文件中可以存在多个 sealing_thread
配置组。
# 基础配置范例
[[sealing_thread]]
# 扇区数据目录路径,必填项,字符串类型
# 建议使用绝对路径,数据目录和工作线程是一对一绑定的
location = "/mnt/nvme1/store"
# 任务类型,选填项,字符串类型
# 默认值为 null
# 可选填 sealer 或 snapup, 当不填写时,默认等效为 selaer
# plan = "snapup"
# 封装过程的定制参数,仅对当前工作线程生效
# sealing.allowed_miners = [10123, 10124, 10125]
# sealing.allowed_sizes = ["32GiB", "64GiB"]
# sealing.enable_deals = true
# sealing.max_retries = 3
# sealing.seal_interval = "30s"
# sealing.recover_interval = "60s"
# sealing.rpc_polling_interval = "180s"
# sealing.ignore_proof_check = false
[[sealing_thread]]
location = "/mnt/nvme2/store"
[[sealing_thread]]
location = "/mnt/nvme3/store"
sealing_thread
的数量和对应的数据路径需要根据规划情况编排。
为了方便组合搭配,每个 sealing_thread
可以配置独立的 sealing
子项,它满足:
可配置项的命名、类型、效果与通用的
sealing
项保持一致仅对当前工作线程生效
未配置时使用通用的
sealing
项内的值
# 特殊配置范例
# 1. 两个工作线程,分别为不同的 SP
服务
[[sealing_thread]]
location = "/mnt/nvme2/store"
sealing.allowed_miners = [1357]
[[sealing_thread]]
location = "/mnt/nvme3/store"
sealing.allowed_miners = [2468]
# 2. 两个工作线程,分别为不同的扇区大小服务
[[sealing_thread]]
location = "/mnt/nvme2/store"
sealing.allowed_sizes = ["32GiB"]
[[sealing_thread]]
location = "/mnt/nvme3/store"
sealing.allowed_sizes = ["64GiB"]
# [remote_store] 已废弃
remote_store
用于配置已完成的扇区持久化数据保存的位置。
# 基础配置范例
[remote_store]
# 名称, 选填项,字符串类型
# 默认为路径对应的绝对路径
# name = "remote-store1"
# 路径,必填项,字符串类型
# 建议直接填写绝对路径
location = "/mnt/remote/10.0.0.14/store"
由于需要在 venus-worker
和 venus-sector-manager
之间协调存储位置信息,而在很多情况下,同一个持久化存储目录在venus-worker
机器和 venus-sector-manager
机器上的挂载路径不完全一致,因此我们决定使用 name
作为协调的基础信息.
如果持久化存储目录在所有机器上的挂载路径都统一的话,配置时也可以选择在 venus-worker
和venus-sector-manager
两侧都不配置 name
。这种情况下,两者都会使用绝对路径作为 name
,也能匹配。
# [attached_selection]
attached_selection
用于配置选择已完成的扇区持久化数据保存的位置
# 基础配置范例
[attached_selection]
# 是否启用以剩余空间作为权重的选择策略,选填项,布尔类型
# 默认值为 false
# enable_space_weighted = false
# [[attached]]
attached
用于配置已完成的扇区持久化数据保存的位置,允许同时配置多个。
# 基础配置范例
[attached]
# 名称, 选填项,字符串类型
# 默认为路径对应的绝对路径
# name = "remote-store1"
# 路径,必填项,字符串类型
# 建议直接填写绝对路径
location = "/mnt/remote/10.0.0.14/store"
# 只读,选填项,布尔类型
# 默认值为 false
# readonly = true
由于需要在 venus-worker
和 venus-sector-manager
之间协调存储位置信息,而在很多情况下,同一个持久化存储目录在venus-worker
机器和 venus-sector-manager
机器上的挂载路径不完全一致,因此我们决定使用 name
作为协调的基础信息.
如果持久化存储目录在所有机器上的挂载路径都统一的话,配置时也可以选择在 venus-worker
和venus-sector-manager
两侧都不配置 name
。这种情况下,两者都会使用绝对路径作为 name
,也能匹配。
# [processors]
processors
用于配置封装执行器,和封装计算过程中的一些信息。
这个配置项实际上分为三个子项,我们逐一分析。
# [processors.limit]
processors.limit
用于配置不同封装阶段的并行任务数量控制。这是为了降低不同阶段的资源相互争抢的情况。
需要注意的是,当配置了外部执行器时,外部执行器的数量和允许的并发总量也会影响并行任务数量。
# 基础配置范例
[processors.limit]
# tree_d 阶段的并发数限制,选填项,数字类型
# tree_d = 1
# pc1 阶段的并发数限制,选填项,数字类型
# pc1 = 3
# pc2 阶段的并发数限制,选填项,数字类型
# pc2 = 2
# c2 阶段的并发数限制,选填项,数字类型
# c2 = 1
举例来说,如果设置了 pc2 = 2
,那么同一时间最多只会有两个扇区可以执行 pc2
阶段的任务。
# [processors.ext_locks]
processors.ext_locks
用于配置一些自定义的锁限制, 它是和 [[processors.{stage_name}]]
中的 locks
配置项联动使用的。
这个配置项允许使用者自定一些限制条件,并令不同的外部处理器受其约束。
# 基础配置范例
[processors.ext_locks]
# some_name = some_number
# 特殊配置范例
processors.ext_locks
自身是不能独立生效的。
# 一块 GPU, pc2 和 c2 公用
[processors.ext_locks]
gpu = 1
[[processors.pc2]]
locks = ["gpu"]
[[processors.c2]]
locks = ["gpu"]
这样,pc2
c2
会各启动一个外部处理器,两者将会产生竞争关系,也就意味着两者将不会同时发生。
# 两块 GPU, pc2 和 c2 公用
[processors.ext_locks]
gpu1 = 1
gpu2 = 1
[[processors.pc2]]
locks = ["gpu1"]
[[processors.pc2]]
locks = ["gpu2"]
[[processors.c2]]
locks = ["gpu1"]
[[processors.c2]]
locks = ["gpu2"]
这样,pc2
c2
会各启动两个外部处理器,将会产生两两竞争的关系,从而允许限制一块 GPU 上只能执行其中一个阶段的任务。
# [processors.static_tree_d]
processors.static_tree_d
是为了提升 cc 扇区
的效率而引入的配置项。
当为相应扇区大小配置了静态文件路径时,将会直接使用此文件作为 cc 扇区
的 tree_d 文件,而不会尝试再次生成。
# 基础配置范例
[processors.static_tree_d]
2KiB = "/var/tmp/2k/sc-02-data-tree-d.dat"
32GiB = "/var/tmp/32g/sc-02-data-tree-d.dat"
64GiB = "/var/tmp/64g/sc-02-data-tree-d.dat"
# [[processors.{stage_name}]]
这是用于配置外部执行器的配置组。
目前 {stage_name}
可选
tree_d
pc1
pc2
c2
每一个这样的配置组意味着将启动一个对应阶段的外部执行器,可选的配置项包含:
[[processors.pc1]]
# 自定义外部执行器可执行文件路径,选填项,字符串类型
# 默认会使用主进程对应的可执行文件路径
# bin = "./dist/bin/venus-worker-plugin-pc1"
# 自定义外部执行器的参数,选填项,字符串数组类型
# 默认值为 null,将使用 `venus-worker` 自己的执行器默认参数
# args = ["--args-1", "1", --"args-2", "2"]
# numa 亲和性分区 id,选填项,数字类型
# 默认值为 null,不会设置亲和性
# 需要根据宿主机的 numa 分区进行填写
# numa_preferred = 0
# cpu 核绑定和限制选项,选填项,字符串类型
# 默认值为 null,不设置绑定
# 值的格式遵循标准 cgroup.cpuset 格式
# cgroup.cpuset = "4-5"
# 外部执行器的附加环境变量,选填项,字典类型
# 默认值为 null
# envs = { RUST_LOG = "info" }
# 本执行器允许的并发任务数量上限
# 默认值为 null,无限制,但任务具体是否并发执行,视使用的外部执行器实现而定
# 主要使用在 pc1 这样可以多个并行的环节,可以有效节约共享内存、线程池等资源
# concurrent = 4
# 自定义的外部限制锁名称,选填项,字符串数组类型
# 默认值为 null
# locks = ["gpu1"]
# 基础配置范例
[processors.limit]
pc1 = 4
pc2 = 2
c2 = 1
[[processors.pc1]]
numa_preferred = 0
cgroup.cpuset = "0-7"
concurrent = 2
envs = { FIL_PROOFS_USE_MULTICORE_SDR = "1" }
[[processors.pc1]]
numa_preferred = 1
cgroup.cpuset = "12-19"
concurrent = 2
envs = { FIL_PROOFS_USE_MULTICORE_SDR = "1" }
[[processors.pc2]]
cgroup.cpuset = "8-11,24-27"
envs = { FIL_PROOFS_USE_GPU_COLUMN_BUILDER = "1", FIL_PROOFS_USE_GPU_TREE_BUILDER = "1", CUDA_VISIBLE_DEVICES = "0" }
[[processors.pc2]]
cgroup.cpuset = "20-23,36-39"
envs = { FIL_PROOFS_USE_GPU_COLUMN_BUILDER = "1", FIL_PROOFS_USE_GPU_TREE_BUILDER = "1", CUDA_VISIBLE_DEVICES = "1" }
[[processors.c2]]
cgroup.cpuset = "28-35"
envs = { CUDA_VISIBLE_DEVICES = "2,3" }
[[processors.tree_d]]
cgroup.cpuset = "40-45"
以上是基于一台 48C + 4GPU 的设备的 processors.{stage_name}
配置范例,在这套配置下,将启动:
- 2个
pc1
外部执行器,采用MULTICORE_SDR
模式,各分配 8 核,允许 2 个并发任务,且内存分配优先使用本 numa 分区 - 2个
pc2
外部执行器,各分配 8 核,各使用一块 GPU - 1个
c2
外部执行器,分配 8 核, 使用一块 GPU - 1 个
tree_d
外部执行器,分配 6 核
# 特殊配置范例
# 1. 使用 patch 了闭源的、经过算法优化的 c2 外部执行器
[[processors.c2]]
bin = /usr/local/bin/venus-worker-c2-optimized
cgroup.cpuset = "40-47"
envs = { CUDA_VISIBLE_DEVICES = "2,3" }
# 2. 使用外包模式的 c2 外部执行器
[[processors.c2]]
bin = /usr/local/bin/venus-worker-c2-outsource
args = ["--url", "/ip4/apis.filecoin.io/tcp/10086/https", "--timeout", "10s"]
envs = { LICENCE_PATH = "/var/tmp/c2.licence.dev" }
# 3. GPU 不足的情况下使用 CPU 模式弥补 pc2 计算能力
[[processors.pc2]]
cgroup.cpuset = "8-11,24-27"
envs = { FIL_PROOFS_USE_GPU_COLUMN_BUILDER = "1", FIL_PROOFS_USE_GPU_TREE_BUILDER = "1", CUDA_VISIBLE_DEVICES = "0" }
[[processors.pc2]]
cgroup.cpuset = "20-23,36-45"
# 4. 最优配比下,pc1 总量为奇数,无法平分
[processors.limit]
pc1 = 29
pc2 = 2
c2 = 1
[[processors.pc1]]
numa_preferred = 0
cgroup.cpuset = "0-41"
concurrent = 14
envs = { FIL_PROOFS_USE_MULTICORE_SDR = "1" }
[[processors.pc1]]
numa_preferred = 1
cgroup.cpuset = "48-92"
concurrent = 15
envs = { FIL_PROOFS_USE_MULTICORE_SDR = "1" }
# 5. 希望优先集中使用 numa 0 区完成 pc1
[processors.limit]
pc1 = 29
pc2 = 2
c2 = 1
[[processors.pc1]]
numa_preferred = 0
cgroup.cpuset = "0-47"
concurrent = 16
envs = { FIL_PROOFS_USE_MULTICORE_SDR = "1" }
[[processors.pc1]]
numa_preferred = 1
cgroup.cpuset = "48-86"
concurrent = 13
envs = { FIL_PROOFS_USE_MULTICORE_SDR = "1" }
# 一份最简可工作的配置文件范例
[sector_manager]
rpc_client.addr = "/ip4/{some_ip}/tcp/1789"
# 根据实际资源规划
[[sealing_thread]]
location = "{path to sealing store1}"
[[sealing_thread]]
location = "{path to sealing store2}"
[[sealing_thread]]
location = "{path to sealing store3}"
[[sealing_thread]]
location = "{path to sealing store4}"
[[sealing_thread]]
location = "{path to sealing store5}"
[[sealing_thread]]
location = "{path to sealing store6}"
[[sealing_thread]]
location = "{path to sealing store7}"
[[sealing_thread]]
location = "{path to sealing store8}"
[remote_store]
name = "{remote store name}"
location = "{path to remote store}"
[processors.static_tree_d]
32GiB = "{path to static tree_d for 32GiB}"
64GiB = "{path to static tree_d for 64GiB}"
# 根据实际资源规划
[processors.limit]
pc1 = 4
pc2 = 2
c2 = 1
[[processors.pc1]]
numa_preferred = 0
cgroup.cpuset = "0-7"
concurrent = 2
envs = { FIL_PROOFS_USE_MULTICORE_SDR = "1" }
[[processors.pc1]]
numa_preferred = 1
cgroup.cpuset = "12-19"
concurrent = 2
envs = { FIL_PROOFS_USE_MULTICORE_SDR = "1" }
[[processors.pc2]]
cgroup.cpuset = "8-11,24-27"
envs = { FIL_PROOFS_USE_GPU_COLUMN_BUILDER = "1", FIL_PROOFS_USE_GPU_TREE_BUILDER = "1", CUDA_VISIBLE_DEVICES = "0" }
[[processors.pc2]]
cgroup.cpuset = "20-23,36-39"
envs = { FIL_PROOFS_USE_GPU_COLUMN_BUILDER = "1", FIL_PROOFS_USE_GPU_TREE_BUILDER = "1", CUDA_VISIBLE_DEVICES = "1" }
[[processors.c2]]
cgroup.cpuset = "28-35"
envs = { CUDA_VISIBLE_DEVICES = "2,3" }
[[processors.tree_d]]
cgroup.cpuset = "40-45"
在按实际情况进行规划并填写相应信息后,以上就是一份:
- 只进行
cc 扇区
- 32GiB 和 64GiB 扇区免 tree_d
- 一体化资源分配
的最简配置文件了。