mirror of
https://github.com/minio/minio.git
synced 2025-01-11 15:03:22 -05:00
Better reporting of total/free usable capacity of the cluster (#15230)
The current code uses approximation using a ratio. The approximation can skew if we have multiple pools with different disk capacities. Replace the algorithm with a simpler one which counts data disks and ignore parity disks.
This commit is contained in:
parent
dd839bf295
commit
8d98282afd
@ -1277,7 +1277,7 @@ func deleteObjectPerfBucket(objectAPI ObjectLayer) {
|
|||||||
func validateObjPerfOptions(ctx context.Context, objectAPI ObjectLayer, concurrent int, size int, autotune bool) (sufficientCapacity bool, canAutotune bool, capacityErrMsg string) {
|
func validateObjPerfOptions(ctx context.Context, objectAPI ObjectLayer, concurrent int, size int, autotune bool) (sufficientCapacity bool, canAutotune bool, capacityErrMsg string) {
|
||||||
storageInfo, _ := objectAPI.StorageInfo(ctx)
|
storageInfo, _ := objectAPI.StorageInfo(ctx)
|
||||||
capacityNeeded := uint64(concurrent * size)
|
capacityNeeded := uint64(concurrent * size)
|
||||||
capacity := uint64(GetTotalUsableCapacityFree(storageInfo.Disks, storageInfo))
|
capacity := GetTotalUsableCapacityFree(storageInfo.Disks, storageInfo)
|
||||||
|
|
||||||
if capacity < capacityNeeded {
|
if capacity < capacityNeeded {
|
||||||
return false, false, fmt.Sprintf("not enough usable space available to perform speedtest - expected %s, got %s",
|
return false, false, fmt.Sprintf("not enough usable space available to perform speedtest - expected %s, got %s",
|
||||||
|
@ -238,6 +238,7 @@ func (z *erasureServerPools) GetRawData(ctx context.Context, volume, file string
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return the count of disks in each pool
|
||||||
func (z *erasureServerPools) SetDriveCounts() []int {
|
func (z *erasureServerPools) SetDriveCounts() []int {
|
||||||
setDriveCounts := make([]int, len(z.serverPools))
|
setDriveCounts := make([]int, len(z.serverPools))
|
||||||
for i := range z.serverPools {
|
for i := range z.serverPools {
|
||||||
|
@ -184,6 +184,10 @@ func (es *erasureSingle) Shutdown(ctx context.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (es *erasureSingle) SetDriveCounts() []int {
|
||||||
|
return []int{1}
|
||||||
|
}
|
||||||
|
|
||||||
func (es *erasureSingle) BackendInfo() (b madmin.BackendInfo) {
|
func (es *erasureSingle) BackendInfo() (b madmin.BackendInfo) {
|
||||||
b.Type = madmin.Erasure
|
b.Type = madmin.Erasure
|
||||||
|
|
||||||
|
10
cmd/fs-v1.go
10
cmd/fs-v1.go
@ -209,7 +209,13 @@ func (fs *FSObjects) Shutdown(ctx context.Context) error {
|
|||||||
|
|
||||||
// BackendInfo - returns backend information
|
// BackendInfo - returns backend information
|
||||||
func (fs *FSObjects) BackendInfo() madmin.BackendInfo {
|
func (fs *FSObjects) BackendInfo() madmin.BackendInfo {
|
||||||
return madmin.BackendInfo{Type: madmin.FS}
|
return madmin.BackendInfo{
|
||||||
|
Type: madmin.FS,
|
||||||
|
StandardSCData: []int{1},
|
||||||
|
StandardSCParity: 0,
|
||||||
|
RRSCData: []int{1},
|
||||||
|
RRSCParity: 0,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// LocalStorageInfo - returns underlying storage statistics.
|
// LocalStorageInfo - returns underlying storage statistics.
|
||||||
@ -234,7 +240,7 @@ func (fs *FSObjects) StorageInfo(ctx context.Context) (StorageInfo, []error) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
storageInfo.Backend.Type = madmin.FS
|
storageInfo.Backend = fs.BackendInfo()
|
||||||
return storageInfo, nil
|
return storageInfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1903,12 +1903,12 @@ func getClusterStorageMetrics() *MetricsGroup {
|
|||||||
|
|
||||||
metrics = append(metrics, Metric{
|
metrics = append(metrics, Metric{
|
||||||
Description: getClusterCapacityUsageBytesMD(),
|
Description: getClusterCapacityUsageBytesMD(),
|
||||||
Value: GetTotalUsableCapacity(storageInfo.Disks, storageInfo),
|
Value: float64(GetTotalUsableCapacity(storageInfo.Disks, storageInfo)),
|
||||||
})
|
})
|
||||||
|
|
||||||
metrics = append(metrics, Metric{
|
metrics = append(metrics, Metric{
|
||||||
Description: getClusterCapacityUsageFreeBytesMD(),
|
Description: getClusterCapacityUsageFreeBytesMD(),
|
||||||
Value: GetTotalUsableCapacityFree(storageInfo.Disks, storageInfo),
|
Value: float64(GetTotalUsableCapacityFree(storageInfo.Disks, storageInfo)),
|
||||||
})
|
})
|
||||||
|
|
||||||
metrics = append(metrics, Metric{
|
metrics = append(metrics, Metric{
|
||||||
|
@ -577,7 +577,7 @@ func storageMetricsPrometheus(ch chan<- prometheus.Metric) {
|
|||||||
"Total usable capacity online in the cluster",
|
"Total usable capacity online in the cluster",
|
||||||
nil, nil),
|
nil, nil),
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
GetTotalUsableCapacity(server.Disks, s),
|
float64(GetTotalUsableCapacity(server.Disks, s)),
|
||||||
)
|
)
|
||||||
// Report total usable capacity free
|
// Report total usable capacity free
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@ -586,7 +586,7 @@ func storageMetricsPrometheus(ch chan<- prometheus.Metric) {
|
|||||||
"Total free usable capacity online in the cluster",
|
"Total free usable capacity online in the cluster",
|
||||||
nil, nil),
|
nil, nil),
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
GetTotalUsableCapacityFree(server.Disks, s),
|
float64(GetTotalUsableCapacityFree(server.Disks, s)),
|
||||||
)
|
)
|
||||||
|
|
||||||
// MinIO Offline Disks per node
|
// MinIO Offline Disks per node
|
||||||
|
@ -30,17 +30,17 @@ func GetTotalCapacity(diskInfo []madmin.Disk) (capacity uint64) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetTotalUsableCapacity gets the total usable capacity in the cluster.
|
// GetTotalUsableCapacity gets the total usable capacity in the cluster.
|
||||||
// This value is not an accurate representation of total usable in a multi-tenant deployment.
|
func GetTotalUsableCapacity(diskInfo []madmin.Disk, s StorageInfo) (capacity uint64) {
|
||||||
func GetTotalUsableCapacity(diskInfo []madmin.Disk, s StorageInfo) (capacity float64) {
|
if globalIsGateway {
|
||||||
raw := GetTotalCapacity(diskInfo)
|
return 0
|
||||||
var approxDataBlocks float64
|
|
||||||
var actualDisks float64
|
|
||||||
for _, scData := range s.Backend.StandardSCData {
|
|
||||||
approxDataBlocks += float64(scData)
|
|
||||||
actualDisks += float64(scData + s.Backend.StandardSCParity)
|
|
||||||
}
|
}
|
||||||
ratio := approxDataBlocks / actualDisks
|
for _, disk := range diskInfo {
|
||||||
return float64(raw) * ratio
|
// Ignore parity disks
|
||||||
|
if disk.DiskIndex < s.Backend.StandardSCData[disk.PoolIndex] {
|
||||||
|
capacity += disk.TotalSpace
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTotalCapacityFree gets the total capacity free in the cluster.
|
// GetTotalCapacityFree gets the total capacity free in the cluster.
|
||||||
@ -52,15 +52,16 @@ func GetTotalCapacityFree(diskInfo []madmin.Disk) (capacity uint64) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetTotalUsableCapacityFree gets the total usable capacity free in the cluster.
|
// GetTotalUsableCapacityFree gets the total usable capacity free in the cluster.
|
||||||
// This value is not an accurate representation of total free in a multi-tenant deployment.
|
func GetTotalUsableCapacityFree(diskInfo []madmin.Disk, s StorageInfo) (capacity uint64) {
|
||||||
func GetTotalUsableCapacityFree(diskInfo []madmin.Disk, s StorageInfo) (capacity float64) {
|
if globalIsGateway {
|
||||||
raw := GetTotalCapacityFree(diskInfo)
|
return 0
|
||||||
var approxDataBlocks float64
|
|
||||||
var actualDisks float64
|
|
||||||
for _, scData := range s.Backend.StandardSCData {
|
|
||||||
approxDataBlocks += float64(scData)
|
|
||||||
actualDisks += float64(scData + s.Backend.StandardSCParity)
|
|
||||||
}
|
}
|
||||||
ratio := approxDataBlocks / actualDisks
|
|
||||||
return float64(raw) * ratio
|
for _, disk := range diskInfo {
|
||||||
|
// Ignore parity disks
|
||||||
|
if disk.DiskIndex < s.Backend.StandardSCData[disk.PoolIndex] {
|
||||||
|
capacity += disk.AvailableSpace
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user