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

Add isPartialResult flag to broker response #11592

Merged
merged 5 commits into from
Oct 30, 2023

Conversation

saurabhd336
Copy link
Contributor

A new flag to the broker response that explicitly denotes whether or not the result being returned is partial or not. This builds on top of PRs merged to resolve #7264

@codecov-commenter
Copy link

codecov-commenter commented Sep 14, 2023

Codecov Report

Merging #11592 (08654b0) into master (025038a) will decrease coverage by 1.60%.
Report is 18 commits behind head on master.
The diff coverage is 62.50%.

@@             Coverage Diff              @@
##             master   #11592      +/-   ##
============================================
- Coverage     62.98%   61.39%   -1.60%     
+ Complexity     1141      207     -934     
============================================
  Files          2367     2373       +6     
  Lines        127958   128284     +326     
  Branches      19744    19804      +60     
============================================
- Hits          80593    78755    -1838     
- Misses        41630    43850    +2220     
+ Partials       5735     5679      -56     
Flag Coverage Δ
custom-integration1 <0.01% <0.00%> (-0.01%) ⬇️
integration <0.01% <0.00%> (-0.01%) ⬇️
integration1 <0.01% <0.00%> (-0.01%) ⬇️
integration2 0.00% <0.00%> (ø)
java-11 61.35% <62.50%> (-1.57%) ⬇️
java-21 61.25% <62.50%> (-1.58%) ⬇️
skip-bytebuffers-false 61.37% <62.50%> (-1.57%) ⬇️
skip-bytebuffers-true 61.24% <62.50%> (-1.57%) ⬇️
temurin 61.39% <62.50%> (-1.60%) ⬇️
unittests 61.38% <62.50%> (-1.60%) ⬇️
unittests1 46.67% <100.00%> (-20.33%) ⬇️
unittests2 27.55% <12.50%> (+13.09%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files Coverage Δ
...t/common/response/broker/BrokerResponseNative.java 94.02% <100.00%> (+0.13%) ⬆️
...n/java/org/apache/pinot/client/ExecutionStats.java 62.50% <50.00%> (-0.66%) ⬇️
...roker/requesthandler/BaseBrokerRequestHandler.java 46.00% <0.00%> (-0.10%) ⬇️

... and 225 files with indirect coverage changes

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

@siddharthteotia
Copy link
Contributor

I thought this was already being returned as part of execution stats. I remember there was a flag hasPartialResults. How is this different ?

Comment on lines 200 to 201
brokerResponse.setPartialResult(true);
brokerResponse.addToExceptions(new QueryProcessingException(QueryException.SERVER_SEGMENT_MISSING_ERROR_CODE,
Copy link
Contributor

Choose a reason for hiding this comment

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

If some servers are not available we currently used to throw an Exception instead of the results
So likely this won't be required as we have an exception stating which servers are in error

@Jackie-Jiang Jackie-Jiang added enhancement release-notes Referenced by PRs that need attention when compiling the next release notes labels Sep 19, 2023
Copy link
Contributor

@Jackie-Jiang Jackie-Jiang left a comment

Choose a reason for hiding this comment

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

I don't see partial result being added when server returns exception. Did I miss it somewhere?

@@ -607,6 +607,7 @@ protected BrokerResponse handleRequest(long requestId, String query, @Nullable S
int numUnavailableSegments = unavailableSegments.size();
requestContext.setNumUnavailableSegments(numUnavailableSegments);

boolean isPartialResult = false;
Copy link
Contributor

@walterddr walterddr Sep 21, 2023

Choose a reason for hiding this comment

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

what is the "partial result" definition? for example if grouplimits reached for order by queries do we consider that as partial results?

i guess the question is when do we set the flag for:

  1. result is correct (this is no flag)
  2. result is correct but we didn't look at the entire table (e.g. select * limit 1000)
  3. result is not correct but each row is correct (e.g. select ... group by key order by COUNT(*))
  4. result is not correct, some rows might be correct some rows might not due to data size limit (select ... join ... group by ... when join hits maxRow limit, grouping result might be partial)
  5. result is incorrect (we shouldn't return in this case)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@walterddr my idea with this flag is to generally cover all cases where we do sent a response back (no failures), but we also know either some segments / servers were not queried (segment unavailability / server down etc) or some rows / groups were ignored.

  1. result is correct (this is no flag)

  2. result is correct but we didn't look at the entire table (e.g. select * limit 1000) -> I don't think this should be flagged as partial result since the result is correct, we don't have to look the entire table up

  3. result is not correct but each row is correct (e.g. select ... group by key order by COUNT(*)) -> I'm not sure if there is a way of knowing this in the current server -> broker response? If yes, then I do think we should flag this a partial result. I may not have full context, but is it the trimming of cross segment groups to max(limit * 5, DEFAULT_MIN_NUM_GROUPS) that you're referring to?

  4. result is not correct, some rows might be correct some rows might not due to data size limit (select ... join ... group by ... when join hits maxRow limit, grouping result might be partial) -> Yes this should classify as partialResponse imo

  5. result is incorrect (we shouldn't return in this case) -> What do you mean by incorrect here?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think general definition (and this is what we did in the current engine IIRC) is that partialResults flag would be set to true in either of the following:

  • Result is incomplete (determined by server based on things like GROUP BY heuristics, threshold etc)
  • Not all servers queried responded (determine by broker)

Basically when we are able to determine that there was more data to be processed but we couldn't either because of our own algorithms (heuristics / thresholds etc) or failed to hear back from servers.

I think (1) can also be determined by broker during merge.

For SELECT with ORDER BY, I don't think we ever set partialResults on server and there is no need imo.

For SELECT without ORDER BY, servers do early termination based on LIMIT N, but again partialResults is not set and there is no need.

@saurabhd336
Copy link
Contributor Author

@Jackie-Jiang @siddharthteotia @walterddr @eaugene
I've updated the PR as per the comments and some internal discussions
Partial response is defined as the case when pinot responds with a result, but is also aware that the result being returned has not considered all the data it should have. Cases that qualify as partial

  1. Not all segments queried by the broker due to unavaliable segments / unavaliable servers
  2. Not all servers responded (either no response or exceptions)
  3. Other algorithm limitations like numGroupsLimitReached.

brokerResponse.addToExceptions(new QueryProcessingException(QueryException.SERVER_NOT_RESPONDING_ERROR_CODE,
String.format("%d servers %s not responded", numServersNotResponded, serversNotResponded)));
_brokerMetrics.addMeteredTableValue(rawTableName, BrokerMeter.BROKER_RESPONSES_WITH_PARTIAL_SERVERS_RESPONDED, 1);
}
if (totalServersFailedOrNotResponded > 0) {
Copy link
Contributor

@walterddr walterddr Oct 16, 2023

Choose a reason for hiding this comment

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

why do we need this? we can simply do

Suggested change
if (totalServersFailedOrNotResponded > 0) {
if (numServersQueried - numServersResponded > 0) {

if there's any exception inside the response, i thought the broker reducer is going to rectify and add proper partial result or failure inside?

for example if it is a SELECT * FROM tbl LIMIT 10 then

  • original logic: selection reducer will not tag partial response as long as there's 1 server returns more than 10 rows
  • in this PR: it will tag as long as 1 server returns an exception

is that the intention?

Copy link
Contributor

Choose a reason for hiding this comment

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

chatted with @Jackie-Jiang offline. i think the idea is to set this as "partial response" even when the results are completely correct. we still want to surface a global "flag" indicating that 'something can be improved underneath'.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Jackie-Jiang @walterddr This was added to make sure any exceptions in the returned dataTable (even if the server has responded with a valid set of rows), are also flagged as potentially partial

Copy link
Contributor

Choose a reason for hiding this comment

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

This should not be handled here. We can simply check if (brokerResponse.getExceptionsSize() > 0) in the end in BaseBrokerRequestHandler and set the flag.

@Jackie-Jiang
Copy link
Contributor

@Jackie-Jiang @siddharthteotia @walterddr @eaugene I've updated the PR as per the comments and some internal discussions Partial response is defined as the case when pinot responds with a result, but is also aware that the result being returned has not considered all the data it should have. Cases that qualify as partial

  1. Not all segments queried by the broker due to unavaliable segments / unavaliable servers
  2. Not all servers responded (either no response or exceptions)
  3. Other algorithm limitations like numGroupsLimitReached.

@saurabhd336 We should count the result as partial if there are exceptions in the server response even if the server responded. One example would be when some segments dropped due to schema mismatch on the server side.

@walterddr
Copy link
Contributor

i think there's just one situation when server returns no exception but we still want to set the partial results flag --> that's numGroupsLimitReach flag, which is only a boolean flag in the data table but not part of exception. if we can rectify this we should be good to only look at exceptions?

@Jackie-Jiang
Copy link
Contributor

i think there's just one situation when server returns no exception but we still want to set the partial results flag --> that's numGroupsLimitReach flag, which is only a boolean flag in the data table but not part of exception. if we can rectify this we should be good to only look at exceptions?

We don't want to model it as an exception because it can happen in happy path, and some client might simply count query with exception as failure

@saurabhd336
Copy link
Contributor Author

@Jackie-Jiang as per the discussion above, does the PR look ok to you?

brokerResponse.addToExceptions(new QueryProcessingException(QueryException.SERVER_NOT_RESPONDING_ERROR_CODE,
String.format("%d servers %s not responded", numServersNotResponded, serversNotResponded)));
_brokerMetrics.addMeteredTableValue(rawTableName, BrokerMeter.BROKER_RESPONSES_WITH_PARTIAL_SERVERS_RESPONDED, 1);
}
if (totalServersFailedOrNotResponded > 0) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This should not be handled here. We can simply check if (brokerResponse.getExceptionsSize() > 0) in the end in BaseBrokerRequestHandler and set the flag.

Comment on lines 644 to 645
// If segments are unavailable, the result should be considered partial
isPartialResult = true;
Copy link
Contributor

Choose a reason for hiding this comment

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

We don't need to update it here. We may set the value in the end by checking if the response contains exceptions

@Jackie-Jiang Jackie-Jiang merged commit b4774c2 into apache:master Oct 30, 2023
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement release-notes Referenced by PRs that need attention when compiling the next release notes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add exception to broker response when not all segments are available (partial response)
6 participants