Skip to content
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

GH-36155: [C++][Go][Java][FlightRPC] Add support for long-running queries #36946

Merged
merged 10 commits into from
Aug 15, 2023

Conversation

kou
Copy link
Member

@kou kou commented Jul 31, 2023

Rationale for this change

In Flight RPC, FlightInfo includes addresses of workers alongside result partition info. This lets clients fetch data directly from workers, in parallel or even distributed across multiple machines. But this also comes with tradeoffs.

Queries generally don't complete instantly (as much as we would like them to). So where can we put the 'query evaluation time'?

  • In GetFlightInfo: block and wait for the query to complete.
    • Con: this is a long-running blocking call, which may fail or time out. Then when the client retries, the server has to redo all the work.
    • Con: parts of the result may be ready before others, but the client can't do anything until everything is ready.
  • In DoGet: return a fixed number of partitions
    • Con: this makes handling worker failures hard. Systems like Trino support fault-tolerant execution by replacing workers at runtime. But GetFlightInfo has already passed, so we can't notify the client of new workers.
    • Con: we have to know or fix the partitioning up front.

Neither solution is optimal.

What changes are included in this PR?

We can address this by adding a retryable version of GetFlightInfo: PollFlightInfo(FlightDescriptor)

PollFlightInfo returns PollInfo:

message PollInfo {
  // The currently available results so far.
  FlightInfo info = 1;
  // The descriptor the client should use on the next try.
  // If unset, the query is complete.
  FlightDescriptor flight_descriptor = 2;
  // Query progress. Must be in [0.0, 1.0] but need not be
  // monotonic or nondecreasing. If unknown, do not set.
  optional double progress = 3;
  // Expiration time for this request. After this passes, the server
  // might not accept the retry descriptor anymore (and the query may
  // be cancelled). This may be updated on a call to PollFlightInfo.
  google.protobuf.Timestamp expiration_time = 4;
}

See the documentation changes for details of them:
http://crossbow.voltrondata.com/pr_docs/36946/format/Flight.html#downloading-data-by-running-a-heavy-query

Are these changes tested?

Yes.

This has C++, Go and Java implementations and an integration test with them.

Are there any user-facing changes?

Yes.

@github-actions
Copy link

⚠️ GitHub issue #36155 has been automatically assigned in GitHub to PR creator.

Copy link
Member

@lidavidm lidavidm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you! I mostly left comments on wording. I can follow up with Java/Python later.

