# Lotus 进阶运维

# 00-应用配置详解

  • miner_10g_inaddr: miner 内网(万兆网卡)IP 地址,通常用来配置 Miner 的内网下载地址,包括下载 lotus 程序,api/token 文件等。

  • 应用程序的运行参数配置: 这个参数通常都是通过为进程添加环境变量来实现,比如设置 lotus-miner 进程的 最大打开文件数 只需添加 _rli_RLIMIT_NOFILE 环境变量即可。

    最大打开文件数      655350    _rli_RLIMIT_NOFILE
    

    通过这种方法你还可以设置进程的其他资源配置,比如限制进程的最大使用 CPU 的核数, 每次可以消费 CPU 时间片的数量等。下面表格列出了常用的几个内核参数:

    参数名称 参数说明
    _rli_RLIMIT_NOFILE 进程最大打开文件数
    _rli_RLIMIT_CORE 进程最大使用 CPU 核数
    _rli_RLIMIT_CPU 进程每次可以消费 CPU 时间片的数量
    _rli_RLIMIT_DATA 进程数据使用空间的限制,包括数据段,bss段和堆
    _rli_RLIMIT_FSIZE 进程进程创建文件大小的限制
    _rli_RLIMIT_RSS 进程驻留内存的页数的大小限制
    _rli_RLIMIT_MEMLOCK 进程可以锁定内存的最大字节数
    _rli_RLIMIT_NPROC 当前进程所属的真实id对应的用户所能创建的最大进程数(线程)

# 01-网关机器配置

如果您的每天新增的算力小于 20TiB,我们建议您直接使用 miner 下载数据。 超过 20TiB 每天的算力增速,而您的 Miner 网卡只有 10GiB 带宽的话,那么建议您使用网关应用下载数据,原因如下:

为什么要使用网关机下载数据?

  1. 控制流量并发,使用 storage-worker 你可以设置并行下载扇区数量,而不会出现一次下载太多扇区,导致 Miner 网络处于一种假死状态。
  2. 读写分离,网关机器负责将扇区写入存储,Miner 负责读入扇区做时空证明和爆块,互不影响。
  3. 方便横向扩展,可以应对日均算力增速达到 PiB 级的集群,只需多加一些网关机下载即可。
  4. 更新存储不需要重启 Miner,只需要重启 storage-worker 即可。
  1. 添加 lotus-storage-worker 应用

    1. 双击桌面的 应用中心 图标,进入应用中心主界面.

    2. 点击 lotus-storage-worker 应用图标下的 添加 按钮.

    3. 添加完成之后桌面上会多出一个 lotus-storage-worker 应用图标(如果没有请刷新页面).

  2. 配置 lotus-storage-worker 应用

    1. 双击桌面的 lotus-storage-worker 应用,进入应用主界面.

    2. 点击 应用配置 标签栏,再点击 编辑 按钮,基本上你直接使用默认的配置就行了,只需要把软件源修改一下:

      • AMD版本下载地址: 改成你自己的内网下载地址,如:http://192.168.100.103:17181/lotus/1.15.1/20220506/amd/lotus-worker
      • Intel版本下载地址: 改成你自己的内网下载地址,如:http://192.168.100.103:17181/lotus/1.15.1/20220506/intel/lotus-worker
      • 并行fetch数量: 默认值为 4,表示可以一次并行下载 4 个扇区,可以根据你的带宽和存储设备写入速度适当调整。
  3. 安装并启动 lotus-storage-worker 应用,启动成功生成 sectorstore.json 文件之后立即停止它。 我们需要对网关机器的 sectorstore.json 文件进行一些额外的配置。

  4. ssh 登录到网关机,编辑 /yuanyu/lotus-storage-worker/data/sectorstore.json 文件,大概内容如下:

    {
       "ID": "69537740-9e0c-4dfd-9f84-0a1d07dc1234",
       "DeclID": "",
       "BootNoDecl": true, 
       "Weight": 10,
       "CanSeal": false,
       "CanStore": true,
       "CanFinal": false,
       "MaxStorage": 0,
       "Groups": null,
       "AllowTo": null,
       "BackupDir": "",
       "BackupTypes": false,
    }
    

    我们需要修改有 2 个字段:

    1. DeclID: 当前 Worker 上的扇区声明的 Storage ID, 这里要修改成 Miner 上对应的 Storage ID。因为网关机器把扇区下载下来以后并不声明自己的 Storage ID 而是要声明 Miner 的 Storage ID。假设你 Miner 其中一个 Storage Path 是 /data01,那么这个值就是 /data01/sectorstore.json 文件中对应的 ID 字段。
    2. BootNoDecl: 设置为 true, 表示启动的时候并不声明当前 Worker 目录下的扇区。 |
  5. 把你最终希望落盘的存储设备挂载到网关机器上,假设你的挂载目录为 /data01,那么你需要在该目录里创建 sealedcache 目录,然后软链到 /yuanyu/lotus-storage-worker/data/ 目录下:

    mkdir /data01/cache /data01/sealed
    # 删除网关机默认生成的 sealed 和 cache 文件夹
    rm -rf /yuanyu/lotus-storage-worker/data/cache 
    rm -rf /yuanyu/lotus-storage-worker/data/sealed
    # 创建软连接
    ln -s /data01/cache /yuanyu/lotus-storage-worker/data/cache
    ln -s /data01/sealed /yuanyu/lotus-storage-worker/data/sealed
    
  6. 一切配置完之后,启动 lotus-storage-worker 应用,等待下载一个扇区,确认一下落盘的位置是否正确。

关于 Worker 落盘方案:

原语云早期应对这种扇区下载流量瓶颈的方案是 Worker 直接落盘方案。大概实现思路是这样的:

  1. FinalizeSector 的时候,Miner 会根据传输配置给 Worker 发送不同的指令。
  2. 如果 Worker 接收到的指令是直接传输,那么 Miner 就会把扇区从 Worker 下载过来 Miner 这边落盘;如果 Worker 接收到的指令是下载重定向,那么 Worker 将会直接把扇区存储到最终存储设备,然后直接响应 Miner 的指令(但是无数据传输)。

