【教程】lotus 是怎么调度任务的? #69
Replies: 12 comments 5 replies
-
是否可并行完全写反了吧。 |
Beta Was this translation helpful? Give feedback.
-
调度流程之前也研究过,大致是走马观花的看了一遍。弄清楚了流转逻辑,但是从来没想过和楼主一样深入了解和分享出来。看来我该反思下自己了。像楼主学习 |
Beta Was this translation helpful? Give feedback.
-
请问一下,二维数组,一维和二维是否反了呢 |
Beta Was this translation helpful? Give feedback.
-
RRMine,雅典娜矿池,全网算力领先1000PB,需要B端C端方案的滴滴我,交流学习,欢迎加入社群Wechet:kkmmjjnn00 |
Beta Was this translation helpful? Give feedback.
-
江浙沪区域需要封装FIl算里的,租赁worker的联系我 15088695255同V |
Beta Was this translation helpful? Give feedback.
-
非常棒,楼主专业!希望以后能发表更多精彩内容 |
Beta Was this translation helpful? Give feedback.
-
FIL联合封装,用户提供质押币,公司提供设备和运维,收益60%,公司扣出20%服务费和20%设备费,合同期1080天,540天质押币退还,t3天封装。可实地考察。V:zhaobo9308,另接代封装业务,价格美丽 |
Beta Was this translation helpful? Give feedback.
-
要定制自己的调度方案,首先需要了解清楚 lotus 的任务调度机制,本文就先从原理上介绍下 lotus 调度任务的机制,方便大家结合代码更好的理解调度逻辑。
1. lotus 任务调度要解决的主要问题
通过阅读 lotus 调度相关的代码发现,lotus 的调度任务实现得比较复杂,使用了十几个数据结构,代码也分布在数十个文件中,做这么多工作,当然有它的原因,它想要解决的主要问题包括:
实现任务绑定配置化。通过启动参数,可以灵活配置 worker 执行的任务种类,方便矿工进行灵活的集群架构调整,并实现集群机器数量的伸缩性;
根据硬件资源分发任务。不同配置的 worker 能够并行执行的任务数量也不相同,超过硬件承受能力的任务分配会导致硬件资源争用,进而导致任务执行时间直线下降。同时要均匀分配负载,不能让忙的忙死,闲的闲死;
兼容各种异常情况。例如当发生 worker 或 miner 突然掉线、网络不畅、存储空间不足等情况时,要能够保证异常状态的任务不会陷入死循环中,能够在合适的时间重启或继续,并且不影响正常状态任务的执行。
在实际使用中发现,尽管第二和第三个问题解决的不尽完美,但当前的方案已经基本适应了大多数场景。
2. 调度核心流程
如上图所示:
以 AP 任务为例,具体的调用时序图如下:
3. 基本数据结构
图中红色部分负责核心调度,绿色为资源管理,灰色负责状态同步记录。
核心数据结构包括:
• scheduler:调度器,负责在 miner 上统筹调度所有task及worker。核心调度方法是 trySched()
• workerHandle: worker 的抽象,记录 worker 基本信息、当前资源使用、worker 的任务 window 等
• workerRequest: task 的抽象,记录任务类型、优先级以及任务的具体执行内容等
• activeResources: 正在使用的资源
• workerResources: worker 总的资源
4. 扇区状态流转
扇区的某个任务执行完成后,会通过一个有限状态机来更新任务状态,并将自动添加下一步任务给到 scheduler 中。有限状态机的代码位于:
extern/storage-sealing/fsm.go
,具体状态机见代码注释,如下:了解到这个状态变化,结合
lotus-miner sectors list
和lotus-miner sectors status --log sector_id
就可以定位扇区异常状态及能否恢复了。5. 举个定制的例子
了解了上面这些,结合代码,基本上就可以按照自己的需求修改代码了,下面举一个简单的例子。
假设我们想要手工限制某台机器 P1 任务的执行数量为 N,结合上面的调度流程,我们只需要修改下调度过程中workerRequest 与 workerHandle 的匹配流程。实现思路就是在匹配的时候,将当前 worker 正在执行的 P1 任务数量与预先设置的阈值 N 进行比较,若大于等于 N,则不再调度给该 worker。那么, 要在哪里添加这部分逻辑呢?
首先需要了解清楚调度的核心代码。这部分代码位于 extern/sector-storage/sched.go 的 trySched()方法中,代码中有一些我补充的中文注释,便于理解:
可以看到,当 windows[wnd].allocated.canHandleRequest(needRes, wid, "schedAssign", wr)返回 false 的时候,task 就不会被分配给该 window 执行。所以,可以考虑将限制逻辑写入 canHandleRequest方法中就可以了。
6. 总结
lotus 调度任务的整体逻辑基本还是遵循生产者-消费者模型,通过对 worker、task 的抽象,结合预配置、资源情况、优先级等因素进行调度,并通过一个有限状态机控制状态流转。
7. 参考资料
[1] https://github.com/filecoin-project/lotus (tag v1.5.0):看了下 v1.6.0 的代码,调度部分代码变化不大
[2] Filecoin Mining Workshop - Filecoin Mining: A Deep Dive[24:40 ~ 31:05]: 核心开发者的视频,英语口音有点重,需要仔细听
[3] 《lotus 官方调度》
8. 最后
欢迎有问题或想合作的朋友加我微信好友一起探讨。同时,我们现在正在招聘早期员工,工作地点在杭州 & 南京,需要 linux 运维、 go/rust 开发、行政及采购,唯一的要求就是人靠谱。纯技术氛围,现金流充裕,欢迎来撩~
另外,硬件渠道还有少量库存,需要采购零件/整机的朋友,也可以联系我们:
Beta Was this translation helpful? Give feedback.
All reactions