-
Notifications
You must be signed in to change notification settings - Fork 3.8k
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
[DO NOT MERGE] distsql: row batching #20621
Conversation
Rather than set up a benchmark with remote communication, I'd rather see a benchmark which exercises a more complex local flow. See my comments below. The fact that Reviewed 2 of 2 files at r1. pkg/sql/distsqlrun/base.go, line 413 at r1 (raw file):
I think pkg/sql/distsqlrun/tablereader_test.go, line 299 at r2 (raw file):
Two criticisms of this benchmark: the use of the Comments from Reviewable |
Release note: None
Release note: None
Set up a hashjoin to
The benefit we're seeing here is due to allowing processors to run concurrently, amortizing row channel overhead, and "tighter" loops (no special processing was done in the aggregator). |
Thanks for adding these benchmarks. Sort of awkward to construct these flows manually, though. Would be nice if you could use Review status: 1 of 5 files reviewed at latest revision, 5 unresolved discussions, some commit checks failed. pkg/sql/distsqlrun/base_test.go, line 120 at r4 (raw file):
Won't the output size be the input size given that you're joining on the single column? Perhaps I'm misunderstanding how pkg/sql/distsqlrun/base_test.go, line 181 at r4 (raw file):
You're setting up a ton of pkg/sql/distsqlrun/base_test.go, line 219 at r4 (raw file):
You need run the Comments from Reviewable |
With the fixes I mention below, the discrepancy between eliding and row-batching is much smaller on my machine:
Review status: 1 of 5 files reviewed at latest revision, 7 unresolved discussions, some commit checks failed. pkg/sql/distsqlrun/aggregator.go, line 279 at r4 (raw file):
Passing in pkg/sql/distsqlrun/aggregator.go, line 288 at r4 (raw file):
This defer is now in the inner-loop. Comments from Reviewable |
Another interesting data point is varying the row batch size:
So batching ~16 rows is equivalent to eliding the row channel. That's interesting because the benchmark always uses full size batches which is optimistic. Review status: 1 of 5 files reviewed at latest revision, 7 unresolved discussions, some commit checks failed. Comments from Reviewable |
Something the
I'm not sure how to get similar benefits without eliding row channels. Possibly we could use pool allocation and return batches to the pool once they have been consumed. Review status: 1 of 5 files reviewed at latest revision, 7 unresolved discussions, some commit checks failed. Comments from Reviewable |
Some more profiling reveals another place of excessive allocations: creating a new Review status: 1 of 5 files reviewed at latest revision, 7 unresolved discussions, some commit checks failed. Comments from Reviewable |
Thanks for taking a look at this. It's definitely useful to have these benchmarks. I'll add these in separate PRs and see if I can do them in a less manual manner. The big thing that stands out to me is the benefit that row channel elision gives us regarding allocations. We can try to approximate that with row batching by, as you say, pooling allocations and reusing batches once consumed but it is nice to have that by default. I want to go back to the question of what we should focus on before the feature freeze. We definitely get a 50% performance improvement in this benchmark by using row batching. Row channel elision can provide better performance by removing unnecessary allocations, but I'm wondering how general that improvement can be since this only applies when we would synchronously plan processors on the same node. Consider the example in this benchmark. Although realistic to a certain extent, a user running a Additionally, row channel elision is going to be a huge change. It fundamentally changes how we think about processors/communication in distsql and requires some careful thinking when planning. I definitely don't see this change making it into 2.0. Row batching is a much less invasive change that we need anyway, gives us significant performance improvements and needs a lot less work to provide us with significant results (I'm thinking I would like to make a decision by the end of the day since the feature freeze is coming up pretty soon. |
IMHO row batching is absolutely essential, always-good optimization. In comparison, channel elision is an incidental, sometimes-good optimization. Benchmarks are good, but we should not mistake the forest for the tree. Progress on row batching must be prioritized, even if it doesn't yet fully work for 2.0. |
Row batching is @asubiotto's primary focus. What additional prioritization would you give it? Discussed offline and not captured above is the current plan to do both row batching and channel elision for 2.0. Channel elision is going to open up other optimization opportunities such as reducing allocations which will have a very large impact as #20755 and #20759 hint at. I feel like I have a decent model of distsql execution in my head now and I'm pretty confident we should do both row batching and channel elision. |
I'm glad you discussed this offline. I was reacting to Alfonso's last comment on this PR. I was not aware of any further discussion after that. |
The discussion was continued on #20555 |
Draft work on row batching with benchmark. Thought it would be useful to share this given discussion on #20555. Results:
This is a meaningless benchmark as
RowBatch
is equal toElideRowChan
but with row copies. Keep in mind thatRowBatch
needs to allocate row copies, but this is a cost that occurs once per local flow and can be amortized.More meaningful benchmarks could be to set up flows with remote communication and longer flows with only local communication.