这个方案的优势是节省了数据传输,比网关方案少一次数据传输,劣势是所有的 Worker 都需要跟 Miner 共享存储,确保它们下载的数据 Miner 全部都能读取到,Worker 部署维护起来会比较麻烦一些。我们推荐大家使用网关机方案,但是如果你的需求确实更贴近 Worker 落盘方案,也可以选择后者。 Worker 落盘的功能我们一直保留着,后期将会补充详细的实施文档。

# 02-开启 Miner 爆块/时空证明加速

经常有集群运维人员反馈:

我的集群有几个 Deadline 隔三差五的掉算力,通常掉完第二天又恢复了,然后又发现另一个 Deadline 掉了算力。。。

不知你是否注意到这么一种情况,随着算力的增加,存储设备越来越满,访问速度越来越慢,你时空证明的时间也从之前的 400-500 秒慢慢变成 1000 多秒甚至更长。如果在某次时空证明的时候不小心卡一下,那么本次时空证明的时间可能就超过 1800 秒了,然后你就不小心掉了一次算力。

对此,原语云提供了一个非常好用加速优化方案:你只需要启用 Miner 的 cache 加速功能即可。 具体操作方式如下:

# 1. 准备 cache 缓存设备

通常我们建议使用高速盘,比如 M.2 或者 U.2 磁盘,空间大小我们建议按照 2.5TiB => 1PiB 这个比例准备,也就是说 1PiB 算力要准备 2.5TiB 的高速缓存盘。这个也是我们为什么在 Miner 机器配置 中为什么要加上 4 块 4TiB 加速数据盘 的原因。至于为什么是 4 块,考虑到可能要组 RAID 或者 ZFS 文件系统。

我们这里假设您的加速设备是挂载在 /speedup 目录下,您需要在该目录下创建好 2 个目录:

mkdir /speedup/cache 
mkdir /speedup/sealed

加速原理:

在数据落盘的时候,扇区的 cache 数据直接写入 /speedup/cache 目录,同时为了防止加速盘损坏导致数据丢失,落盘时会自动写入一份 cache 文件到 备份目录。这样爆块/时空证明直接从加速存储设备读扇区数据,再配合原语云的底层 IO 优化,使得扇区读取吞吐量得到了成倍的提升。

# 2. 启用 cache 备份功能

cache 文件配置备份的方法请参考 扇区文件备份设置

# 3. 拷贝 cache 文件

这里我们假设你原来的扇区存储目录是 /data01

  1. 如果你之前已经有 Proving 状态的扇区的话,你需要把已经完成封装的扇区的 cache 文件拷贝到 /speedup/cache 目录。

  2. /data01/cache 目录移动到 backup 目录,然后将 /speedup/cache 软链到 /data01

    mv /data01/cache /data01/backup
    ln -s /speedup/cache /data01/cache
    

    注意:

    如果你有网关机(lotus-storage-worker)或者单独的证明 Worker(lotus-winning-worker/lotus-window-worker) 的话,也需要在它们上面建立相应的 /speedup/cache 软连接。

  3. 重启 lotus-miner, lotus-winning-worker, lotus-window-worker, lotus-storage-worker 应用。

# 4. 验证加速效果

你可以通过查看启用 cache 加速之后的时空证明日志,来验证当前时空证明的时间:

grep "computing window post" /yuanyu/lotus-miner/log/error.log

输出类似如下:

computing window post	{"batch": 0, "elapsed": 453.373130997}
computing window post	{"batch": 0, "elapsed": 423.827466285}
computing window post	{"batch": 0, "elapsed": 330.872714065}
computing window post	{"batch": 0, "elapsed": 230.683308647}
...

如果当下你的 Miner 没有正在或者即将进行时空证明的 Deadline, 你可以 手动触发时空证明,然后就能立即得到启用加速后的时空证明结果。

# 03-设置 CPU 亲和力核心集合

众所周知,SDR 加速之所以能够大大加快 PC1 的速度,原因就是在进行 PC1 计算的时候加入了并行计算以及绑定共享 L3 缓存核组的功能,但是官方的绑核实现有几个缺陷:

官方绑核缺陷

  1. 核组绑定不稳定,尤其是当你核组数要小于 PC1 任务数的时候,比如你的 CPU 只有 8 组加速核,但是你却想并行 12 个 PC1 任务,这样后面的 4 个任务没法绑核,只能跟前面的任务争抢 CPU 资源,导致整体效率都降低。
  2. 不支持自定义绑核,比如把 PC1 和 PC2 分别绑定不同的核组,防止数据乱串导致 L3 缓存命中率大大降低。

# 1. 修改应用配置

自 v1.11.1-20210923 版本开始,原语云已经开始支持自定义为 lotus 相关进程绑定指定共享 L3 缓存的 CPU 核组。在原语云的 lotus-ap-worker, lotus-p1-worker, lotus-p2-worker, lotus-c2-worker 的应用配置中,都有一个叫做 CPU亲和力核心集合 的配置。

这个配置的值是一个类似下面的表达式:

${auto_cpu_l3_share_cores(-2,-1)}

如果你熟悉原语云的应用配置的参数解析规则,你应该知道上述表达式是一个函数调用的语法。它表示该 lotus 进程绑定倒数第二组核。

PS: 如果你还不知道这个配置表达式的配置语法,请先阅读 应用配置参数解析

接下来咱们详细介绍一下针对不同型号的 CPU,不同的使用场景我们该如何设置各个应用进程的绑核参数。 原语云平台会自动将你当前 CPU 按照共享 L3 缓存的核组进行分组。假设某款 CPU 共享 L3 缓存的分组是这样的:

0,1,2,3/4,5,6,7/8,9,10,11/12,13,14,15/16,17,18,19/20,21,22,23/24,25,26,27/28,29,30,31

