如何進(jìn)行kubernetes scheduler基于map/reduce模式實現(xiàn),很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。
創(chuàng)新互聯(lián)是一家專注于成都網(wǎng)站設(shè)計、做網(wǎng)站與策劃設(shè)計,郊區(qū)網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)十多年,網(wǎng)設(shè)計領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:郊區(qū)等地區(qū)。郊區(qū)做網(wǎng)站價格咨詢:18980820575
優(yōu)選階段通過分map/reduce模式來實現(xiàn)多個node和多種算法的并行計算,并且通過基于二級索引來設(shè)計最終的存儲結(jié)果,從而達(dá)到整個計算過程中的無鎖設(shè)計,同時為了保證分配的隨機(jī)性,針對同等優(yōu)先級的采用了隨機(jī)的方式來進(jìn)行最終節(jié)點的分配,如果大家后續(xù)有類似的需求,不妨可以借鑒借鑒
在進(jìn)行優(yōu)選的時候,除了最后一次計算,在進(jìn)行針對單個算法的計算的時候,會分為兩個階段:單點和聚合
在單點階段,會根據(jù)當(dāng)前算法針對單個node計算 在聚合階段,則會根據(jù)當(dāng)前單點階段計算完成后,來進(jìn)行聚合
單點和聚合兩階段在計算的時候,都是并行的,但是對象則不同,其中單點階段并行是針對單個node的計算,而聚合階段則是針對算法級別的計算,通過這種設(shè)計分離計算,從而避免多goroutine之間數(shù)據(jù)競爭,無鎖加速優(yōu)選的計算
而map與reduce則是針對一個上面并行的兩種具體實現(xiàn),其中map中負(fù)責(zé)單node打分,而reduce則是針對map階段的打分進(jìn)行聚合后,根據(jù)匯總的結(jié)果進(jìn)行二次打分計算
map/reduce階段都是通過算法計算,如果我們要進(jìn)行自定義的調(diào)整,針對單個算法,我們可以調(diào)整其在預(yù)選流程中的權(quán)重,從而進(jìn)行定制自己的預(yù)選流程
當(dāng)進(jìn)行優(yōu)先級判斷的時候,肯定會出現(xiàn)多個node優(yōu)先級相同的情況,在優(yōu)選節(jié)點的時候,會進(jìn)行隨機(jī)計算,從而決定是否用當(dāng)前優(yōu)先級相同的node替換之前的最合適的node
優(yōu)選的核心流程主要是在PrioritizeNodes中,這里只介紹其關(guān)鍵的核心數(shù)據(jù)結(jié)構(gòu)設(shè)計
無鎖計算結(jié)果的保存主要是通過下面的二維數(shù)組實現(xiàn), 如果要存儲一個算法針對某個node的結(jié)果,其實只需要通過兩個索引即可:算法索引和節(jié)點索引,同理如果我吧針對單個node的索引分配給一個goroutine,則其去其他的goroutine則就可以并行計算
// 在計算的時候,會傳入nodes []*v1.Node的數(shù)組,存儲所有的節(jié)點,節(jié)點索引主要是指的該部分 results := make([]schedulerapi.HostPriorityList, len(priorityConfigs), len(priorityConfigs))
之前在預(yù)選階段介紹過ParallelizeUntil函數(shù)的實現(xiàn),其根據(jù)傳入的數(shù)量來生成計算索引,放入chan中,后續(xù)多個goroutine從chan中取出數(shù)據(jù)直接進(jìn)行計算即可
workqueue.ParallelizeUntil(context.TODO(), 16, len(nodes), func(index int) { // 根據(jù)節(jié)點和配置的算法進(jìn)行計算 nodeInfo := nodeNameToInfo[nodes[index].Name] // 獲取算法的索引 for i := range priorityConfigs { if priorityConfigs[i].Function != nil { continue } var err error // 通過節(jié)點索引,來進(jìn)行針對單個node的計算結(jié)果的保存 results[i][index], err = priorityConfigs[i].Map(pod, meta, nodeInfo) if err != nil { appendError(err) results[i][index].Host = nodes[index].Name } } })
基于算法的并行,則是為每個算法的計算都啟動一個goroutine,每個goroutine通過算法索引來進(jìn)行該算法的所有map階段的結(jié)果的讀取,并進(jìn)行計算,后續(xù)結(jié)果仍然存儲在對應(yīng)的位置
// 計算策略的分值 for i := range priorityConfigs { if priorityConfigs[i].Reduce == nil { continue } wg.Add(1) go func(index int) { defer wg.Done() if err := priorityConfigs[index].Reduce(pod, meta, nodeNameToInfo, results[index]); err != nil { appendError(err) } if klog.V(10) { for _, hostPriority := range results[index] { klog.Infof("%v -> %v: %v, Score: (%d)", util.GetPodFullName(pod), hostPriority.Host, priorityConfigs[index].Name, hostPriority.Score) } } }(i) } // Wait for all computations to be finished. wg.Wait()
根據(jù)之前的map/reduce階段,接下來就是將針對所有node的所有算法計算結(jié)果進(jìn)行累加即可
// Summarize all scores. result := make(schedulerapi.HostPriorityList, 0, len(nodes)) for i := range nodes { result = append(result, schedulerapi.HostPriority{Host: nodes[i].Name, Score: 0}) // 便利所有的算法配置 for j := range priorityConfigs { result[i].Score += results[j][i].Score * priorityConfigs[j].Weight } for j := range scoresMap { result[i].Score += scoresMap[j][i].Score } }
這里的隨機(jī)篩選是指的當(dāng)多個host優(yōu)先級相同的時候,會有一定的概率用當(dāng)前的node替換之前的優(yōu)先級相等的node(到目前為止的優(yōu)先級最高的node), 其主要通過cntOfMaxScore和rand.Intn(cntOfMaxScore)來進(jìn)行實現(xiàn)
func (g *genericScheduler) selectHost(priorityList schedulerapi.HostPriorityList) (string, error) { if len(priorityList) == 0 { return "", fmt.Errorf("empty priorityList") } maxScore := priorityList[0].Score selected := priorityList[0].Host cntOfMaxScore := 1 for _, hp := range priorityList[1:] { if hp.Score > maxScore { maxScore = hp.Score selected = hp.Host cntOfMaxScore = 1 } else if hp.Score == maxScore { cntOfMaxScore++ if rand.Intn(cntOfMaxScore) == 0 { // Replace the candidate with probability of 1/cntOfMaxScore selected = hp.Host } } } return selected, nil }
優(yōu)選階段通過分map/reduce模式來實現(xiàn)多個node和多種算法的并行計算,并且通過基于二級索引來設(shè)計最終的存儲結(jié)果,從而達(dá)到整個計算過程中的無鎖設(shè)計,同時為了保證分配的隨機(jī)性,針對同等優(yōu)先級的采用了隨機(jī)的方式來進(jìn)行最終節(jié)點的分配,如果大家后續(xù)有類似的需求,不妨可以借鑒借鑒
看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對創(chuàng)新互聯(lián)的支持。