-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
tools bucket replicate: add support for concurrent bucket replication #5280
Changes from all commits
4294849
c872894
c6e032d
fc2e67d
8a11e08
aa143f3
bf09904
743bca2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -11,9 +11,11 @@ import ( | |||||||
"io/ioutil" | ||||||||
"path" | ||||||||
"sort" | ||||||||
"sync" | ||||||||
|
||||||||
"github.com/go-kit/log" | ||||||||
"github.com/go-kit/log/level" | ||||||||
"github.com/hashicorp/go-multierror" | ||||||||
"github.com/oklog/ulid" | ||||||||
"github.com/pkg/errors" | ||||||||
"github.com/prometheus/client_golang/prometheus" | ||||||||
|
@@ -179,7 +181,7 @@ func newReplicationScheme( | |||||||
} | ||||||||
} | ||||||||
|
||||||||
func (rs *replicationScheme) execute(ctx context.Context) error { | ||||||||
func (rs *replicationScheme) execute(ctx context.Context, concurrencyLvl int) error { | ||||||||
availableBlocks := []*metadata.Meta{} | ||||||||
|
||||||||
metas, partials, err := rs.fetcher.Fetch(ctx) | ||||||||
|
@@ -204,13 +206,44 @@ func (rs *replicationScheme) execute(ctx context.Context) error { | |||||||
return availableBlocks[i].BlockMeta.MinTime < availableBlocks[j].BlockMeta.MinTime | ||||||||
}) | ||||||||
|
||||||||
for _, b := range availableBlocks { | ||||||||
if err := rs.ensureBlockIsReplicated(ctx, b.BlockMeta.ULID); err != nil { | ||||||||
return errors.Wrapf(err, "ensure block %v is replicated", b.BlockMeta.ULID.String()) | ||||||||
} | ||||||||
// iterate over blocks and send them to a channel sequentially | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We use a full sentences in comments (nit).
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yup, my bad, I'll fix it I wonder why this was not picked up by the linter, golangci-lint config includes godot: Line 36 in a6f6ce0
.godot.yaml with config appropriate to make it check all comments? (and probably fix lots and lots of comments across the code base)
|
||||||||
blocksChan := func() <-chan *metadata.Meta { | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why does it have to be in closure (anon function)? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No reason, good point, I'll simplify this. |
||||||||
out := make(chan *metadata.Meta) | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
go func() { | ||||||||
for _, b := range availableBlocks { | ||||||||
out <- b | ||||||||
} | ||||||||
close(out) | ||||||||
}() | ||||||||
return out | ||||||||
}() | ||||||||
|
||||||||
// fan-out for concurrent replication | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wrong comment format (full sentence please). |
||||||||
wg := sync.WaitGroup{} | ||||||||
wg.Add(concurrencyLvl) | ||||||||
errs := make(chan error) | ||||||||
for i := 0; i < concurrencyLvl; i++ { | ||||||||
go func(bc <-chan *metadata.Meta, errs chan<- error) { | ||||||||
for b := range bc { | ||||||||
if err := rs.ensureBlockIsReplicated(ctx, b.BlockMeta.ULID); err != nil { | ||||||||
errs <- err | ||||||||
} | ||||||||
} | ||||||||
wg.Done() | ||||||||
}(blocksChan, errs) | ||||||||
} | ||||||||
go func() { | ||||||||
wg.Wait() | ||||||||
close(errs) | ||||||||
}() | ||||||||
|
||||||||
// fan-in for errors | ||||||||
var me error | ||||||||
for e := range errs { | ||||||||
me = multierror.Append(me, e) | ||||||||
} | ||||||||
|
||||||||
return nil | ||||||||
return me | ||||||||
} | ||||||||
|
||||||||
// ensureBlockIsReplicated ensures that a block present in the origin bucket is | ||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately this is not as simple, so if you want to keep this implementation we have to add extra context and set it to 1.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see what you mean here, even if the problem can be solved by vertical compaction, the blocks should not be uploaded out of sequence for no valid reason.