-
Notifications
You must be signed in to change notification settings - Fork 15
REP-6492 Switch to $sampleRate-style partitioning #128
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
REP-6492 Switch to $sampleRate-style partitioning #128
Conversation
180b79a
to
ab5b493
Compare
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.
This looks good in general. I left some comments on small points.
/* | ||
_, err := verifier.verificationTaskCollection().InsertOne( | ||
ctx, | ||
task, | ||
) | ||
require.NoError(err, "should insert collection task") | ||
|
||
require.NoError( | ||
verifier.ProcessCollectionVerificationTask(ctx, 0, task), | ||
"task should succeed", | ||
) | ||
*/ |
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.
Do we still need this in the test?
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.
oops, removed
internal/verifier/partition.go
Outdated
@@ -95,8 +95,9 @@ func (verifier *Verifier) createPartitionTasksWithSampleRateRetryable( | |||
} | |||
|
|||
pipeline := mongo.Pipeline{ | |||
{{"$project", bson.D{{"_id", 1}}}}, | |||
// NB: $sort MUST precede $project in order to avoid a blocking sort. |
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.
Could be more specific that it's only a problem for versions before v6.0.
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.
done
internal/verifier/partition.go
Outdated
idealNumPartitions := util.Divide(collBytes, idealPartitionBytes) | ||
docsPerPartition := util.Divide(docsCount, idealNumPartitions) |
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.
It seems that it's still possible to get division by 0 error. If collBytes < idealPartitionBytes
, idealNumPartitions
would become 0. Could we limit idealNumPartitions
and docsPerPartition
to be larger than 1?
idealNumPartitions := util.Divide(collBytes, idealPartitionBytes) | |
docsPerPartition := util.Divide(docsCount, idealNumPartitions) | |
idealNumPartitions := min(1, util.Divide(collBytes, idealPartitionBytes)) | |
docsPerPartition := min(1, util.Divide(docsCount, idealNumPartitions)) |
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.
util.Divide() returns a float, so that shouldn’t happen, but I’ve tweaked the logic anyhow.
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.
LGTM, thanks!
$sample-based partitioning has proven problematic for some years now because it often creates highly-imbalanced partitions.
This changeset switches partitioning to use $sampleRate instead. Because this entails a full index scan it tends to be slower; we offset that by creating partition tasks immediately as we receive sampled partition boundaries rather than all at once at the end of the aggregation.
Because MongoDB 4.2 lacked $sampleRate (and $rand as well), the legacy partitioning logic remains for use with that server version.
Both legacy & $sampleRate partitioning are made to use
available
read concern andsecondaryPreferred
read preference. These aggregations don’t need consistency, but they benefit substantially from speed & minimizing workload on the primary.A few simplifications are made here as well. For example,
MongosyncID
is removed from the PartitionKey struct since it’s never actually relevant, and certain parameters to the legacy partitioner are made constant (since they were always used thus). Theutil.Divide
function is renamedutil.DivideToF64
to clarify that its return is a float.