-
Notifications
You must be signed in to change notification settings - Fork 28.5k
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
[SPARK-35093] [SQL] AQE now uses newQueryStage plan as key for looking up cached exchanges for re-use #32195
Conversation
Test build #753174945 for PR 32195 at commit |
@tgravescs fyi |
ok to test |
Kubernetes integration test unable to build dist. exiting with code: 1 |
Test build #137445 has finished for PR 32195 at commit
|
Test build #753637969 for PR 32195 at commit |
Kubernetes integration test starting |
Kubernetes integration test status failure |
cc @maryannxue FYI |
Hi, @andygrove . Could you clarify that this is not a correctness issue in the PR description? It only causes job failures, doesn't it?
|
Test build #137447 has finished for PR 32195 at commit
|
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.
Does it mean, if Spark converts reused query stage from columnar to row-based, it will be compatible? Just out of curiosity.
Yes @dongjoon-hyun that is correct. It would result in an invalid plan that would fail to execute. |
@viirya Spark plugins can create either columnar or row-based exchanges as required for compatibility with other parts of the query plan. For example. a columnar |
Does |
This hasn't been a problem for us. We only ran into issues with the AQE exchange reuse logic because of the adaptive nature where query stages are being created during execution, and with Spark making changes after we provide the new query stage it is too late for our plugin to correct the issue. Without AQE, where the |
I'll take another look at |
If I'm understanding this properly it seems like the root cause is actually that AQE looks at the plan before the columnar changes are applied and physical plan gets executed so it thinks they are canonically the same when really after preparations (specifically here ApplyColumnarRulesAndInsertTransitions) and execution they aren't. I wonder if there is a better way to do that part. Might be nice to investigate that a bit further to see if that is possible. |
cc @cloud-fan |
This is a good point. Without AQE, |
so I was looking at this today and I think its fairly easy fix to just to change it to store the plan after its been through all the rules.
The only downside I can think of is if there is something that is matching on the original plan but after running the rules makes it not canonically the same but really is, it would take a bit longer to have to tranverse down the plan and apply all the rules. But that kind of seems like a bug to me anyway. |
Thanks, @tgravescs. That is a much simpler change! I have updated the PR. |
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.
change looks good to me, but would be great for others to take a look as well.
Test build #137742 has finished for PR 32195 at commit
|
sql/core/src/main/scala/org/apache/spark/sql/execution/adaptive/AdaptiveSparkPlanExec.scala
Outdated
Show resolved
Hide resolved
Kubernetes integration test starting |
Kubernetes integration test status failure |
Kubernetes integration test starting |
Kubernetes integration test status failure |
I'm OK with that. The fix is simple and |
@andygrove could update the description and then test on the 3.1.2 and 3.0.3 branches when you get a chance? |
@cloud-fan @tgravescs I updated the title and description. Let me know if this is still not clear. |
Yes, please backport this to the old branches. |
I applied this patch to the latest in branch-3.0 and branch-3.1 and ran manual tests to confirm that this fixes the issue for us in those releases. |
I'm not sure why the label pull requests check isn't running here. Anyone know? |
Not only here, I also saw other PRs their label pull requests are queued too. |
… up cached exchanges for re-use ### What changes were proposed in this pull request? AQE has an optimization where it attempts to reuse compatible exchanges but it does not take into account whether the exchanges are columnar or not, resulting in incorrect reuse under some circumstances. This PR simply changes the key used to lookup cached stages. It now uses the canonicalized form of the new query stage (potentially created by a plugin) rather than using the canonicalized form of the original exchange. ### Why are the changes needed? When using the [RAPIDS Accelerator for Apache Spark](https://github.com/NVIDIA/spark-rapids) we sometimes see a new query stage correctly create a row-based exchange and then Spark replaces it with a cached columnar exchange, which is not compatible, and this causes queries to fail. ### Does this PR introduce _any_ user-facing change? No. ### How was this patch tested? The patch has been tested with the query that highlighted this issue. I looked at writing unit tests for this but it would involve implementing a mock columnar exchange in the tests so would be quite a bit of work. If anyone has ideas on other ways to test this I am happy to hear them. Closes #32195 from andygrove/SPARK-35093. Authored-by: Andy Grove <andygrove73@gmail.com> Signed-off-by: Thomas Graves <tgraves@apache.org> (cherry picked from commit 52e3cf9) Signed-off-by: Thomas Graves <tgraves@apache.org>
… up cached exchanges for re-use ### What changes were proposed in this pull request? AQE has an optimization where it attempts to reuse compatible exchanges but it does not take into account whether the exchanges are columnar or not, resulting in incorrect reuse under some circumstances. This PR simply changes the key used to lookup cached stages. It now uses the canonicalized form of the new query stage (potentially created by a plugin) rather than using the canonicalized form of the original exchange. ### Why are the changes needed? When using the [RAPIDS Accelerator for Apache Spark](https://github.com/NVIDIA/spark-rapids) we sometimes see a new query stage correctly create a row-based exchange and then Spark replaces it with a cached columnar exchange, which is not compatible, and this causes queries to fail. ### Does this PR introduce _any_ user-facing change? No. ### How was this patch tested? The patch has been tested with the query that highlighted this issue. I looked at writing unit tests for this but it would involve implementing a mock columnar exchange in the tests so would be quite a bit of work. If anyone has ideas on other ways to test this I am happy to hear them. Closes #32195 from andygrove/SPARK-35093. Authored-by: Andy Grove <andygrove73@gmail.com> Signed-off-by: Thomas Graves <tgraves@apache.org> (cherry picked from commit 52e3cf9) Signed-off-by: Thomas Graves <tgraves@apache.org>
thanks @andygrove, thanks everyone for the reviews. |
Hi, All. This seems to break |
Could you check if that is a flakiness or not?
|
I'm looking now |
The tests worked fine for me locally at commit 706f91e. AQE is non-deterministic because query stages can change depending on the order of other stages completing, so this is likely a flakey test. I will investigate further and see how we can make it more robust. |
It looks like this is not a new issue, although potentially the recent change made it more likely to happen. We should probably re-open https://issues.apache.org/jira/browse/SPARK-32304 |
Late LGTM2 |
… up cached exchanges for re-use ### What changes were proposed in this pull request? AQE has an optimization where it attempts to reuse compatible exchanges but it does not take into account whether the exchanges are columnar or not, resulting in incorrect reuse under some circumstances. This PR simply changes the key used to lookup cached stages. It now uses the canonicalized form of the new query stage (potentially created by a plugin) rather than using the canonicalized form of the original exchange. ### Why are the changes needed? When using the [RAPIDS Accelerator for Apache Spark](https://github.com/NVIDIA/spark-rapids) we sometimes see a new query stage correctly create a row-based exchange and then Spark replaces it with a cached columnar exchange, which is not compatible, and this causes queries to fail. ### Does this PR introduce _any_ user-facing change? No. ### How was this patch tested? The patch has been tested with the query that highlighted this issue. I looked at writing unit tests for this but it would involve implementing a mock columnar exchange in the tests so would be quite a bit of work. If anyone has ideas on other ways to test this I am happy to hear them. Closes apache#32195 from andygrove/SPARK-35093. Authored-by: Andy Grove <andygrove73@gmail.com> Signed-off-by: Thomas Graves <tgraves@apache.org> (cherry picked from commit 52e3cf9) Signed-off-by: Thomas Graves <tgraves@apache.org>
… up cached exchanges for re-use ### What changes were proposed in this pull request? AQE has an optimization where it attempts to reuse compatible exchanges but it does not take into account whether the exchanges are columnar or not, resulting in incorrect reuse under some circumstances. This PR simply changes the key used to lookup cached stages. It now uses the canonicalized form of the new query stage (potentially created by a plugin) rather than using the canonicalized form of the original exchange. ### Why are the changes needed? When using the [RAPIDS Accelerator for Apache Spark](https://github.com/NVIDIA/spark-rapids) we sometimes see a new query stage correctly create a row-based exchange and then Spark replaces it with a cached columnar exchange, which is not compatible, and this causes queries to fail. ### Does this PR introduce _any_ user-facing change? No. ### How was this patch tested? The patch has been tested with the query that highlighted this issue. I looked at writing unit tests for this but it would involve implementing a mock columnar exchange in the tests so would be quite a bit of work. If anyone has ideas on other ways to test this I am happy to hear them. Closes apache#32195 from andygrove/SPARK-35093. Authored-by: Andy Grove <andygrove73@gmail.com> Signed-off-by: Thomas Graves <tgraves@apache.org> (cherry picked from commit 52e3cf9) Signed-off-by: Thomas Graves <tgraves@apache.org>
… up cached exchanges for re-use ### What changes were proposed in this pull request? AQE has an optimization where it attempts to reuse compatible exchanges but it does not take into account whether the exchanges are columnar or not, resulting in incorrect reuse under some circumstances. This PR simply changes the key used to lookup cached stages. It now uses the canonicalized form of the new query stage (potentially created by a plugin) rather than using the canonicalized form of the original exchange. ### Why are the changes needed? When using the [RAPIDS Accelerator for Apache Spark](https://github.com/NVIDIA/spark-rapids) we sometimes see a new query stage correctly create a row-based exchange and then Spark replaces it with a cached columnar exchange, which is not compatible, and this causes queries to fail. ### Does this PR introduce _any_ user-facing change? No. ### How was this patch tested? The patch has been tested with the query that highlighted this issue. I looked at writing unit tests for this but it would involve implementing a mock columnar exchange in the tests so would be quite a bit of work. If anyone has ideas on other ways to test this I am happy to hear them. Closes apache#32195 from andygrove/SPARK-35093. Authored-by: Andy Grove <andygrove73@gmail.com> Signed-off-by: Thomas Graves <tgraves@apache.org>
What changes were proposed in this pull request?
AQE has an optimization where it attempts to reuse compatible exchanges but it does not take into account whether the exchanges are columnar or not, resulting in incorrect reuse under some circumstances.
This PR simply changes the key used to lookup cached stages. It now uses the canonicalized form of the new query stage (potentially created by a plugin) rather than using the canonicalized form of the original exchange.
Why are the changes needed?
When using the RAPIDS Accelerator for Apache Spark we sometimes see a new query stage correctly create a row-based exchange and then Spark replaces it with a cached columnar exchange, which is not compatible, and this causes queries to fail.
Does this PR introduce any user-facing change?
No.
How was this patch tested?
The patch has been tested with the query that highlighted this issue. I looked at writing unit tests for this but it would involve implementing a mock columnar exchange in the tests so would be quite a bit of work. If anyone has ideas on other ways to test this I am happy to hear them.