Discovery cluster topology without hardcode
Closed this issue · 2 comments
We use several bare metal nodes to host a redis cluster.
Naturally, not all nodes in the redis cluster use the same port. In order to discovery the cluster topology, at first we used
// hardcode or use a external system to obtain several "seed" node
// I understand not all of them are needed here since there will be a internal discovery later to find all the nodes.
client := redis.NewClusterClient(&redis.ClusterOptions{
Addrs: []string{"host1:port1","host1:port2","host2:port1","host2:port2"},
})We definitely don't want to hardcode. Using an external system is essentially also hardcode since once the client is created the node information is fixed.
A solution I can come up with would be to pass a DNS name into the client and let the client do a DNS SRV resolve every time it needs, which completely eliminate the hardcode. However this functionality is not supported.
Later I tried to implement it as a custom net.Dialer like
func dial(ctx context.Context, network, addr string) (net.Conn, error) {
nd := &net.Dialer{
Timeout: 5 * time.Second, // from github.com/redis/go-redis/v9.NewDialer
KeepAlive: 5 * time.Minute, // from github.com/redis/go-redis/v9.NewDialer
}
host, port, err := mypkg.ResolveSRV(addr)
if err != nil {
return nil, err
}
addr = net.JoinHostPort(host, port)
return nd.DialContext(ctx, network, addr)
}and the use the dialer like
client := redis.NewClusterClient(&redis.ClusterOptions{
Addrs: []string{"some-reds.internal"},
Dialer: dial,
})However, the mypkg.ResolveSRV is not straightforward to implement but needs an understanding of the internal discovery process implementation( I can explain the problem in detail if needed)
So, I wonder if we can implement DNS SRV inside this library, or maybe there are other solutions to avoid hardcode
Hello @rpstw I did wrote a response, but seems i forgot to post it. I do think this is something that should be implemented in the application and not in the client. The client itself provides you a hook (the dialer) where you can resolve the address and the port. Better approach to get the cluster topology would be to use
Line 61 in d54e848
ClusterSlots is exactly what we need and thanks.