format/Flight.proto Outdated Show resolved Hide resolved
format/Flight.proto Outdated Show resolved Hide resolved
format/Flight.proto Outdated Show resolved Hide resolved
format/Flight.proto Outdated Show resolved Hide resolved
cpp/src/arrow/flight/types.h Outdated Show resolved Hide resolved
@@ -57,6 +57,7 @@ enum class FlightMethod : char {
DoAction = 7,
ListActions = 8,
DoExchange = 9,
PollFlightInfo = 10,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll have to update this in Python (I can put up a PR for that later)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll do this in another PR. Issue for this: #36954

docs/source/format/Flight.rst Outdated Show resolved Hide resolved
docs/source/format/Flight.rst Outdated Show resolved Hide resolved
@github-actions github-actions bot added awaiting merge Awaiting merge and removed awaiting committer review Awaiting committer review labels Jul 31, 2023
@lidavidm
Copy link
Member

Actually, I just realized we didn't add any of the previous proposals to Python, so I filed a separate task for that: #36954

@lidavidm
Copy link
Member

Java: kou#14

Copy link
Member

@zeroshade zeroshade left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM just a style comment

Thanks much for doing the Go side of this!

go/arrow/internal/flight_integration/scenario.go Outdated Show resolved Hide resolved
go/arrow/internal/flight_integration/scenario.go Outdated Show resolved Hide resolved
@github-actions github-actions bot added awaiting changes Awaiting changes awaiting change review Awaiting change review and removed awaiting merge Awaiting merge awaiting changes Awaiting changes labels Jul 31, 2023
@kou
Copy link
Member Author

kou commented Jul 31, 2023

Thanks for suggesting wordings! They are very helpful for me.
I've applied all of them!

I'll update the Go style later.

@kou kou changed the title GH-36155: [C++][Go][FlightRPC] Add support for long-running queries GH-36155: [C++][Go][Java][FlightRPC] Add support for long-running queries Aug 1, 2023
@kou kou force-pushed the flight-long-running-queries branch from 9fb0af3 to 5d71b7d Compare August 1, 2023 08:25
@kou
Copy link
Member Author

kou commented Aug 1, 2023

@github-actions crossbow submit preview-docs

@github-actions github-actions bot added awaiting changes Awaiting changes and removed awaiting change review Awaiting change review labels Aug 1, 2023
@github-actions
Copy link

github-actions bot commented Aug 1, 2023

Revision: 5d71b7d

Submitted crossbow builds: ursacomputing/crossbow @ actions-a21b2bffe3

Task Status
preview-docs Github Actions

@kou
Copy link
Member Author

kou commented Aug 1, 2023

@github-actions github-actions bot added awaiting merge Awaiting merge and removed awaiting changes Awaiting changes labels Aug 1, 2023
Copy link
Contributor

@alamb alamb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TLDR is I read this proposal and it makes sense to me. Thank you for working on this. I only reviewed the proto and text, not the implementations

I left some minor suggested wording changes that I believe increase the precision and clarity of language, but I don't think they are necessary

Nice work

/*
* The information to process a long-running query.
*/
message RetryInfo {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor Editorial point is that calling this "RetryInfo" is somewhat misleading in my mind because it implies to me that the query is being retried, when in reality it is that current execution status that is being retried. Maybe something like "PartialFlightInfo" or something might make it clearer

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. It's a good point.
RetryInfo means info to retry polling but I can understand what you thought.

@lidavidm What do you think about this? My suggestion is PollInfo to align PollFlightInfo().

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PollInfo sounds good.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. I've renamed to PollInfo.

format/Flight.proto Outdated Show resolved Hide resolved
format/Flight.proto Outdated Show resolved Hide resolved
format/Flight.proto Outdated Show resolved Hide resolved
format/Flight.proto Outdated Show resolved Hide resolved
@alamb
Copy link
Contributor

alamb commented Aug 8, 2023

prior to merging this PR I think we need to do a formal vote on the change to the spec on the mailing list

Copy link
Member Author

@kou kou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left some minor suggested wording changes that I believe increase the precision and clarity of language, but I don't think they are necessary

Thanks! It's very helpful! I've merged your suggestions.

prior to merging this PR I think we need to do a formal vote on the change to the spec on the mailing list

Yes. You're right. I'll do it in this week or next:

https://lists.apache.org/thread/qcjpcw6m3p15wqxp6n6rqzlx01v1fl3v

Next:

I'll start a vote for this proposal after we reach a consensus
on this proposal.

/*
* The information to process a long-running query.
*/
message RetryInfo {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. It's a good point.
RetryInfo means info to retry polling but I can understand what you thought.

@lidavidm What do you think about this? My suggestion is PollInfo to align PollFlightInfo().

@github-actions github-actions bot added awaiting changes Awaiting changes and removed awaiting merge Awaiting merge labels Aug 8, 2023
@kou kou force-pushed the flight-long-running-queries branch from b8b1d82 to 419d8cf Compare August 9, 2023 01:14
@github-actions github-actions bot added awaiting change review Awaiting change review and removed awaiting changes Awaiting changes labels Aug 9, 2023
kou and others added 10 commits August 11, 2023 06:04
…ries

In Flight RPC, FlightInfo includes addresses of workers alongside
result partition info. This lets clients fetch data directly from
workers, in parallel or even distributed across multiple machines. But
this also comes with tradeoffs.

Queries generally don't complete instantly (as much as we would like
them to). So where can we put the 'query evaluation time'?

* In `GetFlightInfo`: block and wait for the query to complete.
  * Con: this is a long-running blocking call, which may fail or time
    out. Then when the client retries, the server has to redo all the
    work.
  * Con: parts of the result may be ready before others, but the
    client can't do anything until everything is ready.
* In `DoGet`: return a fixed number of partitions
  * Con: this makes handling worker failures hard. Systems like Trino
    support fault-tolerant execution by replacing workers at
    runtime. But GetFlightInfo has already passed, so we can't notify
    the client of new workers.
  * Con: we have to know or fix the partitioning up front.

Neither solution is optimal.

We can address this by adding a retryable version of
`GetFlightInfo`: `PollFlightInfo(FlightDescriptor)`

`PollFlightInfo` returns `RetryInfo`:

```proto
message RetryInfo {
  // The currently available results so far.
  FlightInfo info = 1;
  // The descriptor the client should use on the next try.
  // If unset, the query is complete.
  FlightDescriptor flight_descriptor = 2;
  // Query progress. Must be in [0.0, 1.0] but need not be
  // monotonic or nondecreasing. If unknown, do not set.
  optional double progress = 3;
  // Expiration time for this request. After this passes, the server
  // might not accept the retry descriptor anymore (and the query may
  // be cancelled). This may be updated on a call to PollFlightInfo.
  google.protobuf.Timestamp expiration_time = 4;
}
```

See the documentation changes for details of them.
Co-authored-by: David Li <[email protected]>
Co-authored-by: Andrew Lamb <[email protected]>
@kou kou force-pushed the flight-long-running-queries branch from 419d8cf to ccbda9d Compare August 10, 2023 21:09
@kou
Copy link
Member Author

kou commented Aug 15, 2023

@kou kou merged commit 107b215 into apache:main Aug 15, 2023
@kou kou deleted the flight-long-running-queries branch August 15, 2023 01:51
@kou kou removed the awaiting change review Awaiting change review label Aug 15, 2023
@conbench-apache-arrow
Copy link

After merging your PR, Conbench analyzed the 5 benchmarking runs that have been run so far on merge-commit 107b215.

There were no benchmark performance regressions. 🎉

The full Conbench report has more details. It also includes information about possible false positives for unstable benchmarks that are known to sometimes produce them.

loicalleyne pushed a commit to loicalleyne/arrow that referenced this pull request Nov 13, 2023
…ng queries (apache#36946)

### Rationale for this change

In Flight RPC, FlightInfo includes addresses of workers alongside result partition info. This lets clients fetch data directly from workers, in parallel or even distributed across multiple machines. But this also comes with tradeoffs.

Queries generally don't complete instantly (as much as we would like them to). So where can we put the 'query evaluation time'?

* In `GetFlightInfo`: block and wait for the query to complete.
  * Con: this is a long-running blocking call, which may fail or time out. Then when the client retries, the server has to redo all the work.
  * Con: parts of the result may be ready before others, but the client can't do anything until everything is ready.
* In `DoGet`: return a fixed number of partitions
  * Con: this makes handling worker failures hard. Systems like Trino support fault-tolerant execution by replacing workers at runtime. But GetFlightInfo has already passed, so we can't notify the client of new workers.
  * Con: we have to know or fix the partitioning up front.

Neither solution is optimal.

### What changes are included in this PR?

We can address this by adding a retryable version of `GetFlightInfo`: `PollFlightInfo(FlightDescriptor)`

`PollFlightInfo` returns `PollInfo`:

```proto
message PollInfo {
  // The currently available results so far.
  FlightInfo info = 1;
  // The descriptor the client should use on the next try.
  // If unset, the query is complete.
  FlightDescriptor flight_descriptor = 2;
  // Query progress. Must be in [0.0, 1.0] but need not be
  // monotonic or nondecreasing. If unknown, do not set.
  optional double progress = 3;
  // Expiration time for this request. After this passes, the server
  // might not accept the retry descriptor anymore (and the query may
  // be cancelled). This may be updated on a call to PollFlightInfo.
  google.protobuf.Timestamp expiration_time = 4;
}
```

See the documentation changes for details of them:
http://crossbow.voltrondata.com/pr_docs/36946/format/Flight.html#downloading-data-by-running-a-heavy-query

### Are these changes tested?

Yes.

This has C++, Go and Java implementations and an integration test with them.

### Are there any user-facing changes?

Yes.
* Closes: apache#36155

Lead-authored-by: Sutou Kouhei <[email protected]>
Co-authored-by: Sutou Kouhei <[email protected]>
Co-authored-by: David Li <[email protected]>
Co-authored-by: Andrew Lamb <[email protected]>
Signed-off-by: Sutou Kouhei <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[C++][Go][Java][FlightRPC] Add support for long-running queries
4 participants