CPU 核组绑定功能主要用到了 auto_cpu_l3_share_cores(start,end,split) 这个函数过滤器,该函数过滤器主要接收三个参数:

  • start: 核组的起始下标(从左往右),如果为负数则说明是倒数(从右往左)。

  • end: 核组的结束下标(从左往右),如果为负数则说明是倒数(从右往左)。

  • split: 是否进行二次分组,如果设置为 1,表示不进行二次分组。如果该参数为 2 的话(这个也是原语云的默认值),表示对当前共享 L3 缓存的一组核再进行二次分组:

    # split = 1
    0,1,2,3/4,5,6,7/8,9,10,11/12,13,14,15/16,17,18,19/20,21,22,23/24,25,26,27/28,29,30,31
    # split = 2
    0,1/2,3/4,5/6,7/8,9/10,11/12,13/14,15/16,17/18,19/20,21/22,23/24,25/26,27/28,29/30,31
    

    这样如果你内存够的话,可以把 PC1 的任务数量增加一倍,或者腾出一些核专门给 PC2 程序使用,而使用官方的自动绑核程序是无法做到这一点的。

需要说明的是,核组的起始位置一个左闭右开区间[start,end),也就是说左边值是包含,右边的值是不包含的。

通常我们推荐的配置是:

推荐

  1. PC1-PC2 机器: 留出一组核给 PC2 进程(通常是倒数第一组),再留出一组核给 PC1 进程(通常是倒数第二组),然后剩下的核组都给 PC1 SDR 加速用。
  2. AP-C2 机器: 留出一组核给 AP 进程(通常是倒数第一组),剩下的核组都绑定给 C2 进程。

下面是一些配置的实例:

  1. 筛选出第 0-10 组核(10组核)

    auto_cpu_l3_share_cores(0,10)
    
  2. 筛选出倒数第一组核

    # 1. end 参数不传入
    auto_cpu_l3_share_cores(-1)
    # 2. end 参数传入你CPU 的核数
    # 比如你的 CPU 是 32 核 64 线程的,你可以这样设置
    auto_cpu_l3_share_cores(-1,64)
    # 3. 如果你不知道你 CPU 的核数,那么你可以传入一个很大的值,超过总核数:
    auto_cpu_l3_share_cores(-1,200)
    
  3. 筛选出倒数第二组核

    auto_cpu_l3_share_cores(-2,-1)
    
  4. 筛选 0-倒数第一组核,并把每组核进行二次拆分为 2 组

    auto_cpu_l3_share_cores(0,-1,2)
    

# 2. 确认绑核是否生效

原语云的 lotus-worker 程序会在启动的时候打印一些启动日志,你可以据此确认绑核是否生效,我们以 lotus-p1-worker 为例,日志的路径在 /yuanyu/lotus-p1-worker/log/info.log(如果是 PC2 worker的话,把前面的 p1 改成 p2 即可),日志的输入格式大概如下:

