Skip to content
Merged
Show file tree
Hide file tree
Changes from 89 commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
6dcb8de
Add cluster factory interface and implementation for the existing clu…
HenryYYang Feb 18, 2019
1ac5471
Add configurable factory
HenryYYang Feb 20, 2019
b4253c2
Fix format issues
HenryYYang Feb 20, 2019
3e056bb
make cluster type oneof
HenryYYang Feb 21, 2019
f5420ee
Fix format error.
HenryYYang Feb 21, 2019
d3a9004
Add integration tests
HenryYYang Feb 27, 2019
759e505
Updated comments and docs.
HenryYYang Feb 27, 2019
789316a
Merge branch 'master' into add-cluster-extension
HenryYYang Feb 28, 2019
e7b1625
Merge remote-tracking branch 'origin' into add-cluster-extension
HenryYYang Feb 28, 2019
ef1f54a
remove TestBase from new tests
HenryYYang Feb 28, 2019
cb3e0eb
Merge branch 'add-cluster-extension' of github.com:HenryYYang/envoy i…
HenryYYang Feb 28, 2019
35b2c86
fix formatting
HenryYYang Feb 28, 2019
b3c41e2
fix formatting
HenryYYang Feb 28, 2019
a5e19da
fix formatting
HenryYYang Feb 28, 2019
5311662
fix clang tidy
HenryYYang Feb 28, 2019
6634824
fix typo
HenryYYang Feb 28, 2019
587b1d0
fix clang-tidy
HenryYYang Feb 28, 2019
ff123bf
Merge branch 'master' of github.com:envoyproxy/envoy into add-cluster…
HenryYYang Feb 28, 2019
d16d0b9
delete deprecated api
HenryYYang Mar 1, 2019
b82e014
Fix PR feedbacks
HenryYYang Mar 2, 2019
0cf38a8
Fix PR feedbacks
HenryYYang Mar 4, 2019
506f51b
Merge branch 'master' into add-cluster-extension
HenryYYang Mar 4, 2019
f75d362
Remove TestBase
HenryYYang Mar 5, 2019
d51e41a
Fix PR feedbacks
HenryYYang Mar 5, 2019
6ccc257
Fix missing import
HenryYYang Mar 5, 2019
0cb3806
Fix duplicate registration
HenryYYang Mar 6, 2019
1716d48
Split implementation and registration of custom static cluster out of…
HenryYYang Mar 6, 2019
735524d
fix format
HenryYYang Mar 6, 2019
b06aca8
remove CUSTOM_CLUSTER_CONFIG
HenryYYang Mar 7, 2019
0a53ccb
Kick CI
HenryYYang Mar 8, 2019
661875e
Merge branch 'master' into add-redis-cluster
HenryYYang Mar 8, 2019
72acffa
Add redis cluster
HenryYYang Mar 26, 2019
fe83017
Add redis cluster test
HenryYYang Mar 31, 2019
b25de9f
Support ipv6
HenryYYang Mar 31, 2019
e95f67e
add version history
HenryYYang Apr 1, 2019
f51b36a
Merge branch 'master' into add-redis-cluster
HenryYYang Apr 1, 2019
c186184
Kick CI
HenryYYang Apr 3, 2019
a30136b
Merge branch 'master' into add-redis-cluster
FAYiEKcbD0XFqF2QK2E4viAHg8rMm2VbjYKdjTg Apr 5, 2019
8027e1e
docs
FAYiEKcbD0XFqF2QK2E4viAHg8rMm2VbjYKdjTg Apr 8, 2019
e42cac4
Merge branch 'master' into add-redis-cluster
FAYiEKcbD0XFqF2QK2E4viAHg8rMm2VbjYKdjTg Apr 8, 2019
dabacd1
make docs work zomg
FAYiEKcbD0XFqF2QK2E4viAHg8rMm2VbjYKdjTg Apr 8, 2019
9a8c5ff
fix compile error
FAYiEKcbD0XFqF2QK2E4viAHg8rMm2VbjYKdjTg Apr 10, 2019
d2c4606
mitch comments
FAYiEKcbD0XFqF2QK2E4viAHg8rMm2VbjYKdjTg Apr 10, 2019
96bbf69
fix issue
FAYiEKcbD0XFqF2QK2E4viAHg8rMm2VbjYKdjTg Apr 10, 2019
6738ca9
extra protection on cancels
FAYiEKcbD0XFqF2QK2E4viAHg8rMm2VbjYKdjTg Apr 10, 2019
385a6a5
Revert "extra protection on cancels"
FAYiEKcbD0XFqF2QK2E4viAHg8rMm2VbjYKdjTg Apr 11, 2019
ae24a89
respond to mitch and matt comments
FAYiEKcbD0XFqF2QK2E4viAHg8rMm2VbjYKdjTg Apr 11, 2019
e20db9a
fix spelling
FAYiEKcbD0XFqF2QK2E4viAHg8rMm2VbjYKdjTg Apr 11, 2019
354d635
Merge branch 'master' into add-redis-cluster
FAYiEKcbD0XFqF2QK2E4viAHg8rMm2VbjYKdjTg Apr 11, 2019
6535c6e
Merge branch 'master' into add-redis-cluster
FAYiEKcbD0XFqF2QK2E4viAHg8rMm2VbjYKdjTg Apr 12, 2019
1bb84fb
Update docs per matt comments, put a function in an anonymous namespace
FAYiEKcbD0XFqF2QK2E4viAHg8rMm2VbjYKdjTg Apr 12, 2019
d0d73bb
add test for cluster factory exception pass and fail cases
FAYiEKcbD0XFqF2QK2E4viAHg8rMm2VbjYKdjTg Apr 15, 2019
098ccd2
Add integration test
HenryYYang Apr 25, 2019
7a2eb43
Merge branch 'add-redis-cluster' of github.com:HenryYYang/envoy into …
HenryYYang Apr 25, 2019
c35d0b5
Merge branch 'master' into add-redis-cluster
HenryYYang Apr 25, 2019
97f16fe
Fix merge issues
HenryYYang Apr 26, 2019
169fe5d
Fix clang_tidy errors
HenryYYang Apr 26, 2019
71209e2
Add more robust error checking.
HenryYYang Apr 29, 2019
dab3be9
Add more test for cluster slots response
HenryYYang May 2, 2019
3f1bc38
delete twemproxy from dictionary
HenryYYang May 2, 2019
569b693
Small refactor of the RedisCluster class
HenryYYang May 2, 2019
152e1ab
Merge branch 'master' into add-redis-cluster
HenryYYang May 2, 2019
f746acf
Fix code review feedbacks
HenryYYang May 2, 2019
db280e3
Fix code review feedback.
HenryYYang May 3, 2019
710c915
Fix redis cluster test
HenryYYang May 3, 2019
074221c
Add Redis cluster routing.
HenryYYang May 10, 2019
fbd1030
Add to spelling_dictionary
HenryYYang May 10, 2019
0ca25c5
Merge branch 'master' into add-redis-cluster-mode
HenryYYang May 10, 2019
b63ef2d
Fix clang and format
HenryYYang May 10, 2019
0d810f5
Merge branch 'master' into add-redis-cluster-mode
HenryYYang May 13, 2019
272dde4
Fix memory test
HenryYYang May 13, 2019
2a69c70
Update coowner file
HenryYYang May 15, 2019
17f7da2
Add redis cluster loadbalancer
HenryYYang May 28, 2019
1c94671
fix format
HenryYYang May 28, 2019
4b1d635
Added back imports
HenryYYang May 28, 2019
890a207
Merge branch 'master' into add-redis-cluster-mode
HenryYYang May 28, 2019
6fbceeb
Merge branch 'master' into add-redis-cluster-mode
HenryYYang May 29, 2019
ebd37fb
Integrate Matt's loadbalancer changes
HenryYYang May 30, 2019
a056992
Force loadbalancer update when redis cluster slot is changed.
HenryYYang May 31, 2019
8dd1228
Fix clang error
HenryYYang May 31, 2019
726c112
Fix PR feedback and failed tests.
HenryYYang Jun 1, 2019
5089623
Merge branch 'master' into add-redis-cluster-mode
HenryYYang Jun 3, 2019
c89880a
Merge branch 'master' into add-redis-cluster-mode
HenryYYang Jun 3, 2019
9847905
Fix BUILD file
HenryYYang Jun 4, 2019
de46435
Fix PR feedbacks
HenryYYang Jun 5, 2019
41bdde3
Fix format
HenryYYang Jun 5, 2019
1a96dbf
Fix failed tests
HenryYYang Jun 6, 2019
1b8fdb7
Kick CI
HenryYYang Jun 6, 2019
863fee1
revert state test
HenryYYang Jun 6, 2019
4e765ae
fix PR feedback
HenryYYang Jun 6, 2019
c9d7630
Move crc16 source code.
HenryYYang Jun 6, 2019
8d0c8d8
Fix format
HenryYYang Jun 6, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,5 @@
/*/extensions/quic_listeners/ @alyssawilk @danzh2010 @mattklein123 @mpwarres @wu-bin
# zookeeper_proxy extension
/*/extensions/filters/network/zookeeper_proxy @rgs1 @snowp
# redis cluster extension
/*/extensions/clusters/redis @msukalski @henryyyang @mattklein123
3 changes: 3 additions & 0 deletions docs/root/intro/version_history.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Version history
* original_src filter: added the :ref:`filter<config_http_filters_original_src>`.
* rbac: migrated from v2alpha to v2.
* redis: add support for Redis cluster custom cluster type.
* redis: automatically route commands using cluster slots for Redis cluster.
* redis: added :ref:`prefix routing <envoy_api_field_config.filter.network.redis_proxy.v2.RedisProxy.prefix_routes>` to enable routing commands based on their key's prefix to different upstream.
* redis: add support for zpopmax and zpopmin commands.
* redis: added
Expand Down Expand Up @@ -66,6 +67,8 @@ Version history
that allows ignoring new hosts for the purpose of load balancing calculations until they have
been health checked for the first time.
* upstream: added runtime error checking to prevent setting dns type to STRICT_DNS or LOGICAL_DNS when custom resolver name is specified.
* grpc-json: added support for :ref:`auto mapping
Comment thread
HenryYYang marked this conversation as resolved.
Outdated
<envoy_api_field_config.filter.http.transcoder.v2.GrpcJsonTranscoder.auto_mapping>`.

1.10.0 (Apr 5, 2019)
====================
Expand Down
7 changes: 7 additions & 0 deletions include/envoy/upstream/upstream.h
Original file line number Diff line number Diff line change
Expand Up @@ -724,6 +724,13 @@ class ClusterInfo {
*/
virtual envoy::api::v2::Cluster::DiscoveryType type() const PURE;

