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

Non-polling fetch implementation #15328

Merged
merged 7 commits into from
Feb 6, 2024
Merged

Conversation

ballard26
Copy link
Contributor

@ballard26 ballard26 commented Dec 6, 2023

This PR implements a new fetch_plan_executor that doesn't repeatedly poll every partition in the fetch for new data. Instead it relies on registering callbacks with raft:consensus::visible_offset_monitor to know when a partition has new data and therefore would be worth querying once again.

The gist of how this is implemented is as follows;

  • A fetch "coordinator"(see kafka::nonpolling_fetch_plan_executor::execute_plan) is created on the shard that received the fetch request. This coordinator is responsible for creating fetch workers and determining when a fetch request is completed.
  • A fetch "worker"(see kafka::nonpolling_fetch_plan_executor::shard_fetch_worker) is created on every shard that has a partition from the request. It's responsible for querying partitions for data. And if no partitions have data it'll register with the raft:consensus::visible_offset_monitor for those partitions and wait until it increases for one or more of them. The worker only returns on errors, aborts from the worker, or when it has queried enough data to meet or exceed the lower limit the coordinator specified.

Backports Required

  • none - not a bug fix
  • none - this is a backport
  • none - issue does not exist in previous branches
  • none - papercut/not impactful enough to backport
  • v23.3.x
  • v23.2.x
  • v23.1.x
  • v22.3.x

Release Notes

Improvements

  • Introduces a new non-polling fetch execution strategy that decreases CPU utilization of fetch requests and fetch request latency.
  • Adds a new cluster configuration property fetch_read_strategy. This property determines which fetch execution strategy Redpanda will use to fulfill a fetch request. The newly introduced non_polling execution strategy is the default for this property with the polling strategy being included to make backporting possible.

@ballard26
Copy link
Contributor Author

/dt

@ballard26 ballard26 force-pushed the offset-table branch 3 times, most recently from 88515d5 to 0b7dad1 Compare January 9, 2024 02:06
@github-actions github-actions bot removed the area/rpk label Jan 9, 2024
@ballard26 ballard26 changed the title Draft: Nonpolling fetch implementation Non-polling fetch implementation Jan 9, 2024
@ballard26 ballard26 marked this pull request as ready for review January 9, 2024 02:07
@ballard26 ballard26 assigned ballard26 and unassigned ballard26 Jan 9, 2024
Copy link
Member

@travisdowns travisdowns left a comment

Choose a reason for hiding this comment

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

Looks good to me, but at least some of the test failures look legit with BadLogLines related to the switch to ERROR logging.

As you add cases to handle those, can you also add comments as to why we expect certain error types in that function?

Implements a fetch_plan_executor that doesn't repeatedly poll every partition in the
fetch for new data. Instead it relies on registering callbacks with
raft:consensus::visible_offset_monitor to know when a partition has new
data and therefore would be worth querying once again.
Copy link
Member

@travisdowns travisdowns left a comment

Choose a reason for hiding this comment

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

Awesome, let the new non-polling fetch era begin!

@ballard26 ballard26 merged commit ef31392 into redpanda-data:dev Feb 6, 2024
17 checks passed
@vbotbuildovich
Copy link
Collaborator

/backport v23.3.x

errored_partitions.emplace_back(i, req.ktp().get_partition());
continue;
}
last_visible_indexes[i] = consensus->last_visible_index();
Copy link
Contributor

Choose a reason for hiding this comment

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

FWIW I feel like this is a little error prone. Mostly in this layer we're using kafka offsets (that have gone through translation), but here we explicitly are using raft offsets.

We should probably just prioritize using kafka::offset properly so this footgun is more explicit, but some documentation on this might help.

Copy link
Contributor

Choose a reason for hiding this comment

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

Otherwise a quick look at this PR looks good. Nice work!

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.

None yet

8 participants