2021-10-03 21:04:21  DEBUG  env check and setting: 
2021-10-03 21:04:21  DEBUG  setenv(CACHE_SHARE_PATH, 0): Succeed
2021-10-03 21:04:21  DEBUG  setenv(SEALED_SHARE_PATH, 0): Succeed
2021-10-03 21:04:21  DEBUG  setenv(CACHE_FETCH_REDIRECT_PATH, 0): Succeed
2021-10-03 21:04:21  DEBUG  setenv(IPFS_GATEWAY, https://proof-parameters.s3.cn-south-1.jdcloud-oss.com/ipfs/): Succeed
2021-10-03 21:04:21  DEBUG  setenv(FIL_PROOFS_SDR_CACHE_GROUPS, 0,1,2,3/4,5,6,7/8,9,10,11/12,13,14,15/16,17,18,19/20,21,22,23/24,25,26,27/28,29,30,31/32,33,34,35/36,37,38,39/40,41,42,43/44,45,46,47/48,49,50,51/52,53,54,55/56,57,58,59/64,65,66,67/68,69,70,71/72,73,74,75/76,77,78,79/80,81,82,83/84,85,86,87/88,89,90,91/92,93,94,95/96,97,98,99/100,101,102,103/104,105,106,107/108,109,110,111/112,113,114,115/116,117,118,119/120,121,122,123): Succeed
2021-10-03 21:04:21  DEBUG  setenv(FIL_PROOFS_MULTICORE_SDR_LOOKAHEAD, 800): Succeed
2021-10-03 21:04:21  DEBUG  setenv(CACHE_FETCH_POLICY, transmission): Succeed
2021-10-03 21:04:21  DEBUG  setenv(FIL_PROOFS_MULTICORE_SDR_PRODUCERS, 3): Succeed
2021-10-03 21:04:21  DEBUG  setenv(FIL_PROOFS_USE_MULTICORE_SDR, true): Succeed
2021-10-03 21:04:21  DEBUG  setenv(SEALED_FETCH_POLICY, transmission): Succeed
2021-10-03 21:04:21  DEBUG  setenv(RUST_LOG, Info): Succeed
2021-10-03 21:04:21  DEBUG  setenv(FIL_PROOFS_MAXIMIZE_CACHING, 1): Succeed
2021-10-03 21:04:21  DEBUG  setenv(SEALED_FETCH_REDIRECT_PATH, 0): Succeed
2021-10-03 21:04:21  DEBUG  setenv(UNSEALED_FETCH_REDIRECT_PATH, 0): Succeed
2021-10-03 21:04:21  DEBUG  setenv(UNSEALED_FETCH_POLICY, transmission): Succeed
2021-10-03 21:04:21  DEBUG  setenv(FIL_PROOFS_MULTICORE_SDR_PRODUCER_STRIDE, 128): Succeed
2021-10-03 21:04:21  DEBUG  setenv(UNSEALED_SHARE_PATH, 0): Succeed
2021-10-03 21:04:21  DEBUG  setenv(FIL_PROOFS_PARENT_CACHE, /yuanyu/filecoin-parents): Succeed
2021-10-03 21:04:21  DEBUG  setenv(FIL_PROOFS_PARAMETER_CACHE, /yuanyu/filecoin-proof-parameters): Succeed
2021-10-03 21:04:21  DEBUG  rlimit check and setting: 
2021-10-03 21:04:21  DEBUG  setrlimit(RLIMIT_NOFILE, 655350, 655350): Succeed
2021-10-03 21:04:21  DEBUG  cpu affinity check and setting for process 0: 
2021-10-03 21:04:21  DEBUG  cpu_affinity_cores: 56,57,58,59,120,121,122,123
2021-10-03 21:04:21  DEBUG  sched_setaffinity(0, [56,57,58,59,120,121,122,123]): [56,57,58,59,120,121,122,123]

你需要通过上面输出日志(你只需要关注高亮的那三行)确认下面几个配置是否设置正确:

  1. 确认 PC1 SDR 加速的 CPU 核组划分是否正确(FIL_PROOFS_SDR_CACHE_GROUPS 环境变量设置):

    2021-10-03 21:04:21  DEBUG  setenv(FIL_PROOFS_SDR_CACHE_GROUPS, 0,1,2,3/4,5,6,7/8,9,10,11/12,13,14,15/16,17,18,19/20,21,22,23/24,25,26,27/28,29,30,31/32,33,34,35/36,37,38,39/40,41,42,43/44,45,46,47/48,49,50,51/52,53,54,55/56,57,58,59/64,65,66,67/68,69,70,71/72,73,74,75/76,77,78,79/80,81,82,83/84,85,86,87/88,89,90,91/92,93,94,95/96,97,98,99/100,101,102,103/104,105,106,107/108,109,110,111/112,113,114,115/116,117,118,119/120,121,122,123): Succeed
    

    你只需要确认一组就行了。比如我们可以用下面的方法查看第 1 组共享 L3 缓存的 CPU 核有哪些:

    lscpu -e |grep ":0 "
    # 下面是输出
    CPU NODE SOCKET CORE L1d:L1i:L2:L3 ONLINE    MAXMHZ   MINMHZ
    0    0      0    0 0:0:0:0          yes 2600.0000 1500.0000
    1    0      0    1 1:1:1:0          yes 2600.0000 1500.0000
    2    0      0    2 2:2:2:0          yes 2600.0000 1500.0000
    3    0      0    3 3:3:3:0          yes 2600.0000 1500.0000
    64    0      0    0 0:0:0:0          yes 2600.0000 1500.0000
    65    0      0    1 1:1:1:0          yes 2600.0000 1500.0000
    66    0      0    2 2:2:2:0          yes 2600.0000 1500.0000
    67    0      0    3 3:3:3:0          yes 2600.0000 1500.0000
    

    第一列就是 CPU 核的序号,如果你能在上面的 FIL_PROOFS_SDR_CACHE_GROUPS 参数中找到 0,1,2,364,65,66,67 这两组核就说明原语云自动分组的结果是正确的。如果发现不对,请把问题反馈给原语云客服,或者可以自己手动分组,把分组的结果按照上面的格式填入到 多核SDR L3共享核心分组 这个配置参数。

  2. 确认 FIL_PROOFS_MULTICORE_SDR_PRODUCERS 这个环境变量设置是否正确:

    2021-10-03 21:04:21  DEBUG  setenv(FIL_PROOFS_MULTICORE_SDR_PRODUCERS, 3): Succeed
    

    常用 CPU 的推荐配置值如下:

    CPU 型号 FIL_PROOFS_MULTICORE_SDR_PRODUCERS
    AMD 7542 3
    AMD 7742 3
    AMD 7302 1
    AMD 7532 1
    AMD 7402 1
    AMD 7H12 3
  3. 确认当前进程的 CPU 亲和力设置是否正确:

    2021-10-03 21:04:21  DEBUG  sched_setaffinity(0, [56,57,58,59,120,121,122,123]): [56,57,58,59,120,121,122,123]
    

    sched_setaffinity(0, [56,57,58,59,120,121,122,123]) 的第二个参数跟冒号后面的结果是一致即表示设置成功。

# 3. 动态设置 CPU 亲和力

如果你的某个进程(如 lotus-p1-worker)已经启动了,此时你想改变 CPU 绑核的策略,那么你其实是可以动态配置某个进程的 CPU 亲和力的。

首先,你可以通过下面的脚本(get_cpu_affinity.lua)获取某个进程的当前的 CPU 亲和力设置:

-- auto cpu affinity get util

local func = import("exported.func")

local pid = tonumber(args["pid"])
if pid == nil then
    print("missing pid parameter\n")
    return false
end

local aff = sched_getaffinity(pid)
print("process ", pid, " affinify: ", aff, "\n")

这是一个 Ark 语言脚本,你可以把上面脚本保存到一个文件如:get_cpu_affinity.lua, 然后可以用下面的方式运行:

# 命令格式,<pid> 代表当前 lotus 程序的进程 ID
qark-client --ark get_cpu_affinity.lua --pid=<pid>
# 假如你的进程 ID 为 123
qark-client --ark get_cpu_affinity.lua --pid=123
# 运行输出的结果有点类似下面这样
process 123 affinify: [28,29,30,31,60,61,62,63]

我们也提供了一个动态设置 CPU 亲和力的脚本(set_cpu_affinity.lua),脚本内容如下:

-- auto cpu affinity set util

local func = import("exported.func")

local pid = tonumber(args["pid"])
if pid == nil then
    print("specified --pid=<pid>\n")
    return false
end

local sIdx = tonumber(args["start"])
if sIdx == nil then
    print("specified --start=<start> parameter\n")
    return false
end

local eIdx = tonumber(args["end"])
if eIdx == nil then
    print("specified --end=<end> parameter\n")
end

local cores = {}
local group = func.get_cpu_l3_share_cores(sIdx,eIdx)
for _,g in ipairs(group) do
    for _,v in ipairs(g) do
        table.insert(cores, v)
    end
end

sched_setaffinity(pid, cores)
local aff = sched_getaffinity(pid)
print("process ", pid, " affinify: ", aff, "\n")

假如你需要把倒数第三和倒数第四组核设置给 lotus-p1-worker 进程(进程 ID 为 123),运行方法如下:

qark-client --ark set_cpu_affinity.lua --pid=123 --start=-4, --end=-2
# 运行输出结果有点类似下面这样:
process 123 affinify: [24,25,26,27,56,57,58,59]

对于具体该使用哪种绑核方案效果会比较好,需要你们自己去多都调试绑核方案,这里提供一些关于 CPU 共享 L3 缓存核组信息供大家参考:

  1. 目前主流 AMD 7002 系列的CPU(如 7h12/7542/7742/7302/7532/7702等),不同的 CPU 共享 L3 缓存核组(加速核组)的数量不一样,7542,7302等只有 8 组加速核, 7h12, 7742 等有 18 组加速核,这里顺便提一下拥有 16 组加速核的 CPU 如果关闭了超线程的话,就只有 8 组加速核了。 7742 建议关闭超线程跑,否则 PC1 的效率会大大降低。 7H12 不关闭超线程貌似目前实跑的数据还不错,不过关闭超线程之后也许表现会更好,这个需要大家自己去验证。

  2. 不同的 CPU 每组加速核中 CPU 核心数量不一样,比如同样是 8 组加速核,7542 的 GroupCount(每组加速核中核心数) 是 4, 而 7532 的 GroupCount 是 2。

  3. 在 PC1 的 SDR 加速程序中,有个 FIL_PROOFS_MULTICORE_SDR_PRODUCERS 参数,这个参数的默认值就是 GroupCount - 1,比如 7302/7532 就应该设置为 1, 而 7h12/7542 则应该设置为 3。顺便说一句,在 lotus-p1-worker 应用中,该参数对应着 多核SDR producer 数量 这个配置。

下面提供几种 CPU 绑核方案的示例,供你参考,更重要的是希望你能从中体会到背后的决策原理,体会一点思辨的乐趣

  1. 7302/7532 单路 CPU, 总共有 8 组核,通常我们选择前面 1-6 组加速核给 PC1 的 SDR 加速用,由于原语云默认会把 SDR 加速核组进行二次拆分,这样刚好可以并行 12 个 PC1 任务,相当于是每 2 个任务共用一组加速核。 后面还剩下 2 组,按照常规分组,我们应该把第 7 组和分给 PC1 进程,然后把第 8 组核分给 PC2 进程。但是由于 7302 这款 CPU 的 GroupCount 只有 2,在测试的过程中,我们发现如果只分一组核给 PC2 进程的话,会严重影响 PC2 任务的效率,所以这时我们应该调整一下绑核策略,把 PC1 和 PC2 进程共享绑定到 7-8 两组加速核上,那么最终的绑核结果就变成下面这样了:

  2. 同样是对于 8 组核的 7542,由于它每组核拥有 4 个 CPU 核心(GroupCount = 4),那么它可以分别为 PC1 和 PC2 绑定一组核,这样能保持绑核稳定(PC1 和 PC2 进程都绑定了独立的核组),有能满足 PC2 的性能要求,那么这时候的绑核应该是下面这样的:

  3. 如果你用的是像 7h12 这样的本身拥有 16 组加速核的 CPU(前提是你没有关闭超线程功能),且 GroupCount = 4 的话,那么你可以把前面 1-14 组加速核都给 PC1 的 SDR 加速用(并行 14 个 PC1),剩下 2 组分别给 PC1 进程和PC2 进程用,如下所示:

    如果你的机器有 2TiB 内存的话,那么上述的分组方案依然适用,只需要把 PC1 的并行数量改成 26-28 即可。

  4. 如果是 7302/7532 双路这样的这样 CPU 配置,那么 CPU 核心信息就是 16-2(16组加速核,每组核数为 2),那么一个可行的分组方案可以这样的:

    如果内存为 1TiB,则 PC1 的并行数可以设置为 12,内存为 2TiB 的话,并行数可以设置为 24。

总结:

上述只是几种可行的绑核方案,可能并不是最优的方案,我们只是希望上述示例能够帮助大家理解绑核方案背后的原理,然后大家就能够自己根据 CPU 型号调试出属于自己的最优绑核方案。

# 04-开启/关闭 PC2/C2 批量提交

从 v1.10.0 开始, Lotus 开始支持批量提交扇区,一方面是为了提高 Lotus 链的吞吐量,另一方面也为 Miner 节省 Gas 费。 目前支持批量提交的消息主要有 2 种,PreCommitSectorProveCommitSector 通常又被成为 PC2 提交和 C2 提交,分别对应 BatchPreCommitsAggregateCommits 这两个配置。你可以同时关闭或者开启这两种消息的聚合提交功能,有可以只开启其中的一个。

当前的 Lotus 的默认配置是:BatchPreCommits 默认是开启的(true), 而 AggregateCommits 默认是关闭的(false)。那么如果我们想要关闭批量提交功能,只需要打开 lotus-miner 的配置文档 /yuanyu/lotus-miner/data/config.toml,把上面对应的参数改成 false 即可。

反过来,如果你想开启批量提交功能,就把上面对应的参数改成 true,不过需要注意的的是:如果 AggregateCommits 设置成 true 的话,那么你最好把 FinalizeEarly 这个参数也设置成 true。并且你可以通过调节下面几个参数来控制你批量提交消息数量的多少:

  • MinPreCommitBatch: 每条聚合消息最少包含 PreCommitSector 消息条数
  • MaxPreCommitBatch: 每条聚合消息最多包含 PreCommitSector 消息条数
  • MinCommitBatch: 每条聚合消息最少包含 ProveCommitSector 消息条数
  • MaxCommitBatch: 每条聚合消息最多包含 ProveCommitSector 消息条数

关于批量提交的更多配置说明,请参考 Lotus-Miner 进阶配置

改完配置需要重启 Miner 才会生效,另外,你可以通过下面的命令来手动强制提交聚合消息:

# 1. 提交 SubmitPreCommitBatch 消息
yy_lotus-miner sectors batching precommit --publish-now
# 2. 提交 SubmitCommitAggregate 消息
yy_lotus-miner sectors batching commit --publish-now

# 05-手动触发时空证明

适用场景:在运维过程中时空证明出现异常,在完成修复之后通常如果我们要验证修复的操作是否生效,需要等到第二天的时空证明的时候再去观察。这样有两个弊端:

  1. 时间成本太高,任何一个修复操作都无法立即验证是否生效,需要等到第二天。
  2. 资金成本太高,假如修复操作没有生效,问题没有解决,时空证明没有通过,就需要以罚没质押币作为代价,这种的试错成本完全没有必要承担。

此时我们可以通过在本地运行一次离线的时空证明来进行操作验证:

yy_lotus-miner proving challenge --really-do-it=true <DeadlineIndex>
# e.g
yy_lotus-miner proving challenge --really-do-it=true 0

你还可以传入 <Parttion> 参数来做<DeadlineIndex> 指定某些 Partition 的扇区时空证明(多个 Partition 使用英文逗号隔开):

yy_lotus-miner proving challenge --really-do-it=true --partitions=<Partition> <DeadlineIndex>

执行时空证明需要一定的时间,所以当前命令会阻塞一段时间,执行成功之后会输出类似如下日志:

2022-02-23T16:06:55.826+0800	INFO	main	lotus-miner/proving.go:649	start proving challenge	{"deadline": 0}
2022-02-23T16:07:26.007+0800	INFO	main	lotus-miner/proving.go:659	post result	{"index": 0, "deadline": 0, "partitions": [{"Index":2,"Skipped":[0]}], "proofs": [{"PoStProof":7,"ProofBytes":"tkz8fe/rNEtg9RPMi2DS/JmmCkEx37ELTcyvkV3OpWjy3dmnUaEIzZ7BP+IYPZewgvkTTgBabcLQ+aL0kt9mBg6dNqfal65dmwKIyJackHKOU8D/FezUqGL3lHlBLXi6EJS5GrjRgRfBSWMpgvMb+F54Mqr0MLjDQs9Ge7Me1Uj8ueZrXinLMYP4TQnFPqIcteoHceUrgMJwYeweI8gGakqXv9ZH2E4QdxwJQ/aFWIG8T8CMmqZA0gCzxWUgxHJ4"}]}
2022-02-23T16:07:26.007+0800	INFO	main	lotus-miner/proving.go:662	end proving challenge	{"elapsed": 30.180774601}

警告:

运行时空证明可能会占用并锁定全部证明 Worker,所以强烈建议你错开线上的时空证明的时间段,也可以另外选取一台带 GPU 的机器,将 Miner 的环境(元数据,存储设备挂载)拷贝过去,然后单独运行一个 Miner 程序,但是记得要关闭时空证明调度和爆块证明调度功能,以免重复计算和提交证明,导致惩罚。

nohup yy_lotus-miner run \
--listen=xxx.xxx.xxx.xxx:2345 \
--storage-api=local \
--winning-post=false \ # 关闭爆块证明调度
--winning-worker=true \
--window-post=false \ # 关闭时空证明调度
--window-worker=true \
--sealing-mgr=true \
--sector-store=true \
--deals-mgr=false > /yuanyu/lotus-miner/log/error.log 2>&1 &

启动 Miner 之后,就可以在当前 Miner 去执行手动触发时空证明命令。

# 06-扇区恢复

目前 Lotus 的扇区有两种类型,CC 扇区(无效数据)和订单扇区(真实数据存储),目前我们只实现了 CC 扇区的恢复,对于订单扇区的恢复功能,要等待后续开发。扇区恢复需要你有封装 Worker,恢复速度等于相对应 Worker 的封装速度。

扇区恢复的使用非常简单,跟质押一个扇区一样简单:

yy_lotus-miner sectors recover --really-do-it <sid>

# 输出信息
Recover CC sector 2 
  State:  Removed
  Ignore: GetTicket/PreCommitting/WaitSeed/C2/Committing
  Ticket: {Value: BOrg0kgZmbQy/KukR6CSz938gulGQ3EKLTLiIgdaBJM=, Epoch: 28}
  Seed:   {Value: GQ41slpCnLRn5tPsI/kWTOpnjVCA/g3yE+Yqf/petsQ=, Epoch: 940}

通常你只需传入 SectorID 参数,恢复工具会根据你输入的扇区 ID 自动获取到当前扇区的 Ticket 和 Seed 信息,如果你 Miner 本地元数据损坏或者丢失,那么将无法获取到上述信息,恢复将失败,此时你可以手动传入该扇区获取 Ticket 和 Seed 所在的链高度(epoch)

yy_lotus-miner sectors recover --really-do-it --ticket-epoch=<ticket-epoch> --precommit-epoch=<seed-epoch> <sid>

如果扇区已存在于某个 Storage 上,那么系统将会提示你先删除该扇区,你只需根据提示删除即可:

yy_lotus-miner sectors remove --really-do-it <sid>

你也可以用 debug 模式,查询一下当前要恢复的扇区的信息,比如当前状态,ticket,seed 等信息:

lotus-miner sectors recover --debug <sid>

# 输出信息
Allocated(2): true
OnChainInfo: &{SectorNumber:2 SealProof:6 SealedCID:bagboea4b5abcamnpxdmca75jne7vfak6apep6t22dtifvynqbqgfile44cmjattd DealIDs:[] Activation:948 Expiration:1550368 DealWeight:+0 VerifiedDealWeight:+0 InitialPledge:+244140621168640 ExpectedDayReward:+131685387873035 ExpectedStoragePledge:+366370703133300 SectorKeyCID:<nil>}Recover CC sector 2 (Debug)
  State:  Removed
  Ignore: GetTicket/PreCommitting/WaitSeed/C2/Committing
  Ticket: {Value: BOrg0kgZmbQy/KukR6CSz938gulGQ3EKLTLiIgdaBJM=, Epoch: 28}
  Seed:   {Value: GQ41slpCnLRn5tPsI/kWTOpnjVCA/g3yE+Yqf/petsQ=, Epoch: 940}
@Note: This is a debug mode, for analysis ONLY, drop --debug flag to actually perform the operation

警告:

凡是带 Wait 状态的扇区(WaitSeed/PreCommitWait/CommitWait),一般都是在等待上链,或者等种子,此时请勿进行删除或者恢复操作,否则可能发生未知错误。可以等到状态变为其他常规状态,或者失败状态之后再操作。

# 07-设置 GPU 分组

在原语云最新的 lotus 版本中,我们对 GPU 资源分组进行了更细致的优化,提供了 2 种 GPU 分组模式。

  1. 自动分组,默认我们会把所有的 GPU 分为 1 组,你可以设置 GPU 分组组距来对 GPU 进行平均分组,比如 2 个 GPU 一组。通过导出环境变量 BELLPERSON_GPU_GROUP_SIZE 来实现。原语云的应用配置中也有对应的参数提供给你配置,在 lotus-c2-worker 应用中,这个环境变量的默认值是 1,也就是每个 GPU 运行一个 C2 任务。

  2. 自定义分组,你可以完全根据你的意愿自定义 GPU 分组。通过导出 BELLPERSON_GPU_GROUPS 环境变量来实现:

    export BELLPERSON_GPU_GROUPS="1/2,3/4,5"
    

    数字代表 GPU 的 Bus_id,不同的 GPU Bus_id 之间用,隔开。每组之间用 / 隔开。

# 08-GPU 优化参数调节

原语云内置 GPU 参数优化功能,这个功能默认在 Miner 机器上是关闭的,在 C2-Worker 机器上是打开的。

lotus 程序会自动识别你 GPU 的型号,并应用内置的 GPU 优化参数,目前支持的 GPU 类型有 INVDIA 2080Ti/3080/3090。如果你的 GPU 不在内置的 GPU 型号列表,你需要自己手动传入你的 GPU 优化参数。参数的格式为GPU型号:h_chunk_size:l_chunk_size:h_window_size:l_window_size

一个合法的配置可以是这样:GeForce RTX 3090:34185106:72246808:10:12,通过导出 BELLPERSON_GPU_KERNEL_CONFIG 来传入该参数。不同 GPU 类型的优化参数之间用英文逗号隔开,必须同时打开 BELLPERSON_GPU_CONFIG_OPT 这个参数,优化参数才会生效。

export BELLPERSON_GPU_CONFIG_OPT=true
export BELLPERSON_GPU_KERNEL_CONFIG="GeForce RTX 3090:34185106:72246808:10:12,GeForce RTX 3080:33554466:35554466:8:10"

注意:

470 版本的 GPU 驱动,在 GPU 型号前面需要加上 NVIDIA 前缀:

export BELLPERSON_GPU_CONFIG_OPT=true
export BELLPERSON_GPU_KERNEL_CONFIG="NVIDIA GeForce RTX 3090:123456:123456:12:10"

参数调节的方向是这样的: chunk_size 越大,需要的显存越大,window_size 越大,需要的显存也是增大的。

如果你不知道从哪开始调节的话,可以先跑一个 Lotus-Bench C2 基准测试,程序会在日志中输出默认的参数(高亮行)

2022-03-08T09:42:01.252 INFO bellperson::groth16::prover > YY: start param_h
2022-03-08T09:42:01.252 INFO bellperson::gpu::locks > GPU is available for Multiexp!
2022-03-08T09:42:01.252 INFO bellperson::gpu::locks > GPU group #0 lock acquired!
2022-03-08T09:42:01.252 INFO bellperson::gpu::utils > Adding "GeForce GTX 1660" to GPU list with 1408 CUDA cores.
2022-03-08T09:42:01.252 INFO bellperson::gpu::multiexp > core_count: 1408, mem: 6232014848, n: 2422912, config: h_chunk_size: 2422912, l_chunk_size: 2422912, h_window_size: 10. l_window_size: 10
2022-03-08T09:42:01.252 INFO bellperson::gpu::program > Using kernel on OpenCL.
2022-03-08T09:42:01.349 INFO bellperson::gpu::multiexp > Multiexp: 1 working device(s) selected. (CPU utilization: 0)
2022-03-08T09:42:01.349 INFO bellperson::gpu::multiexp > Multiexp: Device 0: GeForce GTX 1660 (Chunk-size: 2422912)

然后在基准值(默认值)的基础上调节各个参数,然后观察 GPU 资源的消耗情况,然后再调节相应的参数。 建议预留一定的资源来应对生产环境可能出现的资源波动的情况,比如如果你的 GPU 显存只有 8GiB,那么建议把参数调到显存使用在 7GiB 或者 7.5GiB 以内。

原语云的应用中如何使用该功能?

  1. 自动GPU参数优化 设置 true,对应的变量名称为 _env_BELLPERSON_GPU_CONFIG_OPT

  2. 在相应的应用配置里面添加 BELLPERSON_GPU_KERNEL_CONFIG 这个环境变量。这里我们以 lotus-c2-worker 为例,你只切换到应用配置面板,点击 添加配置 按钮,然后填入相关的配置信息,保存就好了。

# 09-扇区文件备份设置

如果你为集群配置了扇区备份功能,那么在扇区 Finalize 之后下载的时候,会同时往备份目录上也下载一份扇区。这个功能在我们 启用时空证明加速 的时候非常有用。

# 1. Miner 落盘配置自动备份

如果你使用的是 Miner 落盘(使用 Miner 把扇区下载到最终存储目录),那么开启备份将会非常简单,只要一条命令就可以解决:

yy_lotus-miner storage set --really-do-it=true  --backup-dir=<BackupDir>  --backup-types=<BackupTypes> <Storage-ID>

参数说明:

  1. backup-dir: 备份路径,这个目录必须存在,并且相应的子目录也要先创建好,假如你的备份目录是 /data01/backup 那么备份目录的文件结构应该是这样的:

    backup # 扇区备份目录
    ├── cache
    ├── sealed
    ├── unsealed
    ├── update
    └── update-cache
    
  2. backup-types: 需要备份的文件类型,不同的文件类型用英文逗号隔开,例如:

    yy_lotus-miner storage set --really-do-it=true --backup-types=cache,update-cache --backup-dir=/data01/backup 408088fc-29ec-4cb9-9480-9539042b658e 
    
  3. 配置完成即刻生效,无需重启 Miner。

# 2. 网关机落盘配置自动备份

  1. 修改 /yuanyu/lotus-storage-worker/data/sectorstore.json 文件,更改备份配置:

    {
    "ID": "0cf821f7-8684-4eaa-a50c-cc7ce10d1641",
    "DeclID": "6a240a06-203d-45af-985b-e16ecdc8239a",
    "BootNoDecl": true,
    "Weight": 10,
    "CanSeal": false,
    "CanStore": true,
    "CanFinal": false,
    "MaxStorage": 0,
    "BackupDir": "/data01/backup", // 设置扇区备份路径
    "BackupTypes": "cache,update-cache" // 设置需要备份哪些类型的文件,不同文件类型用英文逗号隔开
    }
    
  2. 修改完之后需重启 lotus-storage-worker 应用才生效。

# 10-离线时空证明

在运维过程中时空证明出现异常,在完成修复之后通常如果我们要验证修复的操作是否生效,需要等到第二天的时空证明的时候再去观察。如果你是原语云的用户的话,你可以直接手动触发时空证明来验证结果。

对于非原语云用户,我们也提供了一个工具可以让你在本地运行一次离线的时空证明来进行验证,具体操作如下:

  1. 列出你需要做离线时空证明的扇区ID,比如我们从某个存储路径中拿出 1000 个扇区来做离线时空证明测试:
    # /data01/cache,具体执行的时候要替换成你真实的存储路径
    ls -l /data01/cache |awk -F '-' '(NR>2&&NR<1003){print $NF}' > sectors.list
    
  2. 导出时空证明输入参数,通过遍历上述 sectors.list 文件,然后导出扇区的 CommitR:
    # 读取 SectorNumber
    for line in `cat sectors.list`
    do
       # 导出的内容到 `window_post_input.list` 文件
       echo $line,`lotus-miner sectors status $line | awk -F ':' 'NR==3{print $2}'|xargs` >> window_post_input.list
    done
    
    第一列是扇区 ID,后面是对应扇区的 CommitR
    44831,bagboea4b5abcajb37wkcmj6lehowy57oqefcoy22lozquj7p34p7nd2s4f6qes3a
    44320,bagboea4b5abcbeay5clb2vkx6yosnis5b2575rz3xzuroueb5w3ut5p3o3o5dril
    44627,bagboea4b5abcbokg7xhuzburdwpyrhnzvntsgvhpcnlhjszpkedsn5z57yyuy2bt
    44819,bagboea4b5abcbopd555nvahnftvwz7so6toejiu2migl3zi244lqjtpzgrxrg6cp
    44358,bagboea4b5abcbddnlh3eryxsu5hnui7fhedt5542nghj77sz3gjc6vndgsernpdm
    44373,bagboea4b5abcbxlog7h6nwnlbbmavc2lfpijdn3lsj7opppeshibxowdp6kzdgte
    44651,bagboea4b5abcacr3rnxjhjngrmm4whjdm3my3c3fzq3kufmrpax7fdpgpxu5ygkq
    44738,bagboea4b5abcbuwnkzxveovks6ldbq24kro7orfeber4jtml3bfirsxj7fmidgbw
    44396,bagboea4b5abcbv6vtwokojqkun7svk2kpla75cmqdh6ri4tkpa46nvubdpdrxvjs
    44468,bagboea4b5abcb44gneuaurugn3uiolvnhhmdzldxzgmnzfbwsidhfs5c5sf27qlq
    
  3. 下载原语云 lotus-bench 工具
    wget http://mirrors.yyyun.pro/lotus/1.13.2/20220219/amd/lotus-bench
    chmod +x lotus-bench
    
  4. 执行离线时空证明,--storage-dir 表示你做完的 Proving 扇区落盘的目录,--miner-addr 表示 Miner 的账号,需要根据你的实际情况替换。
    export FIL_PROOFS_PARAMETER_CACHE=/yuanyu/filecoin-proof-parameters
    export RUST_LOG=Info
    ./lotus-bench wndpost --storage-dir=/data01 --miner-addr=f0xxx --sector-file=./window_post_input.list > window_post.log 2>&1 &
    
    tail -f window_post.log
    
    如果整个运行过程没有报错,会输出类似的日志信息:
    2021-04-01T16:54:54.798 INFO bellperson::groth16::prover > prover time: 265.771418937s
    2021-04-01T16:54:54.942 INFO storage_proofs_core::compound_proof > snark_proof:finish
    2021-04-01T16:54:54.942 INFO filecoin_proofs::api::post > generate_window_post:finish
    2021-04-01T16:54:55.121 INFO filcrypto::proofs::api > generate_window_post: finish
    2021-04-01T16:54:55.131+0800    ^[[34mINFO^[[0m lotus-bench     lotus-bench/main.go:1375        Done with proof: [{PoStProof:8 ProofBytes:[177 113 254 229 73 129 230 163 58 82 161 139 145 48 125 119 17 32 248 102 25 89 208 1 153 235 91 52 93 191 86 155 188 56 92 9 153 102 220 157 226 214 151 228 189 223 241 10 183 54 205 87 107 218 237 217 230 139 85 56 230 200 20 249 172 252 225 34 174 0 27 211 179 44 57 155 76 118 123 157 50 72 23 232 181 86 161 95 91 151 64 70 160 21 2 105 21 220 154 105 24 47 229 122 142 10 217 140 63 6 200 10 58 90 193 100 196 204 156 220 120 152 118 184 204 255 251 201 133 85 136 86 196 104 163 215 221 204 113 195 195 82 195 221 176 156 159 29 191 228 97 46 248 253 229 163 241 158 224 237 37 8 79 16 205 179 157 214 46 90 248 171 130 138 166 187 109 209 27 190 16 188 247 98 129 192 113 207 148 247 174 10]}], with 0 skips: []
    2021-04-01T16:54:55.132+0800    ^[[34mINFO^[[0m lotus-bench     lotus-bench/main.go:1439        GenerateWindowPoSt Done
    
上次更新: 2022/5/7 12:58:14