/**
* @return the type of cluster, this includes custom discovery type in addition to the build-in
Comment thread
HenryYYang marked this conversation as resolved.
Outdated
* discovery types.
*/
virtual const absl::optional<envoy::api::v2::Cluster::CustomClusterType>&
clusterType() const PURE;

/**
* @return configuration for least request load balancing, only used if LB type is least request.
*/
Expand Down
3 changes: 2 additions & 1 deletion source/common/upstream/upstream_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,8 @@ ClusterInfoImpl::ClusterInfoImpl(const envoy::api::v2::Cluster& config,
cluster_socket_options_(parseClusterSocketOptions(config, bind_config)),
drain_connections_on_host_removal_(config.drain_connections_on_host_removal()),
warm_hosts_(!config.health_checks().empty() &&
common_lb_config_.ignore_new_hosts_until_first_hc()) {
common_lb_config_.ignore_new_hosts_until_first_hc()),
cluster_type_(config.cluster_type()) {
Comment thread
HenryYYang marked this conversation as resolved.
Outdated
switch (config.lb_policy()) {
case envoy::api::v2::Cluster::ROUND_ROBIN:
lb_type_ = LoadBalancerType::RoundRobin;
Expand Down
4 changes: 4 additions & 0 deletions source/common/upstream/upstream_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,9 @@ class ClusterInfoImpl : public ClusterInfo {
extensionProtocolOptions(const std::string& name) const override;
LoadBalancerType lbType() const override { return lb_type_; }
envoy::api::v2::Cluster::DiscoveryType type() const override { return type_; }
const absl::optional<envoy::api::v2::Cluster::CustomClusterType>& clusterType() const override {
return cluster_type_;
}
const absl::optional<envoy::api::v2::Cluster::LeastRequestLbConfig>&
lbLeastRequestConfig() const override {
return lb_least_request_config_;
Expand Down Expand Up @@ -619,6 +622,7 @@ class ClusterInfoImpl : public ClusterInfo {
const bool drain_connections_on_host_removal_;
const bool warm_hosts_;
absl::optional<std::string> eds_service_name_;
const absl::optional<envoy::api::v2::Cluster::CustomClusterType> cluster_type_;
};

/**
Expand Down
25 changes: 25 additions & 0 deletions source/extensions/clusters/redis/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,38 @@ load(

envoy_package()

envoy_cc_library(
name = "crc16_lib",
srcs = [
"crc16.cc",
"crc16.h",
],
)

envoy_cc_library(
name = "redis_cluster_lb",
srcs = [
"redis_cluster_lb.cc",
"redis_cluster_lb.h",
],
deps = [
":crc16_lib",
"//include/envoy/upstream:thread_local_cluster_interface",
"//include/envoy/upstream:upstream_interface",
"//source/common/upstream:upstream_includes",
"//source/common/upstream:upstream_lib",
"//source/extensions/clusters:well_known_names",
],
)

envoy_cc_library(
name = "redis_cluster",
srcs = [
"redis_cluster.cc",
"redis_cluster.h",
],
deps = [
"redis_cluster_lb",
"//include/envoy/api:api_interface",
"//include/envoy/http:codec_interface",
"//include/envoy/upstream:cluster_factory_interface",
Expand Down
55 changes: 55 additions & 0 deletions source/extensions/clusters/redis/crc16.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#include "crc16.h"

#include "absl/strings/string_view.h"

namespace Envoy {
namespace Extensions {
namespace Clusters {
namespace Redis {

/**
* XMODEM CRC16 implementation according to CITT standards.
* Based on (F).
* @param key The string to hash.
* @return The CRC16 hash code.
*/
static const uint16_t crc16tab[256] = {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b,
0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401,
0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738,
0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96,
0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd,
0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb,
0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2,
0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8,
0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827,
0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d,
0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74,
0x2e93, 0x3eb2, 0x0ed1, 0x1ef0};

// (https://github.com/antirez/redis/blob/unstable/src/crc16.c)
Comment thread
HenryYYang marked this conversation as resolved.
Outdated
uint16_t Crc16::crc16(absl::string_view key) {
const char* buf = static_cast<const char*>(key.data());
uint64_t len = key.size();
uint64_t counter;
uint16_t crc = 0;
for (counter = 0; counter < len; counter++) {
crc = (crc << 8) ^ crc16tab[((crc >> 8) ^ *buf++) & 0x00FF];
}
return crc;
}

} // namespace Redis
} // namespace Clusters
} // namespace Extensions
} // namespace Envoy
25 changes: 25 additions & 0 deletions source/extensions/clusters/redis/crc16.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once

#include <string>

#include "absl/strings/ascii.h"

namespace Envoy {
namespace Extensions {
namespace Clusters {
namespace Redis {

class Crc16 {
public:
/**
* XMODEM CRC16 implementation according to CITT standards.
* Based on (https://github.com/antirez/redis/blob/unstable/src/crc16.c).
* @param key The string to hash.
* @return The CRC16 hash code.
*/
static uint16_t crc16(absl::string_view key);
};
} // namespace Redis
} // namespace Clusters
} // namespace Extensions
} // namespace Envoy
48 changes: 28 additions & 20 deletions source/extensions/clusters/redis/redis_cluster.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ RedisCluster::RedisCluster(
Upstream::ClusterManager& clusterManager, Runtime::Loader& runtime, Api::Api& api,
Network::DnsResolverSharedPtr dns_resolver,
Server::Configuration::TransportSocketFactoryContext& factory_context,
Stats::ScopePtr&& stats_scope, bool added_via_api)
Stats::ScopePtr&& stats_scope, bool added_via_api,
ClusterSlotUpdateCallBackSharedPtr lb_factory)
: Upstream::BaseDynamicClusterImpl(cluster, runtime, factory_context, std::move(stats_scope),
added_via_api),
cluster_manager_(clusterManager),
Expand All @@ -32,7 +33,8 @@ RedisCluster::RedisCluster(
? cluster.load_assignment()
: Config::Utility::translateClusterHosts(cluster.hosts())),
local_info_(factory_context.localInfo()), random_(factory_context.random()),
redis_discovery_session_(*this, redis_client_factory), api_(api) {
redis_discovery_session_(*this, redis_client_factory), lb_factory_(std::move(lb_factory)),
api_(api) {
const auto& locality_lb_endpoints = load_assignment_.endpoints();
for (const auto& locality_lb_endpoint : locality_lb_endpoints) {
for (const auto& lb_endpoint : locality_lb_endpoint.lb_endpoints()) {
Expand Down Expand Up @@ -77,17 +79,22 @@ void RedisCluster::updateAllHosts(const Upstream::HostVector& hosts_added,

void RedisCluster::onClusterSlotUpdate(const std::vector<ClusterSlot>& slots) {
Upstream::HostVector new_hosts;
SlotArray slots_;

for (const ClusterSlot& slot : slots) {
new_hosts.emplace_back(new RedisHost(info(), "", slot.master_, *this, true));
new_hosts.emplace_back(new RedisHost(info(), "", slot.master(), *this, true));
}

std::unordered_map<std::string, Upstream::HostSharedPtr> updated_hosts;
Upstream::HostVector hosts_added;
Upstream::HostVector hosts_removed;
if (updateDynamicHostList(new_hosts, hosts_, hosts_added, hosts_removed, updated_hosts,
all_hosts_)) {
const bool host_updated = updateDynamicHostList(new_hosts, hosts_, hosts_added, hosts_removed,
updated_hosts, all_hosts_);
const bool slot_updated =
lb_factory_ ? lb_factory_->onClusterSlotUpdate(slots, updated_hosts) : false;

// If slot is updated, call updateAllHosts regardless of if there's new hosts to force
// update of the thread local load balancers.
if (host_updated || slot_updated) {
ASSERT(std::all_of(hosts_.begin(), hosts_.end(), [&](const auto& host) {
return host->priority() == localityLbEndpoint().priority();
}));
Expand All @@ -96,16 +103,7 @@ void RedisCluster::onClusterSlotUpdate(const std::vector<ClusterSlot>& slots) {
info_->stats().update_no_rebuild_.inc();
}

for (const ClusterSlot& slot : slots) {
auto host = updated_hosts.find(slot.master_->asString());
ASSERT(host != updated_hosts.end(), "we expect all address to be found in the updated_hosts");
for (auto i = slot.start_; i <= slot.end_; ++i) {
slots_[i] = host->second;
}
}

all_hosts_ = std::move(updated_hosts);
cluster_slots_map_.swap(slots_);

// TODO(hyang): If there is an initialize callback, fire it now. Note that if the
// cluster refers to multiple DNS names, this will return initialized after a single
Expand Down Expand Up @@ -317,17 +315,27 @@ RedisClusterFactory::createClusterWithConfig(
Envoy::Stats::ScopePtr&& stats_scope) {
if (!cluster.has_cluster_type() ||
cluster.cluster_type().name() != Extensions::Clusters::ClusterTypes::get().Redis) {
throw EnvoyException("Redis cluster can only created with redis cluster type");
throw EnvoyException("Redis cluster can only created with redis cluster type.");
}
// TODO(hyang): This is needed to migrate existing cluster, disallow using other lb_policy
Comment thread
mattklein123 marked this conversation as resolved.
// in the future
if (cluster.lb_policy() != envoy::api::v2::Cluster::CLUSTER_PROVIDED) {
return std::make_pair(std::make_shared<RedisCluster>(
cluster, proto_config,
NetworkFilters::Common::Redis::Client::ClientFactoryImpl::instance_,
context.clusterManager(), context.runtime(), context.api(),
selectDnsResolver(cluster, context), socket_factory_context,
std::move(stats_scope), context.addedViaApi(), nullptr),
nullptr);
}
// TODO(Henry): Implement a thread aware load balancer for Redis Cluster. This can come from
// inside the created cluster.
auto lb_factory = std::make_shared<RedisClusterLoadBalancerFactory>();
return std::make_pair(std::make_shared<RedisCluster>(
cluster, proto_config,
NetworkFilters::Common::Redis::Client::ClientFactoryImpl::instance_,
context.clusterManager(), context.runtime(), context.api(),
selectDnsResolver(cluster, context), socket_factory_context,
std::move(stats_scope), context.addedViaApi()),
nullptr);
std::move(stats_scope), context.addedViaApi(), lb_factory),
std::make_unique<RedisClusterThreadAwareLoadBalancer>(lb_factory));
}

REGISTER_FACTORY(RedisClusterFactory, Upstream::ClusterFactory);
Expand Down
28 changes: 8 additions & 20 deletions source/extensions/clusters/redis/redis_cluster.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
#include "common/upstream/resource_manager_impl.h"
#include "common/upstream/upstream_impl.h"

#include "source/extensions/clusters/redis/redis_cluster_lb.h"

#include "server/transport_socket_config_impl.h"

#include "extensions/clusters/well_known_names.h"
Expand Down Expand Up @@ -80,16 +82,11 @@ namespace Redis {
* the `CLUSTER SLOTS command <https://redis.io/commands/cluster-slots>`_, and the responses and
* failure cases.
*
* The topology is stored in cluster_slots_map_. According to the
* `Redis Cluster Spec <https://redis.io/topics/cluster-spec#keys-distribution-model`_, the key
* space is split into a fixed size 16384 slots. The current implementation uses a fixed size
* std::array() of shared_ptr pointing to the master host. This has a fixed cpu and memory cost and
* provide a fast lookup constant time lookup similar to Maglev. This will be used by the redis
* proxy filter for load balancing purpose.
* Once the topology is fetched from Redis, the cluster will update the
* RedisClusterLoadBalancerFactory, which will be used by the redis proxy filter for load balancing
* purpose.
*/

typedef std::array<Upstream::HostSharedPtr, 16384> SlotArray;

class RedisCluster : public Upstream::BaseDynamicClusterImpl {
public:
RedisCluster(const envoy::api::v2::Cluster& cluster,
Expand All @@ -98,7 +95,8 @@ class RedisCluster : public Upstream::BaseDynamicClusterImpl {
Upstream::ClusterManager& clusterManager, Runtime::Loader& runtime, Api::Api& api,
Network::DnsResolverSharedPtr dns_resolver,
Server::Configuration::TransportSocketFactoryContext& factory_context,
Stats::ScopePtr&& stats_scope, bool added_via_api);
Stats::ScopePtr&& stats_scope, bool added_via_api,
ClusterSlotUpdateCallBackSharedPtr factory);

struct ClusterSlotsRequest : public Extensions::NetworkFilters::Common::Redis::RespValue {
public:
Expand All @@ -124,15 +122,6 @@ class RedisCluster : public Upstream::BaseDynamicClusterImpl {
void updateAllHosts(const Upstream::HostVector& hosts_added,
const Upstream::HostVector& hosts_removed, uint32_t priority);

struct ClusterSlot {
ClusterSlot(int64_t start, int64_t end, Network::Address::InstanceConstSharedPtr master)
: start_(start), end_(end), master_(std::move(master)) {}

int64_t start_;
int64_t end_;
Network::Address::InstanceConstSharedPtr master_;
};

void onClusterSlotUpdate(const std::vector<ClusterSlot>&);

const envoy::api::v2::endpoint::LocalityLbEndpoints& localityLbEndpoint() const {
Expand Down Expand Up @@ -259,8 +248,7 @@ class RedisCluster : public Upstream::BaseDynamicClusterImpl {
const LocalInfo::LocalInfo& local_info_;
Runtime::RandomGenerator& random_;
RedisDiscoverySession redis_discovery_session_;
// The slot to master node map.
SlotArray cluster_slots_map_;
const ClusterSlotUpdateCallBackSharedPtr lb_factory_;

Upstream::HostVector hosts_;
Upstream::HostMap all_hosts_;
Expand Down
Loading