Koordinator-Predict

创建predictServer

predictServer := prediction.NewPeakPredictServer(config.PredictionConf)
predictorFactory := prediction.NewPredictorFactory(predictServer, config.PredictionConf.ColdStartDuration, config.PredictionConf.SafetyMarginPercent)

看下NewPeakPredictServer方法。

  • 设置cfg
  • 初始化uidGenerator、PredictModelMap、checkPointer
func NewPeakPredictServer(cfg *Config) PredictServer {
    return &peakPredictServer{
        cfg:          cfg,
        uidGenerator: &generator{},
        models:       make(map[UIDType]*PredictModel),
        clock:        clock.RealClock{},
        hasSynced:    &atomic.Bool{},
        checkpointer: NewFileCheckpointer(cfg.CheckpointFilepath),
    }
}

NewPredictorFactory

简单设置属性

func NewPredictorFactory(predictServer PredictServer, coldStartDuration time.Duration, safetyMarginPercent int) PredictorFactory {
    return &predictorFactory{
        predictServer:       predictServer,
        coldStartDuration:   coldStartDuration,
        safetyMarginPercent: safetyMarginPercent,
    }
}

predict.Config

type Config struct {
	CheckpointFilepath           string
	ColdStartDuration            time.Duration
	SafetyMarginPercent          int
	MemoryHistogramDecayHalfLife time.Duration
	CPUHistogramDecayHalfLife    time.Duration
	TrainingInterval             time.Duration
	ModelExpirationDuration      time.Duration
	ModelCheckpointInterval      time.Duration
	ModelCheckpointMaxPerStep    int
}

启动predictServer

// start predict server
    go func() {
        if err := d.predictServer.Setup(d.statesInformer, d.metricCache); err != nil {
            klog.Fatal("Unable to setup the predict server: ", err)
        }
        if err := d.predictServer.Run(stopCh); err != nil {
            klog.Fatal("Unable to run the predict server: ", err)
        }
    }()

Run()

  • 重置模型数据
  • metric模型训练,1min一次
  • 清理过期metric,1min一次
  • checkpoint,1min一次
func (p *peakPredictServer) Run(stopCh <-chan struct{}) error {
    if !cache.WaitForCacheSync(stopCh, p.informer.HasSynced) {
       return fmt.Errorf("time out waiting for states informer caches to sync")
    }
    unknownUIDs := p.restoreModels()
    // remove unknown checkpoints before starting to work
    for _, uid := range unknownUIDs {
       err := p.checkpointer.Remove(uid)
       klog.InfoS("remove unknown checkpoint", "uid", uid)
       if err != nil {
          klog.Errorf("remove checkpoint %v failed, err: %v", uid, err)
       }
    }
    go wait.Until(p.training, p.cfg.TrainingInterval, stopCh)
    go wait.Until(p.gcModels, time.Minute, stopCh)
    go wait.Until(p.doCheckpoint, time.Minute, stopCh)
    <-stopCh
    return nil
}

training()

  • 遍历所有容器

    • 获取容器最近cpu/mem使用率,更新容器id model。
  • 获取node最近cpu/mem使用率,更新nodeid model。

  • 更新node priority class model

  • 更新system model

