Optimize complex object assembly #539
No reviewers
Labels
No labels
P0
P1
P2
P3
badger
frostfs-adm
frostfs-cli
frostfs-ir
frostfs-lens
frostfs-node
good first issue
triage
Infrastructure
blocked
bug
config
discussion
documentation
duplicate
enhancement
go
help wanted
internal
invalid
kludge
observability
perfomance
question
refactoring
wontfix
No milestone
No project
No assignees
3 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: TrueCloudLab/frostfs-node#539
Loading…
Reference in a new issue
No description provided.
Delete branch "dstepanov-yadro/frostfs-node:fix/assembling_optimizations"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
As is: The node reads objects in memory sequentially, allocating a new buffer for each child object.
Optimization, version 1: Removed the allocation of a new buffer for each child object.
Optimization, version 2: The child object is written direct to the output stream. Side effect: previously, the object was validated first, then the payload was sent; now we send the payload first, then we validate.
See commits for realization details.
Dev-env test results on local PC: 10 readers, 10 minutes, object size 512MB
master
v1
v2
5962672fae
tod3128378a1
@ -51,9 +51,7 @@ func NewSimpleObjectWriter() *SimpleObjectWriter {
func (s *SimpleObjectWriter) WriteHeader(_ context.Context, obj *objectSDK.Object) error {
s.obj = obj
argh
d3128378a1
to4e9e0e66fc
@ -11,3 +11,3 @@
type objectGetter interface {
GetObject(ctx context.Context, id oid.ID, rng *objectSDK.Range) (*objectSDK.Object, error)
GetObjectAndWritePayload(ctx context.Context, id oid.ID, rng *objectSDK.Range, writer ChunkWriter) (*objectSDK.Object, error)
I find the idea for the such optimization as excellent, but didn't you consider to return payload from the method instead passing the writer?
for
I am afraid that with this hack (that works perfectly anyway) we may break SRP (I am really confused when one method gets and sends something in the same place) and dependency inversion (the point to pass an instance that implements the interface gives us the opportunity that we barely can use - we pass
NewSimpleObjectWriter
but will we ever wrap something else?)Fix me, if I skipped or didn't get something!
Then we will have to allocate memory for the entire object, and I'm just trying to avoid this.
NewSimpleObjectWriter()
passes only in one place. SeeassemblePayloadByObjectIDs
:writer
writes directly to response stream.4e9e0e66fc
to99bb488ebd
Awesome 👍