Skip to content

Commit 491546e

Browse files
authored
docs(bigtable): add page describing retry policies (#11955)
1 parent 1de2f07 commit 491546e

3 files changed

Lines changed: 201 additions & 0 deletions

File tree

google/cloud/bigtable/doc/bigtable-main.dox

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ library.
3737
This can be an effective approach to diagnose runtime problems.
3838
- @ref bigtable-endpoint-example
3939
- @ref bigtable-auth-example
40+
- @ref bigtable-override-retry
4041
- @ref bigtable-mocking "Mocking the Cloud Bigtable C++ client"
4142
- The [Setting up your development environment] guide describes how to set up
4243
a C++ development environment in various platforms, including the Google Cloud
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
/*!
2+
3+
@page bigtable-override-retry Override Retry, Backoff, and Idempotency Policies
4+
5+
When it is safe to do so, the library automatically retries requests that fail
6+
due to a transient error. The library then uses [exponential backoff] to backoff
7+
before trying again. Which operations are considered safe to retry, which
8+
errors are treated as transient failures, the details of the exponential backoff
9+
algorithm, and for how long the library retries are all configurable via
10+
policies.
11+
12+
This document provides examples showing how to override the default policies.
13+
14+
The policies can be set when a [`DataConnection`],
15+
[`BigtableInstanceAdminConnection`], or [`BigtableTableAdminConnection`]
16+
object is created. The library provides default policies for any policy that
17+
is not set.
18+
19+
The application can also override some (or all) policies when the corresponding
20+
[`Table`], [`BigtableInstanceAdminClient`], or [`BigtableTableAdminClient`]
21+
object is created. This can be useful if multiple `Table` (or `*Client`) objects
22+
share the same `*Connection` object, but you want different retry behavior in
23+
some of the clients.
24+
25+
Finally, the application can override some retry policies when calling a
26+
specific member function.
27+
28+
The library uses three different options to control the retry loop. The options
29+
have per-client names
30+
31+
@section bigtable-override-retry-retry-policy Configuring the transient errors and retry duration
32+
33+
The `*RetryPolicyOption` controls:
34+
35+
- Which errors are to be treated as transient errors.
36+
- How long the library will keep retrying transient errors.
37+
38+
You can provide your own class for this option. The library also provides two
39+
built-in policies:
40+
41+
- `*LimitedErrorCountRetryPolicy`: stops retrying after a specified number
42+
of transient errors.
43+
- `*LimitedTimeRetryPolicy`: stops retrying after a specified time.
44+
45+
Note that a library may have more than one version of these classes. Their name
46+
match the `*Client` and `*Connection` object they are intended to be used
47+
with. Some `*Client` objects treat different error codes as transient errors.
48+
In most cases, only [kUnavailable](@ref google::cloud::StatusCode) is treated
49+
as a transient error.
50+
51+
@see google::cloud::bigtable::DataRetryPolicyOption
52+
@see google::cloud::bigtable::DataRetryPolicy
53+
@see google::cloud::bigtable::DataLimitedTimeRetryPolicy
54+
@see google::cloud::bigtable::DataLimitedErrorCountRetryPolicy
55+
@see google::cloud::bigtable_admin::BigtableTableAdminRetryPolicy
56+
@see google::cloud::bigtable_admin::BigtableInstanceAdminRetryPolicy
57+
58+
@section bigtable-override-retry-backoff-policy Controlling the backoff algorithm
59+
60+
The `*BackoffPolicyOption` controls how long the client library will wait
61+
before retrying a request that failed with a transient error. You can provide
62+
your own class for this option.
63+
64+
The only built-in backoff policy is
65+
[`ExponentialBackoffPolicy`](@ref google::cloud::ExponentialBackoffPolicy).
66+
This class implements a truncated exponential backoff algorithm, with jitter.
67+
In summary, it doubles the current backoff time after each failure. The actual
68+
backoff time for an RPC is chosen at random, but never exceeds the current
69+
backoff. The current backoff is doubled after each failure, but never exceeds
70+
(or is "truncated") if it reaches a prescribed maximum.
71+
72+
@see google::cloud::bigtable::DataBackoffPolicyOption
73+
@see google::cloud::bigtable_admin::BigtableTableAdminBackoffPolicyOption
74+
@see google::cloud::bigtable_admin::BigtableInstanceAdminBackoffPolicyOption
75+
76+
@section bigtable-override-retry-idempotency-policy Controlling which operations are retryable
77+
78+
The `*IdempotencyPolicyOption` controls which requests are retryable, as some
79+
requests are never safe to retry.
80+
81+
Only one built-in idempotency policy is provided by the library. The name
82+
matches the name of the client it is intended for. For example,
83+
`BigtableTableAdminClient` will use
84+
`BigtableTableAdminConnectionIdempotencyPolicy`.
85+
86+
In the case of data operations, only mutations need to be considered.
87+
The [`Table`] class uses [`IdempotentMutationPolicy`]. Mutations that use
88+
server-assigned timestamps are not considered idempotent by default. Mutations
89+
that use client-assigned timestamps are idempontent by default.
90+
91+
@see google::cloud::bigtable::IdempotentMutationPolicy
92+
@see google::cloud::bigtable::IdempotentMutationPolicyOption
93+
@see google::cloud::bigtable_admin::BigtableTableAdminConnectionIdempotencyPolicy
94+
@see google::cloud::bigtable_admin::BigtableTableAdminConnectionIdempotencyPolicyOption
95+
@see google::cloud::bigtable_admin::BigtableInstanceAdminConnectionIdempotencyPolicy
96+
@see google::cloud::bigtable_admin::BigtableInstanceAdminConnectionIdempotencyPolicyOption
97+
98+
@section bigtable-override-retry-example Example
99+
100+
For example, this will override the retry policies for `bigtable::Table`:
101+
102+
@snippet client_samples.cc set-retry-policy
103+
104+
105+
Follow these links to find examples for other `*Client` classes:
106+
107+
- [\c BigtableInstanceAdminClient](@ref admin::BigtableInstanceAdminClient-retry-snippet)
108+
- [\c BigtableTableAdminClient](@ref admin::BigtableTableAdminClient-retry-snippet)
109+
110+
@section bigtable-override-retry-more-information More Information
111+
112+
@see google::cloud::Options
113+
@see google::cloud::BackoffPolicy
114+
@see google::cloud::ExponentialBackoffPolicy
115+
116+
[exponential backoff]: https://en.wikipedia.org/wiki/Exponential_backoff
117+
[`DataConnection`]: @ref google::cloud::bigtable::DataConnection
118+
[`Table`]: @ref google::cloud::bigtable::Table
119+
[`BigtableInstanceAdminConnection`]: @ref google::cloud::bigtable_admin::BigtableInstanceAdminConnection
120+
[`BigtableInstanceAdminClient`]: @ref google::cloud::bigtable_admin::BigtableInstanceAdminClient
121+
[`BigtableTableAdminConnection`]: @ref google::cloud::bigtable_admin::BigtableTableAdminConnection
122+
[`BigtableTableAdminClient`]: @ref google::cloud::bigtable_admin::BigtableTableAdminClient
123+
[`IdempotentMutationPolicy`]: @ref google::cloud::bigtable::IdempotentMutationPolicy
124+
125+
*/
126+
127+
/*! @page admin::BigtableInstanceAdminClient-retry-snippet Override admin::BigtableInstanceAdminClient Retry Policies
128+
129+
This shows how to override the retry policies for admin::BigtableInstanceAdminClient:
130+
131+
@snippet google/cloud/bigtable/admin/samples/bigtable_instance_admin_client_samples.cc set-retry-policy
132+
133+
Assuming you have created a custom idempotency policy. Such as:
134+
135+
@snippet google/cloud/bigtable/admin/samples/bigtable_instance_admin_client_samples.cc custom-idempotency-policy
136+
137+
*/
138+
139+
/*! @page admin::BigtableTableAdminClient-retry-snippet Override admin::BigtableTableAdminClient Retry Policies
140+
141+
This shows how to override the retry policies for admin::BigtableTableAdminClient:
142+
143+
@snippet google/cloud/bigtable/admin/samples/bigtable_table_admin_client_samples.cc set-retry-policy
144+
145+
Assuming you have created a custom idempotency policy. Such as:
146+
147+
@snippet google/cloud/bigtable/admin/samples/bigtable_table_admin_client_samples.cc custom-idempotency-policy
148+
149+
*/

google/cloud/bigtable/examples/client_samples.cc

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,53 @@ void TableSetEndpoint(std::vector<std::string> const& argv) {
4545
(argv.at(0), argv.at(1), argv.at(2));
4646
}
4747

48+
void SetRetryPolicy(std::vector<std::string> const& argv) {
49+
if (argv.size() != 3) {
50+
throw google::cloud::testing_util::Usage{
51+
"set-retry-policy <project-id> <instance-id> <table-id>"};
52+
}
53+
//! [set-retry-policy]
54+
namespace cbt = google::cloud::bigtable;
55+
[](std::string const& project_id, std::string const& instance_id,
56+
std::string const& table_id) {
57+
auto options = google::cloud::Options{}
58+
.set<cbt::IdempotentMutationPolicyOption>(
59+
cbt::AlwaysRetryMutationPolicy().clone())
60+
.set<cbt::DataRetryPolicyOption>(
61+
cbt::DataLimitedErrorCountRetryPolicy(3).clone())
62+
.set<cbt::DataBackoffPolicyOption>(
63+
google::cloud::ExponentialBackoffPolicy(
64+
/*initial_delay=*/std::chrono::milliseconds(200),
65+
/*maximum_delay=*/std::chrono::seconds(45),
66+
/*scaling=*/2.0)
67+
.clone());
68+
auto connection = cbt::MakeDataConnection(options);
69+
70+
auto const table_name =
71+
cbt::TableResource(project_id, instance_id, table_id);
72+
// c1 and c2 share the same retry policies
73+
auto c1 = cbt::Table(connection, table_name);
74+
auto c2 = cbt::Table(connection, table_name);
75+
76+
// You can override any of the policies in a new client. This new client
77+
// will share the policies from c1 (or c2) *except* from the retry policy.
78+
auto c3 = cbt::Table(
79+
connection, table_name,
80+
google::cloud::Options{}.set<cbt::DataRetryPolicyOption>(
81+
cbt::DataLimitedTimeRetryPolicy(std::chrono::minutes(5)).clone()));
82+
83+
// You can also override the policies in a single call. In this case, we
84+
// allow no retries.
85+
auto result =
86+
c3.ReadRow("my-key", cbt::Filter::PassAllFilter(),
87+
google::cloud::Options{}.set<cbt::DataRetryPolicyOption>(
88+
cbt::DataLimitedErrorCountRetryPolicy(0).clone()));
89+
(void)result; // ignore errors in this example
90+
}
91+
//! [set-retry-policy]
92+
(argv.at(0), argv.at(1), argv.at(2));
93+
}
94+
4895
void TableWithServiceAccount(std::vector<std::string> const& argv) {
4996
namespace examples = ::google::cloud::testing_util;
5097
if (argv.size() != 4) {
@@ -94,6 +141,9 @@ void AutoRun(std::vector<std::string> const& argv) {
94141
std::cout << "\nRunning TableWithServiceAccount() sample" << std::endl;
95142
TableWithServiceAccount({project_id, instance_id, table_id, keyfile});
96143

144+
std::cout << "\nRunning SetRetryPolicy() sample" << std::endl;
145+
SetRetryPolicy({project_id, instance_id, table_id});
146+
97147
std::cout << "\nAutoRun done" << std::endl;
98148
}
99149

@@ -102,6 +152,7 @@ void AutoRun(std::vector<std::string> const& argv) {
102152
int main(int argc, char* argv[]) { // NOLINT(bugprone-exception-escape)
103153
google::cloud::testing_util::Example example({
104154
{"table-set-endpoint", TableSetEndpoint},
155+
{"set-retry-policy", SetRetryPolicy},
105156
{"table-with-service-account", TableWithServiceAccount},
106157
{"auto", AutoRun},
107158
});

0 commit comments

Comments
 (0)