背景
1.34后引入了SizeBasedListCostEstimate特性,用于评估List请求的开销,针对内存开销判断list请求开销.在此之前都是基于对象数量进行list请求开销评估.
源码
staging/src/k8s.io/apiserver/pkg/util/flowcontrol/request/list_work_estimator.go中
func (e *listWorkEstimator) estimate(r *http.Request, flowSchemaName, priorityLevelName string) WorkEstimate {
...
var seats uint64
if utilfeature.DefaultFeatureGate.Enabled(features.SizeBasedListCostEstimate) {
seats = e.seatsBasedOnObjectSize(stats, listOptions, isListFromCache, matchesSingle)
} else {
seats = e.seatsBasedOnObjectCount(stats, listOptions, isListFromCache, matchesSingle)
}
...
}
根据对象大小评估开销
func (e *listWorkEstimator) seatsBasedOnObjectSize(stats storage.Stats, listOptions metav1.ListOptions, isListFromCache bool, matchesSingle bool) uint64 {
...
如果objectcount非0但是EstimatedAverageObjectSizeBytes为0则使用seatsBasedOnObjectCount处理
if stats.EstimatedAverageObjectSizeBytes <= 0 && stats.ObjectCount != 0 {
return e.seatsBasedOnObjectCount(stats, listOptions, isListFromCache, matchesSingle)
}
...
加载到内存中的对象数量*每个对象的大小
memoryUsedAtOnce := objectsLoadedInMemory * stats.EstimatedAverageObjectSizeBytes
if isListFromCache {
取memoryUsedAtOnce和1_000_000最小的值
memoryUsedAtOnce = min(memoryUsedAtOnce, cacheWithStreamingMaxMemoryUsage)
}
memoryUsedAtOnce/100_000
return uint64(math.Ceil(float64(memoryUsedAtOnce) / bytesPerSeat))
}
根据对象数量评估开销
func (e *listWorkEstimator) seatsBasedOnObjectCount(stats storage.Stats, listOptions metav1.ListOptions, isListFromCache bool, matchesSingle bool) uint64 {
...
对象数据* 每个对象的开销(固定配置,为100)
return uint64(math.Ceil(float64(estimatedObjectsToBeProcessed) / e.config.ObjectsPerSeat))
}