redis / redis-py

Redis Python client
MIT License
12.45k stars 2.48k forks source link

[BUG] redis-py does not use the "previously used host address" to connect when it gets a null/None response for the host during server redirects #2795

Closed sureshvasanthkumar closed 2 weeks ago

sureshvasanthkumar commented 1 year ago

Version: 4.5.5

Platform:
Ubuntu 20.04 Python 3.10.6 pip 22.0.2 from /usr/lib/python3/dist-packages/pip (python 3.10) Redis cluster - redis-server version 7.0.11, All redis cluster member instances are accessible via the same hostname/IP address but on different ports.

Description:

When the Redis cluster is configured with cluster-preferred-endpoint-type unknown-endpoint, it indicates that the server doesn't know how clients can reach it during redirects. This is made clear to the client from the null/None response on the host field during redirects from the server. In this case, the server is expecting the client to reach out on the same endpoint it used for making the last request, but use the new port provided in the response.

This does not happen with redis-py. It tries to connect with the null/None hostname during redirects which is not the expected behavior from the server. This results in the following traceback.

Traceback (most recent call last):
  File "/home/ubuntu/.local/lib/python3.10/site-packages/redis/connection.py", line 699, in connect
    sock = self.retry.call_with_retry(
  File "/home/ubuntu/.local/lib/python3.10/site-packages/redis/retry.py", line 46, in call_with_retry
    return do()
  File "/home/ubuntu/.local/lib/python3.10/site-packages/redis/connection.py", line 700, in <lambda>
    lambda: self._connect(), lambda error: self.disconnect(error)
  File "/home/ubuntu/.local/lib/python3.10/site-packages/redis/connection.py", line 1002, in _connect
    raise err
  File "/home/ubuntu/.local/lib/python3.10/site-packages/redis/connection.py", line 990, in _connect
    sock.connect(socket_address)
ConnectionRefusedError: [Errno 111] Connection refused

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/ubuntu/.local/lib/python3.10/site-packages/redis/cluster.py", line 1119, in _execute_command
    connection = get_connection(redis_node, *args, **kwargs)
  File "/home/ubuntu/.local/lib/python3.10/site-packages/redis/cluster.py", line 47, in get_connection
    return redis_node.connection or redis_node.connection_pool.get_connection(
  File "/home/ubuntu/.local/lib/python3.10/site-packages/redis/connection.py", line 1457, in get_connection
    connection.connect()
  File "/home/ubuntu/.local/lib/python3.10/site-packages/redis/connection.py", line 705, in connect
    raise ConnectionError(self._error_message(e))
redis.exceptions.ConnectionError: Error 111 connecting to None:6383. Connection refused.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/ubuntu/.local/lib/python3.10/site-packages/redis/connection.py", line 699, in connect
    sock = self.retry.call_with_retry(
  File "/home/ubuntu/.local/lib/python3.10/site-packages/redis/retry.py", line 46, in call_with_retry
    return do()
  File "/home/ubuntu/.local/lib/python3.10/site-packages/redis/connection.py", line 700, in <lambda>
    lambda: self._connect(), lambda error: self.disconnect(error)
  File "/home/ubuntu/.local/lib/python3.10/site-packages/redis/connection.py", line 1002, in _connect
    raise err
  File "/home/ubuntu/.local/lib/python3.10/site-packages/redis/connection.py", line 990, in _connect
    sock.connect(socket_address)
ConnectionRefusedError: [Errno 111] Connection refused

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/ubuntu/.local/lib/python3.10/site-packages/redis/cluster.py", line 1491, in initialize
    if bool(r.info().get("cluster_enabled")) is False:
  File "/home/ubuntu/.local/lib/python3.10/site-packages/redis/commands/core.py", line 991, in info
    return self.execute_command("INFO", **kwargs)
  File "/home/ubuntu/.local/lib/python3.10/site-packages/redis/client.py", line 1266, in execute_command
    conn = self.connection or pool.get_connection(command_name, **options)
  File "/home/ubuntu/.local/lib/python3.10/site-packages/redis/connection.py", line 1457, in get_connection
    connection.connect()
  File "/home/ubuntu/.local/lib/python3.10/site-packages/redis/connection.py", line 705, in connect
    raise ConnectionError(self._error_message(e))
redis.exceptions.ConnectionError: Error 111 connecting to None:6381. Connection refused.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/ubuntu/rc.py", line 93, in <module>
    rc = RedisCluster(host=redis_cluster_node,
  File "/home/ubuntu/.local/lib/python3.10/site-packages/redis/cluster.py", line 620, in __init__
    self.commands_parser = CommandsParser(self)
  File "/home/ubuntu/.local/lib/python3.10/site-packages/redis/commands/parser.py", line 16, in __init__
    self.initialize(redis_connection)
  File "/home/ubuntu/.local/lib/python3.10/site-packages/redis/commands/parser.py", line 19, in initialize
    commands = r.execute_command("COMMAND")
  File "/home/ubuntu/.local/lib/python3.10/site-packages/redis/cluster.py", line 1090, in execute_command
    raise e
  File "/home/ubuntu/.local/lib/python3.10/site-packages/redis/cluster.py", line 1076, in execute_command
    res[node.name] = self._execute_command(node, *args, **kwargs)
  File "/home/ubuntu/.local/lib/python3.10/site-packages/redis/cluster.py", line 1148, in _execute_command
    self.nodes_manager.initialize()
  File "/home/ubuntu/.local/lib/python3.10/site-packages/redis/cluster.py", line 1572, in initialize
    raise RedisClusterException(
redis.exceptions.RedisClusterException: Redis Cluster cannot be connected. Please provide at least one reachable node: Error 111 connecting to None:6381. Connection refused.

Expected behavior:

When a server redirects a client with :new port, the client should connect using the same hostname/IP/endpoint it used previously to connect to the server but with the new port value indicated in the redirect.

keenborder786 commented 1 year ago

Please let me check into the issue and get back to you.

sureshvasanthkumar commented 1 year ago

This is a similar issue on other Redis clients. So far it seems to have been fixed on lettuce. It will soon be fixed on redis-cli - https://github.com/redis/redis/issues/12266

github-actions[bot] commented 1 month ago

This issue is marked stale. It will be closed in 30 days if it is not updated.