mirror of
https://github.com/minio/minio.git
synced 2025-01-23 12:43:16 -05:00
Add server pool reserved space (#14974)
If one or more pools reach 85% usage in a set, we will only use pools that have more free space. In case all pools are above 85% we allow all of them to be used with the regular distribution.
This commit is contained in:
parent
d8101573be
commit
a4be0b88f6
@ -233,8 +233,9 @@ func (z *erasureServerPools) SetDriveCounts() []int {
|
|||||||
type serverPoolsAvailableSpace []poolAvailableSpace
|
type serverPoolsAvailableSpace []poolAvailableSpace
|
||||||
|
|
||||||
type poolAvailableSpace struct {
|
type poolAvailableSpace struct {
|
||||||
Index int
|
Index int
|
||||||
Available uint64
|
Available uint64
|
||||||
|
MaxUsedPct int // Used disk percentage of most filled disk, rounded down.
|
||||||
}
|
}
|
||||||
|
|
||||||
// TotalAvailable - total available space
|
// TotalAvailable - total available space
|
||||||
@ -246,10 +247,41 @@ func (p serverPoolsAvailableSpace) TotalAvailable() uint64 {
|
|||||||
return total
|
return total
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FilterMaxUsed will filter out any pools that has used percent bigger than max,
|
||||||
|
// unless all have that, in which case all are preserved.
|
||||||
|
func (p serverPoolsAvailableSpace) FilterMaxUsed(max int) {
|
||||||
|
// We aren't modifying p, only entries in it, so we don't need to receive a pointer.
|
||||||
|
if len(p) <= 1 {
|
||||||
|
// Nothing to do.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var ok bool
|
||||||
|
for _, z := range p {
|
||||||
|
if z.MaxUsedPct < max {
|
||||||
|
ok = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
// All above limit.
|
||||||
|
// Do not modify
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove entries that are above.
|
||||||
|
for i, z := range p {
|
||||||
|
if z.MaxUsedPct < max {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
p[i].Available = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// getAvailablePoolIdx will return an index that can hold size bytes.
|
// getAvailablePoolIdx will return an index that can hold size bytes.
|
||||||
// -1 is returned if no serverPools have available space for the size given.
|
// -1 is returned if no serverPools have available space for the size given.
|
||||||
func (z *erasureServerPools) getAvailablePoolIdx(ctx context.Context, bucket, object string, size int64) int {
|
func (z *erasureServerPools) getAvailablePoolIdx(ctx context.Context, bucket, object string, size int64) int {
|
||||||
serverPools := z.getServerPoolsAvailableSpace(ctx, bucket, object, size)
|
serverPools := z.getServerPoolsAvailableSpace(ctx, bucket, object, size)
|
||||||
|
serverPools.FilterMaxUsed(100 - (100 * diskReserveFraction))
|
||||||
total := serverPools.TotalAvailable()
|
total := serverPools.TotalAvailable()
|
||||||
if total == 0 {
|
if total == 0 {
|
||||||
return -1
|
return -1
|
||||||
@ -302,11 +334,17 @@ func (z *erasureServerPools) getServerPoolsAvailableSpace(ctx context.Context, b
|
|||||||
serverPools[i] = poolAvailableSpace{Index: i}
|
serverPools[i] = poolAvailableSpace{Index: i}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
var maxUsedPct int
|
||||||
for _, disk := range zinfo {
|
for _, disk := range zinfo {
|
||||||
if disk == nil {
|
if disk == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
available += disk.Total - disk.Used
|
available += disk.Total - disk.Used
|
||||||
|
|
||||||
|
// set maxUsedPct to the value from the disk with the least space percentage.
|
||||||
|
if pctUsed := int(disk.Used * 100 / disk.Total); pctUsed > maxUsedPct {
|
||||||
|
maxUsedPct = pctUsed
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Since we are comparing pools that may have a different number of sets
|
// Since we are comparing pools that may have a different number of sets
|
||||||
@ -317,8 +355,9 @@ func (z *erasureServerPools) getServerPoolsAvailableSpace(ctx context.Context, b
|
|||||||
available *= uint64(nSets[i])
|
available *= uint64(nSets[i])
|
||||||
|
|
||||||
serverPools[i] = poolAvailableSpace{
|
serverPools[i] = poolAvailableSpace{
|
||||||
Index: i,
|
Index: i,
|
||||||
Available: available,
|
Available: available,
|
||||||
|
MaxUsedPct: maxUsedPct,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return serverPools
|
return serverPools
|
||||||
|
@ -113,6 +113,10 @@ const (
|
|||||||
// diskFillFraction is the fraction of a disk we allow to be filled.
|
// diskFillFraction is the fraction of a disk we allow to be filled.
|
||||||
diskFillFraction = 0.99
|
diskFillFraction = 0.99
|
||||||
|
|
||||||
|
// diskReserveFraction is the fraction of a disk where we will fill other server pools first.
|
||||||
|
// If all pools reach this, we will use all pools with regular placement.
|
||||||
|
diskReserveFraction = 0.15
|
||||||
|
|
||||||
// diskAssumeUnknownSize is the size to assume when an unknown size upload is requested.
|
// diskAssumeUnknownSize is the size to assume when an unknown size upload is requested.
|
||||||
diskAssumeUnknownSize = 1 << 30
|
diskAssumeUnknownSize = 1 << 30
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user