https://github.com/redis/redis/blob/6f11acbd67f65c5f3fd84223bf07fefd75cfdc37/src/server.c#L2807

I am requesting that the allowed values for the port be changed as follows:

  • 0..65535 are valid
  • all other values disable TCP listening

0 has special meaning: select an unused port. This port can then be queried with tools like lsof, netstat, ss, etc.

Comment From: itamarhaber

Hello @Phantal

Thanks for proposing this feature request. The problem with your suggestion is that historically the value of 0 means that Redis will not listen on TCP ports, so if we make the change we'll break the contract with the userbase. This, however, can be easily solved by using a different value, e.g. -1, or even a new config flag.

That said, I'm not totally clear on the use case here. As Redis is a non-discoverable service, in the sense that a remote client needs beforehand knowledge of its address and port, a random choice of port seems unneeded. Please clarify how this can be used in the wild.

Comment From: Phantal

Our use case is a multi process application in a multi tenant environment without something like kubernetes [yet] available.

The IPC mechanisms our predecessors came up with are many and varied. We're attempting to standardize on Redis.

Unfortunately, the multi tenancy means we cannot just choose a port.

Without this feature the only other option I've found and like is to bind port zero, query the socket, close it, then launch Redis with that port. This is contingent upon Redis using SO_REUSEADDR, something I have not yet verified.

Another less palatable option is domain sockets. This is less palatable in that some of the processes are on remote machines. I could forward the domain socket with SSH, but that strays into the realm of hokey, not to mention possibly adding latency.

On Wed, Aug 12, 2020, 05:49 Itamar Haber notifications@github.com wrote:

Hello @Phantal https://github.com/Phantal

Thanks for proposing this feature request. The problem with your suggestion is that historically the value of 0 means that Redis will not listen on TCP ports, so if we make the change we'll break the contract with the userbase. This, however, can be easily solved by using a different value, e.g. -1, or even a new config flag.

That said, I'm not totally clear on the use case here. As Redis is a non-discoverable service, in the sense that a remote client needs beforehand knowledge of its address and port, a random choice of port seems unneeded. Please clarify how this can be used in the wild.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/redis/redis/issues/7652#issuecomment-672824042, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACG4TLUAR4DRGSQ3V4C3EFTSAJ6V3ANCNFSM4P4FVHJQ .

Comment From: oranagra

this could also possibly be a solution to a problem we are / were facing with our test suite.

the code we have now is some loop that tries to find a free port (see find_available_port), then tries to spawn redis that binds on it. if it failed to bind due to a race (someone else using that port first), we try the whole thing again. see this as an example: https://github.com/redis/redis/pull/7635 in theory letting redis choose the port and then sniffing the port number by some way (e.g. parsing the log file) could be a solution.

@yossigo what do you think

Note that in the non-cluster tests this is not a good solution, since we must have each test thread use a different port range so that in some races in the test teardown servers will not try to replicate from ones in a different test. And in the cluster tests, there's no concurrency and i simply can't understand why they still fail despite running in a container and having that retry loop.

Comment From: yossigo

I am not in favor of this for several reasons:

  1. Dynamic port allocation could make sense if we also had a service discovery framework, so a process binds to some random port and then has a standard way to announce it. Having to poke around to discover what port seems like a very specific hack to me.
  2. Modern environments rely on containers (in this context, network namespaces really) to handle this kind of contention. So I really don't see any justification to create such discovery framework.

@oranagra I think solving the tests issues externally would be anyway simpler and more reliable.

@Phantal Do processes in your environment continuously race each other for resources (TCP ports)? If they don't do that, I guess a simpler approach would be to wrap Redis with some script that handles it: - Query netstat to find an unused port - Start Redis with that port - Retry if failed

The only other potential solution I see is to be support run-time CONFIG SET port (currently the port can only be read from config file on startup).

This could get tricky, in particular now that we have both TCP and TLS, etc.. But it could also be simplified by allowing a port to be set if it was not previously configured. So, you could start with no TCP port configured, then attempt random CONFIG SET port which would only succeed if bind() was successful.

This would have the benefits of (a) allocation is atomic, so it works well in a dynamic environment; (b) it MIGHT be marginally useful in some other cases.

Comment From: sergey-komissarov

Hello, we are facing the same situation. We want to start multiple redis servers on the single node with some other services which uses random ports. Actually we have 50-100 services per node.

@yossigo May be it is acceptable to write bound port value in the file specified by the config? It should be enough in most cases.

Comment From: yossigo

@sergey-komissarov I'm not sure I understand your suggestion, do you mean specify a port range Redis should allocate from? How do you plan to determine the mapping between ports and instances if it's random?

Comment From: sergey-komissarov

@yossigo I thought about config or command line option 'port-file' with absolute path to the file where server writes port number as text. Of course file path must be unique for each instance on the node, but this may be handled by node maintaners.

Comment From: yossigo

@sergey-komissarov Your proposal is valid, but I think it goes a relatively long way (new config option) to solve a very specific problem.

I am more in favor of simply making port runtime configurable as described above, so the service launcher can start Redis with a Unix socket and then use CONFIG SET port with a random port until successful.

Comment From: ThibaultLemaire

Hello, just chiming in to say that would be useful to us @BelledonneCommunications as well, because we use redis in our automated test suite.

Both being able to ask for the port to be dynamic (and then e.g. parsing stdout to get it) or being able to CONFIG SET it in a loop at runtime would be satisfactory. (Although my personal preference goes to the first solution. It's simpler, and since it's only for tests, a new version of redis changing its output wouldn't break anything serious.)