Skip to content

Redis cluster read replica#7496

Merged
mattklein123 merged 16 commits intoenvoyproxy:masterfrom
HenryYYang:redis-cluster-read-replica
Aug 15, 2019
Merged

Redis cluster read replica#7496
mattklein123 merged 16 commits intoenvoyproxy:masterfrom
HenryYYang:redis-cluster-read-replica

Conversation

@HenryYYang
Copy link
Copy Markdown
Contributor

@HenryYYang HenryYYang commented Jul 8, 2019

Description: Add read policy to redis proxy config. Here's the definition of ReadPolicy and descriptions for each option.

// All ReadPolicy settings except MASTER may return stale data because replicas replication is
// asynchronous and requires some delay. You need to ensure that your application can tolerate
// stale data.
enum ReadPolicy {
  // Default mode. Read from the current master node.
  MASTER = 0;
  // Read from the master, but if it is unavailable, read from replica nodes.
  PREFER_MASTER = 1;
  // Read from replica nodes.
  REPLICA = 2;
  // Read from the replica nodes, but if none is unavailable, read from the master.
  PREFER_REPLICA = 3;
  // Read from any node of the cluster.
  ANY = 4;
}

Risk Level: Medium, the default will be MASTER which is same as existing case.
Testing: Added unit tests, more integration test to follow.
Docs Changes:
Release Notes:
[Optional Fixes #Issue]
[Optional Deprecated:]

Signed-off-by: Henry Yang <hyang@lyft.com>
Signed-off-by: Henry Yang <hyang@lyft.com>
@mattklein123
Copy link
Copy Markdown
Member

@msukalski for first pass.

/wait

Signed-off-by: Henry Yang <hyang@lyft.com>
Signed-off-by: Henry Yang <hyang@lyft.com>
Signed-off-by: Henry Yang <hyang@lyft.com>
@msukalski
Copy link
Copy Markdown
Contributor

I'll take a look at this this weekend.

Copy link
Copy Markdown
Contributor

@msukalski msukalski left a comment

Choose a reason for hiding this comment

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

Overall, it looks pretty good at this stage.

// defaults to 3ms.
google.protobuf.Duration buffer_flush_timeout = 5 [(gogoproto.stdduration) = true];

// All ReadPolicy settings except MASTER may return stale data because replicas replication is
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: "replicas" appears redundant.

current = slot_array_;
// The slots is sorted, allowing for a quick comparison to make sure we need to update the slot
// array sort based on start and end to enable efficient comparison
sort(slots->begin(), slots->end(), [](const ClusterSlot& lhs, const ClusterSlot& rhs) -> bool {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It's not particularly clear whether this sort() is worth it. Mostly I don't see any ordering dependencies in this code that the sort() might alleviate. Your thoughts, please?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The sort() is useful for the current_cluster_slot_ && *current_cluster_slot_ == *slots.

Let's say K(16384) slots are broken down to M ranges which are assigned to N shards(1 master + 0-n replicas). M and N should normally be < 100 except for the largest clusters.

If we sort the M ranges based on the start and end for each range, then the comparison of whether allocation is changed is O(M log M) + O(M) without allocating additional space. I can't be certain that "Cluster Slots" return a sorted range, as that's not part of the contract. If it does return a sorted range, the sort function is going to be O(M) in most implementations, then it's a small cost to pay.

if (!shard->replicas_.healthyHosts().empty()) {
return chooseRandomHost(shard->replicas_, random_);
} else {
return chooseRandomHost(shard->all_hosts_, random_);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is there a reason for the lack of symmetry with respect to PreferMaster? In other words, why does the no replicas available in this scenario not return shard->master_ instead of chooseRandomHost(shard->all_hosts_, random_)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

by doing chooseRandomHost(shard->all_hosts_, random_) will make sure that we pick a random host if the master and replicas are all unhealthy. If only the master is healthy, then that's the host that will be picked.

}
// Any connection to replica requires the READONLY command in order to perform read.
// Also the READONLY command is a no-opt for the master.
// We only need to send the READONLY command iff it's possible that the host is a replica.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this is a valid conclusion after looking at the redis 4 server code.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks for verifying

@stale
Copy link
Copy Markdown

stale bot commented Jul 29, 2019

This pull request has been automatically marked as stale because it has not had activity in the last 7 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions!

@stale stale bot added the stale stalebot believes this issue/PR has not been touched recently label Jul 29, 2019
…k status change.

Signed-off-by: Henry Yang <hyang@lyft.com>
@stale stale bot removed the stale stalebot believes this issue/PR has not been touched recently label Jul 31, 2019
@repokitteh-read-only
Copy link
Copy Markdown

CC @envoyproxy/api-shepherds: Your approval is needed for changes made to api/.

🐱

Caused by: #7496 was synchronize by HenryYYang.

see: more, trace.

@HenryYYang HenryYYang changed the title WIP: Redis cluster read replica Redis cluster read replica Jul 31, 2019
Signed-off-by: Henry Yang <hyang@lyft.com>
@repokitteh-read-only
Copy link
Copy Markdown

CC @envoyproxy/api-shepherds: Your approval is needed for changes made to api/.

🐱

Caused by: #7496 was synchronize by HenryYYang.

see: more, trace.

@htuch
Copy link
Copy Markdown
Member

htuch commented Jul 31, 2019

@envoyproxy/api-shepherds API LGTM

@repokitteh-read-only
Copy link
Copy Markdown

CC @envoyproxy/api-shepherds: Your approval is needed for changes made to api/.

🐱

Caused by: #7496 was synchronize by HenryYYang.

see: more, trace.

@repokitteh-read-only
Copy link
Copy Markdown

CC @envoyproxy/api-shepherds: Your approval is needed for changes made to api/.

🐱

Caused by: #7496 was synchronize by HenryYYang.

see: more, trace.

@repokitteh-read-only
Copy link
Copy Markdown

CC @envoyproxy/api-shepherds: Your approval is needed for changes made to api/.

🐱

Caused by: #7496 was synchronize by HenryYYang.

see: more, trace.

HenryYYang and others added 6 commits August 14, 2019 11:55
Signed-off-by: Henry Yang <hyang@lyft.com>
Signed-off-by: Henry Yang <hyang@lyft.com>
Signed-off-by: Henry Yang <hyang@lyft.com>
Co-Authored-By: Matt Klein <mattklein123@gmail.com>
Signed-off-by: Henry Yang <hyang@lyft.com>
Co-Authored-By: Matt Klein <mattklein123@gmail.com>
Signed-off-by: Henry Yang <hyang@lyft.com>
Co-Authored-By: Matt Klein <mattklein123@gmail.com>
Signed-off-by: Henry Yang <hyang@lyft.com>
@HenryYYang HenryYYang force-pushed the redis-cluster-read-replica branch from 5ea702e to 5909e01 Compare August 14, 2019 18:57
@repokitteh-read-only
Copy link
Copy Markdown

CC @envoyproxy/api-shepherds: Your approval is needed for changes made to api/.

🐱

Caused by: #7496 was synchronize by HenryYYang.

see: more, trace.

Signed-off-by: Henry Yang <hyang@lyft.com>
@repokitteh-read-only
Copy link
Copy Markdown

CC @envoyproxy/api-shepherds: Your approval is needed for changes made to api/.

🐱

Caused by: #7496 was synchronize by HenryYYang.

see: more, trace.

Signed-off-by: Henry Yang <hyang@lyft.com>
@repokitteh-read-only
Copy link
Copy Markdown

CC @envoyproxy/api-shepherds: Your approval is needed for changes made to api/.

🐱

Caused by: #7496 was synchronize by HenryYYang.

see: more, trace.

@mattklein123
Copy link
Copy Markdown
Member

Please merge master.

/wait

Signed-off-by: Henry Yang <hyang@lyft.com>
@repokitteh-read-only
Copy link
Copy Markdown

CC @envoyproxy/api-shepherds: Your approval is needed for changes made to api/.

🐱

Caused by: #7496 was synchronize by HenryYYang.

see: more, trace.

Copy link
Copy Markdown
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

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

Nice, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants