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

Cluster: support host names when available, via CLUSTER SLOTS #2826

Open
mgravell opened this issue Dec 18, 2024 · 6 comments
Open

Cluster: support host names when available, via CLUSTER SLOTS #2826

mgravell opened this issue Dec 18, 2024 · 6 comments

Comments

@mgravell
Copy link
Collaborator

mgravell commented Dec 18, 2024

Situation:

  • especially from v7, cluster shards may be routed via hosts instead of IPs
  • thus, the advertised IPs may sometimes (with known examples) may not be routable
  • SLOTS and SHARDS (v7+) provide the hosts; NODES does not, as far as known

Proposal:

  • prefer SLOTS to NODES (but not SHARDS due to v7 dependency)
  • route via hostname when available, IP otherwise
  • possibly with option to use fallback old behaviour?

Was: "Lookup by endpoint should check IP and host"

Currently, only exact endpoint matches are considered. However, specially in the case of CLUSTER, a node may have both host and IP evidently. Further, -MOVED may return the unexpected option, leading to additional connections.

We should:

  • record both identities as declared, for example from the CLUSTER NODES response
  • if no equality endpoint match is found, check also using the best data available (after type-testing the endpoint)

Context: dotnet/aspnetcore#59211

Auxiliary consideration: should cluster routing be limited to IP, as current? Should there be a "use host routing" option? Or should we try IP and use host if that fails?

@CaringDev
Copy link

Additional complexity for bonus points: (part of) the cluster might be hidden behind a proxy / load balancer requiring SNI, i.e. all (some) hostnames resolve to the same IP.

@mgravell
Copy link
Collaborator Author

Side note: some of this may already be shimmable by individual callers, if they already know how they want things to connect: the Tunnel API allows callers to override how connections are established. This would, in theory, allow custom client-side code to take a requested endpoint and do whatever it needs, as long as it can create a Stream. I've seen this use proxy servers, custom DNS-like things, you name it.

@CaringDev
Copy link

CaringDev commented Jan 6, 2025

I got a response from the team providing "redis as a service"... the summary is as follows:

The advertised hosts when receiving a MOVED response are correct [...]
the library should not use IPs from “CLUSTER NODES” responses for its own routing. We explicitly configure internal IPs for the Redis routing so that the sharding and replication does not go out the OpenShift network. We then expose different routing for client libraries as these need to be routable from outside the network. [...]
The documentation [...] states “Note that normally clients willing to fetch the map between Cluster hash slots and node addresses should use CLUSTER SLOTS instead.” The output of that command provides the hostname as first routing priority, and returns correct hostnames [...]
We will not be able to make the IPs routable from outside the OpenShift cluster

The output of CLUSTER SHARDS (7.x successor of CLUSTER SLOTS) is:

slots
 0
 5460
nodes
  id
  c9ef1500c2acc37273e5b04275f7e5620b796fff
  tls-port
  443
  ip
  10.42.0.1
  endpoint
  redis-7c2b3133-0bf4-0.redis.example
  hostname
  redis-7c2b3133-0bf4-0.redis.example
  role
  master
  replication-offset
  0
  health
  online
slots
 10923
 16383
nodes
  id
  753343875ffe163a64284b36d7743861f2ef1506
  tls-port
  443
  ip
  10.42.0.3
  endpoint
  redis-7c2b3133-0bf4-2.redis.example
  hostname
  redis-7c2b3133-0bf4-2.redis.example
  role
  master
  replication-offset
  0
  health
  online
slots
 5461
 10922
nodes
  id
  8992b30e1499e2cf0bc86609d752c4f3f49c2199
  tls-port
  443
  ip
  10.42.0.2
  endpoint
  redis-7c2b3133-0bf4-1.redis.example
  hostname
  redis-7c2b3133-0bf4-1.redis.example
  role
  master
  replication-offset
  0
  health
  online

Could you see a possible future for SE.R supporting such a topology / configuration?

@mgravell
Copy link
Collaborator Author

mgravell commented Jan 6, 2025

Well, we're making progress, at least. Yes, there is potential for us to migrate to CLUSTER SLOTS, but it'll take a bit of testing and effort. Basically, CLUSTER NODES was the original and therefore most widely available version of topology discovery. Moving to a newer version gets tricky because of server Vs client level, but CLUSTER SLOTS is almost as old as CLUSTER NODES so is almost certainly fine (IIRC both were pre-GA of 3.0). Migrating to CLUSTER SHARDS - probably not an option yet, and it looks like CLUSTER SLOTS is documented as supporting host names from v7, so: we're probably fine there.

But: this is at least actionable and makes reasonable sense. I don't think I can have much influence on the provider, but I suspect they may have similar problems with several client libraries, at least the cluster-aware ones, but: this seems pragmatic and I'm not going to fight making such a change. We might need to think about the possible matrix of server versions, host/IP configs, etc - the law of unintended consequences means that any such change that fixes some people: may also break others.

/Cc @philon-msft in case using hosts instead of IP routing might be useful, if/when we do this.

@mgravell mgravell changed the title Lookup by endpoint should check IP and host Cluster: support host names when available, via CLUSTER SLOTS Jan 6, 2025
@mgravell
Copy link
Collaborator Author

mgravell commented Jan 6, 2025

See edit for my proposal

@CaringDev
Copy link

CaringDev commented Jan 6, 2025

Yes, CLUSTER SLOTS is returning the host names (together with optional, non-routable IP adresses), so seems to be the better choice:

0 0 0
  1 5460
  2 0 redis-7c2b3133-0bf4-0.redis.example
    1 443
    2 c9ef1500c2acc37273e5b04275f7e5620b796fff
    3 ip: 10.42.0.1
1 0 5461
  1 10922
 2 0 redis-7c2b3133-0bf4-1.redis.example
    1 443
    2 8992b30e1499e2cf0bc86609d752c4f3f49c2199
    3 ip: 10.42.0.2
2 0 10923
  1 16383
  2 0 redis-7c2b3133-0bf4-2.redis.example
    1 443
    2 753343875ffe163a64284b36d7743861f2ef1506
    3 ip: 10.42.0.3

Side note: in my case, all hostnames resolve to the same routable IP and require SNI.

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

No branches or pull requests

2 participants