-
Notifications
You must be signed in to change notification settings - Fork 311
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
feat(make_idempotent): support making incr
request idempotent in pegasus_write_service
#2192
base: master
Are you sure you want to change the base?
Changes from 5 commits
fb3c1de
0194e3f
99932a6
367ee8e
351fdf7
705d9b9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -136,7 +136,19 @@ class pegasus_write_service : dsn::replication::replica_base | |
const dsn::apps::multi_remove_request &update, | ||
dsn::apps::multi_remove_response &resp); | ||
|
||
// Write INCR record. | ||
// Translate an INCR request into an idempotent PUT request. Only called by primary | ||
// replicas. | ||
int make_idempotent(const dsn::apps::incr_request &req, | ||
dsn::apps::incr_response &err_resp, | ||
dsn::apps::update_request &update); | ||
|
||
// Write an idempotent INCR record (i.e. a PUT record) and reply to the client with INCR | ||
// response. Only called by primary replicas. | ||
int put(const db_write_context &ctx, | ||
const dsn::apps::update_request &update, | ||
dsn::apps::incr_response &resp); | ||
|
||
// Write a non-idempotent INCR record. | ||
int incr(int64_t decree, const dsn::apps::incr_request &update, dsn::apps::incr_response &resp); | ||
|
||
// Write CHECK_AND_SET record. | ||
|
@@ -167,6 +179,8 @@ class pegasus_write_service : dsn::replication::replica_base | |
// Add PUT record in batch write. | ||
// \returns rocksdb::Status::Code. | ||
// NOTE that `resp` should not be moved or freed while the batch is not committed. | ||
// When called by secondary replicas, this put request may be translated from an incr | ||
// request for idempotence. | ||
int batch_put(const db_write_context &ctx, | ||
const dsn::apps::update_request &update, | ||
dsn::apps::update_response &resp); | ||
|
@@ -202,6 +216,12 @@ class pegasus_write_service : dsn::replication::replica_base | |
|
||
uint64_t _batch_start_time; | ||
|
||
// Only used for primary replica to calculate the duration that an incr request from | ||
// the client is translated into an idempotent put request before appended to plog, | ||
// including reading the current value from RocksDB and incrementing it by a given | ||
// amount. | ||
uint64_t _make_incr_idempotent_duration_ns; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a member variable, which will be shared by all requests. But it's a request related latency, isn't it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This variable is defined as per-replica rather than per-request, for the reason that the current design for implementing idempotence is to make sure there is only one atomic request being processed in the write pipeline for each replica. This pipeline consists of the following stages: For a request, this variable will be set in stage (1) and read in stage (4); since there is only one request in the pipeline, this variable is guaranteed not to be set for another request before stage (4) is finished. Therefore, it is safe to define this variable as per-replica. |
||
|
||
capacity_unit_calculator *_cu_calculator; | ||
|
||
METRIC_VAR_DECLARE_counter(put_requests); | ||
|
@@ -224,10 +244,16 @@ class pegasus_write_service : dsn::replication::replica_base | |
METRIC_VAR_DECLARE_percentile_int64(dup_time_lag_ms); | ||
METRIC_VAR_DECLARE_counter(dup_lagging_writes); | ||
|
||
// Record batch size for put and remove requests. | ||
// Measure the size of single-put requests in batch applied into RocksDB for metrics. | ||
uint32_t _put_batch_size; | ||
|
||
// Measure the size of single-remove requests in batch applied into RocksDB for metrics. | ||
uint32_t _remove_batch_size; | ||
|
||
// Measure the size of incr requests (with each translated into an idempotent put request) | ||
// in batch applied into RocksDB for metrics. | ||
uint32_t _incr_batch_size; | ||
|
||
// TODO(wutao1): add metrics for failed rpc. | ||
}; | ||
|
||
|
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.
The function name is not accurate, not only 'clean up', but also update the metrics.
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.
We could name this function
batch_finish()
as opposed tobatch_prepare
: finish batch write with metrics such as latencies calculated and some states cleared.