Kaynağa Gözat

Compute efficiency on the fly

Niko Kovacevic 5 yıl önce
ebeveyn
işleme
b0891e2eac

+ 17 - 17
pkg/costmodel/allocation.go

@@ -402,23 +402,23 @@ func (cm *CostModel) ComputeAllocation(start, end time.Time) (*kubecost.Allocati
 		alloc.TotalCost += alloc.SharedCost
 		alloc.TotalCost += alloc.ExternalCost
 
-		if alloc.RAMBytesRequestAverage > 0 {
-			alloc.RAMEfficiency = alloc.RAMBytesUsageAverage / alloc.RAMBytesRequestAverage
-		} else {
-			alloc.RAMEfficiency = 1.0
-		}
-
-		if alloc.CPUCoreRequestAverage > 0 {
-			alloc.CPUEfficiency = alloc.CPUCoreUsageAverage / alloc.CPUCoreRequestAverage
-		} else {
-			alloc.CPUEfficiency = 1.0
-		}
-
-		if alloc.CPUCost+alloc.RAMCost > 0 {
-			ramCostEff := alloc.RAMEfficiency * alloc.RAMCost
-			cpuCostEff := alloc.CPUEfficiency * alloc.CPUCost
-			alloc.TotalEfficiency = (ramCostEff + cpuCostEff) / (alloc.CPUCost + alloc.RAMCost)
-		}
+		// if alloc.RAMBytesRequestAverage > 0 {
+		// 	alloc.RAMEfficiency = alloc.RAMBytesUsageAverage / alloc.RAMBytesRequestAverage
+		// } else {
+		// 	alloc.RAMEfficiency = 1.0
+		// }
+
+		// if alloc.CPUCoreRequestAverage > 0 {
+		// 	alloc.CPUEfficiency = alloc.CPUCoreUsageAverage / alloc.CPUCoreRequestAverage
+		// } else {
+		// 	alloc.CPUEfficiency = 1.0
+		// }
+
+		// if alloc.CPUCost+alloc.RAMCost > 0 {
+		// 	ramCostEff := alloc.RAMEfficiency * alloc.RAMCost
+		// 	cpuCostEff := alloc.CPUEfficiency * alloc.CPUCost
+		// 	alloc.TotalEfficiency = (ramCostEff + cpuCostEff) / (alloc.CPUCost + alloc.RAMCost)
+		// }
 
 		// Make sure that the name is correct (node may not be present at this
 		// point due to it missing from queryMinutes) then insert.

+ 29 - 53
pkg/kubecost/allocation.go

@@ -57,7 +57,6 @@ type Allocation struct {
 	CPUCoreRequestAverage  float64    `json:"cpuCoreRequestAverage"`
 	CPUCoreUsageAverage    float64    `json:"cpuCoreUsageAverage"`
 	CPUCost                float64    `json:"cpuCost"`
-	CPUEfficiency          float64    `json:"cpuEfficiency"`
 	GPUHours               float64    `json:"gpuHours"`
 	GPUCost                float64    `json:"gpuCost"`
 	NetworkCost            float64    `json:"networkCost"`
@@ -67,11 +66,9 @@ type Allocation struct {
 	RAMBytesRequestAverage float64    `json:"ramBytesRequestAverage"`
 	RAMBytesUsageAverage   float64    `json:"ramBytesUsageAverage"`
 	RAMCost                float64    `json:"ramCost"`
-	RAMEfficiency          float64    `json:"ramEfficiency"`
 	SharedCost             float64    `json:"sharedCost"`
 	ExternalCost           float64    `json:"externalCost"`
 	TotalCost              float64    `json:"totalCost"`
-	TotalEfficiency        float64    `json:"totalEfficiency"`
 }
 
 // AllocationMatchFunc is a function that can be used to match Allocations by
@@ -113,7 +110,6 @@ func (a *Allocation) Clone() *Allocation {
 		CPUCoreRequestAverage:  a.CPUCoreRequestAverage,
 		CPUCoreUsageAverage:    a.CPUCoreUsageAverage,
 		CPUCost:                a.CPUCost,
-		CPUEfficiency:          a.CPUEfficiency,
 		GPUHours:               a.GPUHours,
 		GPUCost:                a.GPUCost,
 		NetworkCost:            a.NetworkCost,
@@ -123,11 +119,9 @@ func (a *Allocation) Clone() *Allocation {
 		RAMBytesRequestAverage: a.RAMBytesRequestAverage,
 		RAMBytesUsageAverage:   a.RAMBytesUsageAverage,
 		RAMCost:                a.RAMCost,
-		RAMEfficiency:          a.RAMEfficiency,
 		SharedCost:             a.SharedCost,
 		ExternalCost:           a.ExternalCost,
 		TotalCost:              a.TotalCost,
-		TotalEfficiency:        a.TotalEfficiency,
 	}
 }
 
@@ -159,9 +153,6 @@ func (a *Allocation) Equal(that *Allocation) bool {
 	if a.CPUCost != that.CPUCost {
 		return false
 	}
-	if a.CPUEfficiency != that.CPUEfficiency {
-		return false
-	}
 	if a.GPUHours != that.GPUHours {
 		return false
 	}
@@ -183,9 +174,6 @@ func (a *Allocation) Equal(that *Allocation) bool {
 	if a.RAMCost != that.RAMCost {
 		return false
 	}
-	if a.RAMEfficiency != that.RAMEfficiency {
-		return false
-	}
 	if a.SharedCost != that.SharedCost {
 		return false
 	}
@@ -195,13 +183,36 @@ func (a *Allocation) Equal(that *Allocation) bool {
 	if a.TotalCost != that.TotalCost {
 		return false
 	}
-	if a.TotalEfficiency != that.TotalEfficiency {
-		return false
-	}
 
 	return true
 }
 
+func (a *Allocation) CPUEfficiency() float64 {
+	if a.CPUCoreRequestAverage > 0 {
+		return a.CPUCoreUsageAverage / a.CPUCoreRequestAverage
+	}
+
+	return 1.0
+}
+
+func (a *Allocation) RAMEfficiency() float64 {
+	if a.RAMBytesRequestAverage > 0 {
+		return a.RAMBytesUsageAverage / a.RAMBytesRequestAverage
+	}
+
+	return 1.0
+}
+
+func (a *Allocation) TotalEfficiency() float64 {
+	if a.CPUCost+a.RAMCost > 0 {
+		ramCostEff := a.RAMEfficiency() * a.RAMCost
+		cpuCostEff := a.CPUEfficiency() * a.CPUCost
+		return (ramCostEff + cpuCostEff) / (a.CPUCost + a.RAMCost)
+	}
+
+	return 0.0
+}
+
 // CPUCores converts the Allocation's CPUCoreHours into average CPUCores
 func (a *Allocation) CPUCores() float64 {
 	if a.Minutes() <= 0.0 {
@@ -240,7 +251,7 @@ func (a *Allocation) MarshalJSON() ([]byte, error) {
 	jsonEncodeFloat64(buffer, "cpuCoreUsageAverage", a.CPUCoreUsageAverage, ",")
 	jsonEncodeFloat64(buffer, "cpuCoreHours", a.CPUCoreHours, ",")
 	jsonEncodeFloat64(buffer, "cpuCost", a.CPUCost, ",")
-	jsonEncodeFloat64(buffer, "cpuEfficiency", a.CPUEfficiency, ",")
+	jsonEncodeFloat64(buffer, "cpuEfficiency", a.CPUEfficiency(), ",")
 	jsonEncodeFloat64(buffer, "gpuHours", a.GPUHours, ",")
 	jsonEncodeFloat64(buffer, "gpuCost", a.GPUCost, ",")
 	jsonEncodeFloat64(buffer, "networkCost", a.NetworkCost, ",")
@@ -252,10 +263,10 @@ func (a *Allocation) MarshalJSON() ([]byte, error) {
 	jsonEncodeFloat64(buffer, "ramByteUsageAverage", a.RAMBytesUsageAverage, ",")
 	jsonEncodeFloat64(buffer, "ramByteHours", a.RAMByteHours, ",")
 	jsonEncodeFloat64(buffer, "ramCost", a.RAMCost, ",")
-	jsonEncodeFloat64(buffer, "ramEfficiency", a.RAMEfficiency, ",")
+	jsonEncodeFloat64(buffer, "ramEfficiency", a.RAMEfficiency(), ",")
 	jsonEncodeFloat64(buffer, "sharedCost", a.SharedCost, ",")
 	jsonEncodeFloat64(buffer, "totalCost", a.TotalCost, ",")
-	jsonEncodeFloat64(buffer, "totalEfficiency", a.TotalEfficiency, "")
+	jsonEncodeFloat64(buffer, "totalEfficiency", a.TotalEfficiency(), "")
 	buffer.WriteString("}")
 	return buffer.Bytes(), nil
 }
@@ -307,13 +318,10 @@ func (a *Allocation) Share(that *Allocation) (*Allocation, error) {
 	// non-shared costs, then add.
 	share := that.Clone()
 	share.SharedCost += share.TotalCost
-	share.TotalEfficiency = 1.0
 	share.CPUCost = 0
 	share.CPUCoreHours = 0
-	share.CPUEfficiency = 0
 	share.RAMCost = 0
 	share.RAMByteHours = 0
-	share.RAMEfficiency = 0
 	share.GPUCost = 0
 	share.GPUHours = 0
 	share.PVCost = 0
@@ -375,38 +383,6 @@ func (a *Allocation) add(that *Allocation) {
 		a.End = that.End
 	}
 
-	// Note: efficiency numbers are computed the cost-weighted sum of each
-	// Allocation's efficiency.
-	// e.g. ($10 @ 25%) + ($10 @ 75%)  = (2.5+7.5)/20   =  50%
-	// e.g. ($90 @ 10%) + ($10 @ 100%) = (9.0+10.0)/100 =  19%
-	// e.g. ($100 @ 0%) + ($100 @ 0%)  = (0.0+0.0)/200  =   0%
-	// e.g. ($10 @ 150%) + ($10 @ 50%) = (15.0+5.0)/20  = 100%
-	// e.g. ($0 @ 100%) + ($0 @ 50%)                    =   0% (no div by 0)
-
-	// Compute CPU efficiency (see note above for methodology)
-	aggCPUCost := a.CPUCost + that.CPUCost
-	if aggCPUCost > 0 {
-		a.CPUEfficiency = (a.CPUEfficiency*a.CPUCost + that.CPUEfficiency*that.CPUCost) / aggCPUCost
-	} else {
-		a.CPUEfficiency = 0.0
-	}
-
-	// Compute RAM efficiency (see note above for methodology)
-	aggRAMCost := a.RAMCost + that.RAMCost
-	if aggRAMCost > 0 {
-		a.RAMEfficiency = (a.RAMEfficiency*a.RAMCost + that.RAMEfficiency*that.RAMCost) / aggRAMCost
-	} else {
-		a.RAMEfficiency = 0.0
-	}
-
-	// Compute total efficiency (see note above for methodology)
-	aggTotalCost := a.TotalCost + that.TotalCost
-	if aggTotalCost > 0 {
-		a.TotalEfficiency = (a.TotalEfficiency*a.TotalCost + that.TotalEfficiency*that.TotalCost) / aggTotalCost
-	} else {
-		aggTotalCost = 0.0
-	}
-
 	// Sum all cumulative resource fields
 	a.CPUCoreHours += that.CPUCoreHours
 	a.CPUCoreRequestAverage += that.CPUCoreRequestAverage

+ 25 - 24
pkg/kubecost/allocation_test.go

@@ -32,24 +32,25 @@ func NewUnitAllocation(name string, start time.Time, resolution time.Duration, p
 	end := start.Add(resolution)
 
 	alloc := &Allocation{
-		Name:            name,
-		Properties:      *properties,
-		Window:          NewWindow(&start, &end).Clone(),
-		Start:           start,
-		End:             end,
-		CPUCoreHours:    1,
-		CPUCost:         1,
-		CPUEfficiency:   1,
-		GPUHours:        1,
-		GPUCost:         1,
-		NetworkCost:     1,
-		PVByteHours:     1,
-		PVCost:          1,
-		RAMByteHours:    1,
-		RAMCost:         1,
-		RAMEfficiency:   1,
-		TotalCost:       5,
-		TotalEfficiency: 1,
+		Name:                   name,
+		Properties:             *properties,
+		Window:                 NewWindow(&start, &end).Clone(),
+		Start:                  start,
+		End:                    end,
+		CPUCoreHours:           1,
+		CPUCost:                1,
+		CPUCoreRequestAverage:  1,
+		CPUCoreUsageAverage:    1,
+		GPUHours:               1,
+		GPUCost:                1,
+		NetworkCost:            1,
+		PVByteHours:            1,
+		PVCost:                 1,
+		RAMByteHours:           1,
+		RAMCost:                1,
+		RAMBytesRequestAverage: 1,
+		RAMBytesUsageAverage:   1,
+		TotalCost:              5,
 	}
 
 	// If idle allocation, remove non-idle costs, but maintain total cost
@@ -1221,8 +1222,8 @@ func TestAllocationSetRange_Accumulate(t *testing.T) {
 	if alloc.CPUCost != 2.0 {
 		t.Fatalf("accumulating AllocationSetRange: expected 2.0; actual %f", alloc.CPUCost)
 	}
-	if alloc.CPUEfficiency != 1.0 {
-		t.Fatalf("accumulating AllocationSetRange: expected 1.0; actual %f", alloc.CPUEfficiency)
+	if alloc.CPUEfficiency() != 1.0 {
+		t.Fatalf("accumulating AllocationSetRange: expected 1.0; actual %f", alloc.CPUEfficiency())
 	}
 	if alloc.GPUHours != 2.0 {
 		t.Fatalf("accumulating AllocationSetRange: expected 2.0; actual %f", alloc.GPUHours)
@@ -1245,14 +1246,14 @@ func TestAllocationSetRange_Accumulate(t *testing.T) {
 	if alloc.RAMCost != 2.0 {
 		t.Fatalf("accumulating AllocationSetRange: expected 2.0; actual %f", alloc.RAMCost)
 	}
-	if alloc.RAMEfficiency != 1.0 {
-		t.Fatalf("accumulating AllocationSetRange: expected 1.0; actual %f", alloc.RAMEfficiency)
+	if alloc.RAMEfficiency() != 1.0 {
+		t.Fatalf("accumulating AllocationSetRange: expected 1.0; actual %f", alloc.RAMEfficiency())
 	}
 	if alloc.TotalCost != 10.0 {
 		t.Fatalf("accumulating AllocationSetRange: expected 10.0; actual %f", alloc.TotalCost)
 	}
-	if alloc.TotalEfficiency != 1.0 {
-		t.Fatalf("accumulating AllocationSetRange: expected 1.0; actual %f", alloc.TotalEfficiency)
+	if alloc.TotalEfficiency() != 1.0 {
+		t.Fatalf("accumulating AllocationSetRange: expected 1.0; actual %f", alloc.TotalEfficiency())
 	}
 	if !alloc.Start.Equal(yesterday) {
 		t.Fatalf("accumulating AllocationSetRange: expected to start %s; actual %s", yesterday, alloc.Start)

+ 12 - 24
pkg/kubecost/kubecost_codecs.go

@@ -156,7 +156,6 @@ func (target *Allocation) MarshalBinary() (data []byte, err error) {
 	buff.WriteFloat64(target.CPUCoreRequestAverage)  // write float64
 	buff.WriteFloat64(target.CPUCoreUsageAverage)    // write float64
 	buff.WriteFloat64(target.CPUCost)                // write float64
-	buff.WriteFloat64(target.CPUEfficiency)          // write float64
 	buff.WriteFloat64(target.GPUHours)               // write float64
 	buff.WriteFloat64(target.GPUCost)                // write float64
 	buff.WriteFloat64(target.NetworkCost)            // write float64
@@ -166,11 +165,9 @@ func (target *Allocation) MarshalBinary() (data []byte, err error) {
 	buff.WriteFloat64(target.RAMBytesRequestAverage) // write float64
 	buff.WriteFloat64(target.RAMBytesUsageAverage)   // write float64
 	buff.WriteFloat64(target.RAMCost)                // write float64
-	buff.WriteFloat64(target.RAMEfficiency)          // write float64
 	buff.WriteFloat64(target.SharedCost)             // write float64
 	buff.WriteFloat64(target.ExternalCost)           // write float64
 	buff.WriteFloat64(target.TotalCost)              // write float64
-	buff.WriteFloat64(target.TotalEfficiency)        // write float64
 	return buff.Bytes(), nil
 }
 
@@ -258,49 +255,40 @@ func (target *Allocation) UnmarshalBinary(data []byte) (err error) {
 	target.CPUCost = t
 
 	u := buff.ReadFloat64() // read float64
-	target.CPUEfficiency = u
+	target.GPUHours = u
 
 	w := buff.ReadFloat64() // read float64
-	target.GPUHours = w
+	target.GPUCost = w
 
 	x := buff.ReadFloat64() // read float64
-	target.GPUCost = x
+	target.NetworkCost = x
 
 	y := buff.ReadFloat64() // read float64
-	target.NetworkCost = y
+	target.PVByteHours = y
 
 	z := buff.ReadFloat64() // read float64
-	target.PVByteHours = z
+	target.PVCost = z
 
 	aa := buff.ReadFloat64() // read float64
-	target.PVCost = aa
+	target.RAMByteHours = aa
 
 	bb := buff.ReadFloat64() // read float64
-	target.RAMByteHours = bb
+	target.RAMBytesRequestAverage = bb
 
 	cc := buff.ReadFloat64() // read float64
-	target.RAMBytesRequestAverage = cc
+	target.RAMBytesUsageAverage = cc
 
 	dd := buff.ReadFloat64() // read float64
-	target.RAMBytesUsageAverage = dd
+	target.RAMCost = dd
 
 	ee := buff.ReadFloat64() // read float64
-	target.RAMCost = ee
+	target.SharedCost = ee
 
 	ff := buff.ReadFloat64() // read float64
-	target.RAMEfficiency = ff
+	target.ExternalCost = ff
 
 	gg := buff.ReadFloat64() // read float64
-	target.SharedCost = gg
-
-	hh := buff.ReadFloat64() // read float64
-	target.ExternalCost = hh
-
-	ll := buff.ReadFloat64() // read float64
-	target.TotalCost = ll
-
-	mm := buff.ReadFloat64() // read float64
-	target.TotalEfficiency = mm
+	target.TotalCost = gg
 
 	return nil
 }