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

Support making atomic write requests idempotent #2197

Open
3 tasks done
empiredan opened this issue Feb 21, 2025 · 0 comments
Open
3 tasks done

Support making atomic write requests idempotent #2197

empiredan opened this issue Feb 21, 2025 · 0 comments
Labels
type/enhancement Indicates new feature requests

Comments

@empiredan
Copy link
Contributor

empiredan commented Feb 21, 2025

Motivation

Pegasus does not support duplicating atomic write requests including incr, check_and_set and check_and_mutate since they are not idempotent. In practice, various applications use atomic write interfaces in many scenarios. However, such applications cannot use duplication to synchronize data, and therefore cannot benefit from the high performance that duplication provides.

Design

Due to the urgency of the requirements, the first version of the idempotent implementation for the atomic writes should be as simple as possible, without making fundamental changes to the write path.

Therefore, we decided to implement the idempotence of atomic write requests as follows: for each replica, ensure that only one atomic write request is being processed in the write pipeline at any given time. Once the replica server receives an atomic request, firstly it will be cached. It will not be pushed into the write pipeline until all requests before it have been applied. The write pipeline consists of the following stages:

  1. read the current value from RocksDB, calculate the final value according to specific semantics of requested atomic write and build the idempotent request based on it;
  2. append the corresponding mutation to plog;
  3. broadcast the prepare requests to the secondary replicas;
  4. apply the final result back to RocksDB ultimately;

The primary replicas have all 1 ~ 4 stages, and at last reply to the client while the secondary replicas only have stages 2 and 4.

Task List

Making incr requests idempotent:

@empiredan empiredan added the type/enhancement Indicates new feature requests label Feb 21, 2025
empiredan added a commit that referenced this issue Feb 21, 2025
…egasus_server_write` and `replication_app_base` (#2196)

#2197

To support idempotence, a new interface `make_idempotent()` is introduced and
an existing interface `on_batched_write_requests()` is changed for both the classes
`pegasus_server_write` and `replication_app_base`. This is different from what we
have done for `pegasus_write_service` and `pegasus_write_service::impl`, both of
which provide `make_idempotent()` and `put()` by the following PRs:
- #2185
- #2192

`make_idempotent()` for `replication_app_base` is provided as a virtual function
called by primary replicas, implemented internally by `pegasus_server_impl` and
`pegasus_server_write`. `on_batched_write_requests`  for `replication_app_base`
is the same. It is changed with a new parameter `original_request` added. It is just
the original request received from the client. It must be an atomic request (i.e. `incr`,
`check_and_set` and `check_and_mutate`) if it is non-null, and used to decide if a
write request is atomic and generate the response corresponding to the atomic write
request.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type/enhancement Indicates new feature requests
Projects
None yet
Development

No branches or pull requests

1 participant