mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-08-16 04:06:44 +00:00
perf(weed/topology): gather a node's volumes into one slice (#10617)
* perf(weed/topology): preallocate the node's volume concatenation A node's volumes are gathered per disk and concatenated into a slice grown from nil, so a server with several disks reallocates and copies its way up. The writable-volume refresh loop does this for every node every few seconds. BenchmarkDataNodeGetVolumes/8Disks 322551844 B/op -> 121602326 B/op * perf(weed/topology): fill one slice across a node's disks Each disk built its own right-sized copy of its volumes, and the node then copied all of them again into the combined slice. Appending into the caller's slice makes it one allocation whatever the disk count, which halves even the single-disk case. BenchmarkDataNodeGetVolumes 1Disks 121602326 B/op 2 allocs/op -> 60801314 B/op 1 allocs/op 8Disks 121602326 B/op 9 allocs/op -> 60801024 B/op 1 allocs/op
This commit is contained in:
@@ -200,11 +200,15 @@ func (dn *DataNode) AdjustDiskUsageBytes(diskTotalBytes, diskFreeBytes map[strin
|
||||
|
||||
func (dn *DataNode) GetVolumes() (ret []storage.VolumeInfo) {
|
||||
dn.RLock()
|
||||
defer dn.RUnlock()
|
||||
total := 0
|
||||
for _, c := range dn.children {
|
||||
disk := c.(*Disk)
|
||||
ret = append(ret, disk.GetVolumes()...)
|
||||
total += c.(*Disk).VolumeCount()
|
||||
}
|
||||
ret = make([]storage.VolumeInfo, 0, total)
|
||||
for _, c := range dn.children {
|
||||
ret = c.(*Disk).AppendVolumes(ret)
|
||||
}
|
||||
dn.RUnlock()
|
||||
return ret
|
||||
}
|
||||
|
||||
|
||||
+10
-5
@@ -202,14 +202,19 @@ func (d *Disk) doAddOrUpdateVolume(v storage.VolumeInfo) (isNew, isChanged bool)
|
||||
return
|
||||
}
|
||||
|
||||
func (d *Disk) GetVolumes() (ret []storage.VolumeInfo) {
|
||||
func (d *Disk) GetVolumes() []storage.VolumeInfo {
|
||||
return d.AppendVolumes(make([]storage.VolumeInfo, 0, d.VolumeCount()))
|
||||
}
|
||||
|
||||
// AppendVolumes appends the disk's volumes to dst, so a caller gathering
|
||||
// several disks fills one slice instead of concatenating a copy per disk.
|
||||
func (d *Disk) AppendVolumes(dst []storage.VolumeInfo) []storage.VolumeInfo {
|
||||
d.RLock()
|
||||
ret = make([]storage.VolumeInfo, 0, len(d.volumes))
|
||||
defer d.RUnlock()
|
||||
for _, v := range d.volumes {
|
||||
ret = append(ret, v)
|
||||
dst = append(dst, v)
|
||||
}
|
||||
d.RUnlock()
|
||||
return ret
|
||||
return dst
|
||||
}
|
||||
|
||||
func (d *Disk) VolumeCount() int {
|
||||
|
||||
Reference in New Issue
Block a user