func (p *peakPredictServer) training() {
    // get pod metrics
    // 1. list pods, update models
    pods := p.informer.ListPods()
    // count the node-level usages of different priority classes and system
    nodeItemsMetric := NewNodeItemUsage()
    for _, pod := range pods {
       uid := p.uidGenerator.Pod(pod)
       lastCPUUsage, err := p.metricServer.GetPodMetric(MetricDesc{UID: uid}, CPUUsage)
       if err != nil {
          klog.Warningf("failed to query pod cpu metric, pod %s, err: %s", util.GetPodKey(pod), err)
          continue
       }
       lastMemoryUsage, err := p.metricServer.GetPodMetric(MetricDesc{UID: uid}, MemoryUsage)
       if err != nil {
          klog.Warningf("failed to query pod memory metric, pod %s, err: %s", util.GetPodKey(pod), err)
          continue
       }
       // update the pod model
       p.updateModel(uid, lastCPUUsage, lastMemoryUsage)
       // update the node priority metric
       priorityItemID := string(extension.GetPodPriorityClassWithDefault(pod))
       nodeItemsMetric.AddMetric(priorityItemID, lastCPUUsage, lastMemoryUsage)
       // count all pods metric
       nodeItemsMetric.AddMetric(AllPodsItemID, lastCPUUsage, lastMemoryUsage)
    }


    // 2. get node, update models
    nodeUID := p.uidGenerator.Node()
    lastNodeCPUUsage, errCPU := p.metricServer.GetNodeMetric(MetricDesc{UID: nodeUID}, CPUUsage)
    lastNodeMemoryUsage, errMem := p.metricServer.GetNodeMetric(MetricDesc{UID: nodeUID}, MemoryUsage)
    if errCPU != nil || errMem != nil {
       klog.Warningf("failed to query node cpu and memory metric, CPU err: %s, Memory err: %s", errCPU, errMem)
    } else {
       p.updateModel(nodeUID, lastNodeCPUUsage, lastNodeMemoryUsage)
    }


    // 3. update node priority models
    for _, priorityClass := range extension.KnownPriorityClasses {
       itemID := string(priorityClass)
       priorityUID := p.uidGenerator.NodeItem(itemID)
       metric, ok := nodeItemsMetric.GetMetric(itemID)
       if ok {
          p.updateModel(priorityUID, metric.LastCPUUsage, metric.LastMemoryUsage)
       } else {
          // reset the priority usage
          p.updateModel(priorityUID, 0, 0)
       }
    }


    // 4. update system model
    sysCPUUsage := lastNodeCPUUsage
    sysMemoryUsage := lastNodeMemoryUsage
    allPodsMetric, ok := nodeItemsMetric.GetMetric(AllPodsItemID)
    if ok {
       sysCPUUsage = math.Max(sysCPUUsage-allPodsMetric.LastCPUUsage, 0)
       sysMemoryUsage = math.Max(sysMemoryUsage-allPodsMetric.LastMemoryUsage, 0)
    }
    systemUID := p.uidGenerator.NodeItem(SystemItemID)
    p.updateModel(systemUID, sysCPUUsage, sysMemoryUsage)


    p.hasSynced.Store(true)
}

updateModel()

不存在对应model则设置一下model,调用AddSample()

func (p *peakPredictServer) updateModel(uid UIDType, cpu, memory float64) {
    p.modelsLock.Lock()
    defer p.modelsLock.Unlock()
    model, ok := p.models[uid]
    if !ok {
        model = &PredictModel{
            CPU:    p.defaultCPUHistogram(),
            Memory: p.defaultMemoryHistogram(),
        }
        p.models[uid] = model
    }
    now := p.clock.Now()
    model.Lock.Lock()
    defer model.Lock.Unlock()
    model.LastUpdated = now
    // TODO Add adjusted weights
    model.CPU.AddSample(cpu, 1, now)
    model.Memory.AddSample(memory, 1, now)
}

gcModels()

清理过期model

  • 遍历所有的model,若上次更新信息大于配置的过期时长,则删除。

    • 同时删除对应checkpointer中的model
func (p *peakPredictServer) gcModels() {
    if !p.HasSynced() {
        klog.Infof("wait for the state to be synchronized, skipping the step of model GC")
        return
    }
    tobeRemovedModels := make([]UIDType, 0)
    p.modelsLock.Lock()
    for uid, model := range p.models {
        if p.clock.Since(model.LastUpdated) > p.cfg.ModelExpirationDuration {
            delete(p.models, uid)
            klog.InfoS("gc model", "uid", uid)
            tobeRemovedModels = append(tobeRemovedModels, uid)
        }
    }
    p.modelsLock.Unlock()
    // do the io operations out of lock
    for _, uid := range tobeRemovedModels {
        err := p.checkpointer.Remove(uid)
        klog.InfoS("remove checkpoint", "uid", uid)
        if err != nil {
            klog.Errorf("remove checkpoint %v failed, err: %v", uid, err)
        }
    }
}

doCheckpoint()

  • 遍历所有的model

    • 按key:model进行pair组装,然后对上次checkpoint时间进行排序。
  • 遍历所有的pair,最大检查个数和间隔时间判断下,然后调用model的SaveToCheckpointer方法。

func (p *peakPredictServer) doCheckpoint() {
    if !p.HasSynced() {
        klog.Infof("wait for the state to be synchronized, skipping the step of model GC")
        return
    }
    type pair struct {
        UID   UIDType
        Model *PredictModel
    }
    p.modelsLock.Lock()
    pairs := make([]pair, 0, len(p.models))
    for key, model := range p.models {
        pairs = append(pairs, pair{UID: key, Model: model})
    }
    p.modelsLock.Unlock()
    // Sort models and keys by LastCheckpointed time
    sort.Slice(pairs, func(i, j int) bool {
        return pairs[i].Model.LastCheckpointed.Before(pairs[j].Model.LastCheckpointed)
    })
    checkpointModelsCount := 0
    for _, pair := range pairs {
        if checkpointModelsCount >= p.cfg.ModelCheckpointMaxPerStep {
            break
        }
        if p.clock.Since(pair.Model.LastCheckpointed) < p.cfg.ModelCheckpointInterval {
            break
        }
        ckpt := ModelCheckpoint{
            UID:         pair.UID,
            LastUpdated: metav1.NewTime(p.clock.Now()),
        }
        pair.Model.Lock.Lock()
        ckpt.CPU, _ = pair.Model.CPU.SaveToCheckpoint()
        ckpt.Memory, _ = pair.Model.Memory.SaveToCheckpoint()
        pair.Model.Lock.Unlock()
        err := p.checkpointer.Save(ckpt)
        if err != nil {
            klog.Errorf("save checkpoint uid %v failed, err: %s", pair.UID, err)
        } else {
            klog.InfoS("save checkpoint", "uid", pair.UID)
        }
        pair.Model.LastCheckpointed = p.clock.Now()
        checkpointModelsCount++
    }
}

SaveToCheckpoint()

func (h *histogram) SaveToCheckpoint() (*HistogramCheckpoint, error) {
	result := HistogramCheckpoint{
		BucketWeights: make(map[int]uint32),
	}
	result.TotalWeight = h.totalWeight
	// Find max
	max := 0.
	for bucket := h.minBucket; bucket <= h.maxBucket; bucket++ {
		if h.bucketWeight[bucket] > max {
			max = h.bucketWeight[bucket]
		}
	}
	// Compute ratio
	ratio := float64(MaxCheckpointWeight) / max
	// Convert weights and drop near-zero weights
	for bucket := h.minBucket; bucket <= h.maxBucket; bucket++ {
		newWeight := uint32(round(h.bucketWeight[bucket] * ratio))
		if newWeight > 0 {
			result.BucketWeights[bucket] = newWeight
		}
	}

	return &result, nil
}

目前只看到了怎样把数据放入到model中,还没有看到怎样去使用model数据。

接下来去找下哪里使用了model。

