redis / node-redis

Redis Node.js client
https://redis.js.org/
MIT License
16.86k stars 1.87k forks source link

Support SRV records #2088

Open onfleet-ablair opened 2 years ago

onfleet-ablair commented 2 years ago

Suppose we have multiple environments -- staging, production, development.

In each environment, we have a different redis server. However, I don't want to change the code of my application -- I want the application to connect to a host, redis-server, and have it reach the correct server. I can do this with CNAMEs. However, each server is running on a different port: staging, port 8362; production, port 19872; development, 6379. This is because we're using a hosting provider for our redis instances.

I still don't want to have to change the configuration or code to connect to the proper redis instance.

Enter DNS SRV records: the record contains a target and a port. redis-server.staging.my-environment.com -> SRV 0 10 8362 redis-192.hosted.redis-provider.com (priority, weight, port, target [name])

I would like to be able to tell redis to connect to simply redis-server, allow the machine's searchdomains DNS list to expand that to redis-server.staging.my-environment.com, allow the redis connector to do a DNS lookup for the SRV record, and then connect to the appropriate server and port:

const client = createClient({
    url: 'redis://alice:foobar@redis-server'
  });

and with just the above, the infrastructure would control the reference to the redis server for that environment.

See also:

leibale commented 2 years ago
createClient({
  url: '...',
  socket: {
    lookup(hostname, options, callback) {
      // https://nodejs.org/api/net.html#socketconnect
      // https://nodejs.org/api/dns.html#dnslookuphostname-options-callback
    }
  }
});
LuizPanariello commented 1 year ago

SRV is important for some AWS ECS service discovery patterns.

leibale commented 1 year ago

Although there is no built-in support for SRV records in the package (and this is why this issue is still open), you can use socket.lookup to implement that yourself. See my last comment.

chongma commented 1 year ago

Is there also a url.lookup method? In AWS when a service is recreated the SRV and A record may change when using bridge mode.

With service discovery if I create a service called _redis._tcp.internal.domain.tld then AWS creates an: SRV record: 1 1 6379 a80c2a1fe36d452d9db3d707d040dcc8._redis._tcp.internal.domain.tld. A record: a80c2a1fe36d452d9db3d707d040dcc8._redis._tcp.internal.domain.tld.

The a80c2a1fe36d452d9db3d707d040dcc8 part is dynamic and could change if the service restarts.

I guess AWS want you to use awsvpc instead of bridge which means less tasks fit on a container thus costing more. However awsvpc is very laggy