介绍
首先我们来了解下Cache的作用:收集pod信息,并提供节点级的聚合信息。其设计目标是为通用调度器提供高效查询。Cache的操作是以pod为中心的,能够基于pod的事件进行增量更新。但是由于事件是通过网络发送的,无法保证所有事件都能够传递,因为使用了Reflector进行list和watch操作,可能会由于延迟或relist出现事件丢失的情况。具体参考pkg/scheduler/internal/cache/interface.go中的说明。
在Cache中有有一个assume的概念,其含义为假定、假设,代表了调度器认为这个pod是已调度状态,这个是在scheduleCycle找到合适的节点之后设置的,但是此时还没有调用bind操作将其绑定到具体的节点上,在运行完绑定之后会将其从assumedPods中移除。由于bind的是异步执行的,所以调度器在启动这个协程之后会开始一个新的调度周期来调度下一个pod,在计算已用资源时,是会包含在assume集合中的pod的。
Cache中的数据时基于事件触发添加和更新的,因此为了保证在一个调度周期执行过程中,用到的数据不会发生变化,保证数据的一致性,scheduler在调度开始会使用当前Cache生成一个节点信息的快照,后续会用这个快照进行计算。
接口
下面首先看下Cache的接口定义,了解一下有哪些方法:
type Cache interface {
// 节点数量
// 测试用
NodeCount() int
// pod数量
// 测试用
PodCount() (int, error)
// 假设pod已调度,并聚合pod的信息到其对应的节点上,加入到assumedPods。
// 调度框架使用
AssumePod(pod *v1.Pod) error
// 完成绑定,设置assumedPod过期时间,后面在执行清理时会在assumedPods中删掉。
// 调度框架使用
FinishBinding(pod *v1.Pod) error
// 删除assumedPod。
// 调度框架使用
ForgetPod(pod *v1.Pod) error
// 添加pod,如果是assumedPod,则会执行确认逻辑,否则则是过期的pod,将其加入到缓存。
// 已调度pod informer使用
AddPod(pod *v1.Pod) error
// 更新pod信息
// 已调度pod informer使用
UpdatePod(oldPod, newPod *v1.Pod) error
// 从缓存中删除pod
// 已调度pod informer使用
RemovePod(pod *v1.Pod) error
//…