源码来自:https://pan.quark.cn/s/7a757c0c80ca 《在Neovim中运用Lua的详尽教程》在当代文本编辑器领域,Neovim凭借其卓越的性能、可扩展性以及高度可定制的特点,赢得了程序开发者的广泛青睐。 其中,Lua语言的融入更是为Neovim注入了强大的活力。 本指南将深入剖析如何在Neovim中高效地运用Lua进行配置和插件开发,助你充分发挥这一先进功能的潜力。 一、Lua为何成为Neovim的优选方案经典的Vim脚本语言(Vimscript)虽然功能完备,但其语法结构与现代化编程语言相比显得较为复杂。 与此形成对比的是,Lua是一种精简、轻量且性能卓越的脚本语言,具备易于掌握、易于集成的特点。 因此,Neovim选择Lua作为其核心扩展语言,使得配置和插件开发过程变得更加直观和便捷。 二、安装与设置在Neovim中启用Lua支持通常十分简便,因为Lua是Neovim的固有组件。 然而,为了获得最佳体验,我们建议升级至Neovim的最新版本。 可以通过`vim-plug`或`dein.vim`等包管理工具来安装和管理Lua插件。 三、Lua基础在着手编写Neovim的Lua配置之前,需要对Lua语言的基础语法有所掌握。 Lua支持变量、函数、控制流、表(类似于数组和键值对映射)等核心概念。 它的语法设计简洁明了,便于理解和应用。 例如,定义一个变量并赋值:```lualocal myVariable = "Hello, Neovim!"```四、Lua在Neovim中的实际应用1. 配置文件:Neovim的初始化文件`.vimrc`能够完全采用Lua语言编写,只需在文件首声明`set runtimepath^=~/.config/nvim ini...
基于STM32 F4的永磁同步电机无位置传感器控制策略研究内容概要:本文围绕基于STM32 F4的永磁同步电机(PMSM)无位置传感器控制策略展开研究,重点探讨在不使用机械式位置传感器的情况下,如何通过算法实现对电机转子位置和速度的精确估算与控制。文中结合STM32 F4高性能微控制器平台,采用如滑模观测器(SMO)、扩展卡尔曼滤波(EKF)或高频注入法等先进观测技术,实现对电机反电动势或磁链的实时估算,进而完成磁场定向控制(FOC)。研究涵盖了控制算法设计、系统建模、仿真验证(可能使用Simulink)以及在嵌入式平台上的代码实现与实验测试,旨在提高电机驱动系统的可靠性、降低成本并增强环境适应性。; 适合人群:具备一定电机控制理论基础和嵌入式开发经验的电气工程、自动化及相关专业的研究生、科研人员及从事电机驱动开发的工程师;熟悉C语言和MATLAB/Simulink工具者更佳。; 使用场景及目标:①为永磁同步电机驱动系统在高端制造、新能源汽车、家用电器等领域提供无位置传感器解决方案的设计参考;②指导开发者在STM32平台上实现高性能FOC控制算法,掌握位置观测器的设计与调试方法;③推动电机控制技术向低成本、高可靠方向发展。; 其他说明:该研究强调理论与实践结合,不仅包含算法仿真,还涉及实际硬件平台的署与测试,建议读者在学习过程中配合使用STM32开发板和PMSM电机进行实操验证,以深入理解控制策略的动态响应与鲁棒性问题。
先看效果: https://pan.quark.cn/s/21391ce66e01 企业级办公自动化系统,一般被称为OA(Office Automation)系统,是企业数字化进程中的关键构成分,旨在增强组织内的工作效能与协同水平。 本资源提供的企业级办公自动化系统包含了详尽的C#源代码,涉及多个技术领域,对于软件开发者而言是一份极具价值的参考资料。 接下来将具体介绍OA系统的核心特性、关键技术以及在实践操作中可能涉及的技术要点。 1. **系统构造** - **三层构造**:大型OA系统普遍采用典型的三层构造,包含表现层、业务逻辑层和数据访问层。 这种构造能够有效分离用户交互界面、业务处理过程和数据存储功能,从而提升系统的可维护性与可扩展性。 2. **C#编程语言** - **C#核心**:作为开发语言,C#具备丰富的类库和语法功能,支持面向对象编程,适用于开发复杂的企业级应用。 - **.NET Framework**:C#在.NET Framework环境中运行,该框架提供了大量的类库与服务,例如ASP.NET用于Web开发,Windows Forms用于桌面应用。 3. **控件应用** - **WinForms**或**WPF**:在客户端,可能会使用WinForms或WPF来设计用户界面,这两者提供了丰富的控件和可视化设计工具。 - **ASP.NET Web Forms/MVC**:对于Web应用,可能会使用ASP.NET的Web Forms或MVC模式来构建交互式页面。 4. **数据库操作** - **SQL Server**:大型OA系统通常采用关系型数据库管理系统,如SQL Server,用于存储和处理大量数据。 - **ORM框架**:如Ent...
下载前必看:https://pan.quark.cn/s/ac7b3acb6cfd 《模拟人才招聘选拔群体决策支持系统》是一款为人力资源门量身打造的高级软件应用,它融合了人工智能技术、大数据分析方法以及多方位评估手段,致力于改善招聘流程,增强人才选择的精准度与工作效率。 该系统通过构建逼真的人才招聘情境,引导决策者在繁杂的信息体系中做出更为理性的判断。 在人才选拔阶段,系统借助大数据分析手段对海量的个人简历进行有效甄别,迅速锁定与岗位特征相符的应聘者。 其能够依据事先定义的职位规范,自动对接应聘者的学历层次、职业履历、能力专长等资料,显著降低了人工审查的时间投入。 与此同时,该系统拥有智能评估模块,能够对候选人的个性特征、发展潜能及团队协作素养等非量化指标进行数值化衡量。 经由心理测试、网络面试等途径获取的数据,将运用机器学习模型展开深度解析,从而构建详尽的应聘者能力剖析报告,助力招聘人员全面把握候选人的综合条件。 再者,模拟人才招聘选拔群体决策支持系统支持多方用户协同运作。 在集体决策场景下,各位评审专家可独立对候选人作出评价,系统将汇总所有评审意见,转化为群体抉择的参考蓝本。 此类集体决策架构有助于削减个体主观倾向,提升决策的公平性与可靠性。 系统还配备了卓越的数据报表系统,能够输出多样化的招聘数据统计,例如求职者数量、面试合格率、新员工维系比率等,为企业实时呈现人力资源现状,有利于管理层制定更为得当的招募方针。 在实践操作层面,模拟人才招聘选拔群体决策支持系统不仅有助于提升招聘效能,压缩招聘开销,更能协助企业发掘潜在的高素质人才,为机构的长远进步注入动力。 然而,在运用此类系统时亦需关注应聘者隐私权保护,确保信息安全性,并融合人工评判,防止技术过度依赖,维持人性化招聘的基本...
### Koordinator 跨云管理 Kubernetes 集群的支持性 Koordinator 是一个专注于合工作负载调度的系统,其设计目标是提升延迟敏感型工作负载和批处理作业的运行效率与可靠性,同时通过资源超卖和技术提高集群资源利用率[^2]。然而,关于 Koordinator 是否支持跨云管理 Kubernetes 集群的问题,目前官方文档和已知信息中并未明确提及此类功能。 从架构角度来看,Koordinator 的核心功能集中在单个或多个同构集群内的资源调度与管理,例如支持 K8s 与 YARN 、资源精细化管理以及通过 QoS 提升任务运行效率[^1]。这些特性主要面向同一基础设施下的多租户环境,并未直接涉及跨不同云供应商的 Kubernetes 集群管理。 在跨云管理方面,通常需要依赖于更高层次的多集群管理工具或框架,例如 Kubernetes 原生的 Cluster API、Kubefed(Kubernetes Federation),或者第三方解决方案如 Rancher、Anthos 等。这些工具提供了对分布在不同云环境中的 Kubernetes 集群进行统一管理和调度的能力。如果 Koordinator 要实现跨云管理,理论上需要与上述工具集成,或者扩展其自身功能以支持多云环境下的集群发现、资源协调和任务调度。 此外,尽管 Koordinator 本身可能不直接支持跨云管理,但其设计理念和模块化架构为未来扩展此类功能提供了可能性。例如,通过引入外调度插件或与多集群管理平台结合,Koordinator 可能能够间接支持跨云场景下的资源调度[^3]。 ```python # 示例:假设 Koordinator 集成多集群管理功能后的伪代码 from koordinator import Scheduler, MultiClusterManager def cross_cloud_scheduling(clusters: list, workload: dict): manager = MultiClusterManager(clusters) scheduler = Scheduler(manager) return scheduler.schedule(workload) ``` ### 相关问题
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值