Redis по умолчанию количество подключений в пуле в Python - PullRequest
0 голосов
/ 08 мая 2019

Python - 3.7

Redis - 2.10.6


Я создаю пул соединений для Redis, используя

redis_pool = redis.ConnectionPool(host=REDIS_URL, port=REDIS_PORT, decode_responses=True) 

Я не указал max_connections.Глядя на исходный код для redis.ConnectionPool(),

def __init__(self, connection_class=Connection, max_connections=None,
             **connection_kwargs):
    """
    Create a connection pool. If max_connections is set, then this
    object raises redis.ConnectionError when the pool's limit is reached.

    By default, TCP connections are created unless connection_class is
    specified. Use redis.UnixDomainSocketConnection for unix sockets.

    Any additional keyword arguments are passed to the constructor of
    connection_class.
    """
    max_connections = max_connections or 2 ** 31
    if not isinstance(max_connections, (int, long)) or max_connections < 0:
        raise ValueError('"max_connections" must be a positive integer')

    self.connection_class = connection_class
    self.connection_kwargs = connection_kwargs
    self.max_connections = max_connections

    self.reset()

я вижу, max_connections установлены на 2 ** 31 , то есть 2 147 483 648 (, если не установлено ).Что странно для меня.

Какое количество подключений Redis по умолчанию поддерживает в пуле?Максимальное значение составляет около 2 миллионов.Таким образом, это означает, что мы должны передать нашу собственную практическую ценность для этого.

1 Ответ

2 голосов
/ 08 мая 2019

Пул не существует на стороне Redis, этот класс на самом деле представляет собой просто фантастическую коллекцию self.connection_class экземпляров на стороне Python.

Согласен с вами, но в 99 +% случаев2 ** 31 число неоправданно велико.Не думайте, что это слишком важно, потому что инициализация пула не создает никаких соединений (или резервирует место для них).max_connections ограничивает только массив _available_connections, который увеличивается, когда требуется соединение, но у пула нет свободного, доступного для немедленного использования.

Вот еще несколько классов ConnectionPool с несколькимиПримечания.

https://github.com/andymccurdy/redis-py/blob/master/redis/connection.py#L967

def reset(self):
    self.pid = os.getpid()
    self._created_connections = 0
    self._available_connections = []  # <- starts empty
    self._in_use_connections = set()
    self._check_lock = threading.Lock()

https://github.com/andymccurdy/redis-py/blob/master/redis/connection.py#L983

def get_connection(self, command_name, *keys, **options):
    "Get a connection from the pool"
    self._checkpid()
    try:
        connection = self._available_connections.pop()
    except IndexError:
        connection = self.make_connection()  # <- make a new conn only if _available_connections is tapped
    self._in_use_connections.add(connection)
    try:
        # ensure this connection is connected to Redis
        connection.connect()
        # connections that the pool provides should be ready to send
        # a command. if not, the connection was either returned to the
        # pool before all data has been read or the socket has been
        # closed. either way, reconnect and verify everything is good.
        if not connection.is_ready_for_command():
            connection.disconnect()
            connection.connect()
            if not connection.is_ready_for_command():
                raise ConnectionError('Connection not ready')
    except:  # noqa: E722
        # release the connection back to the pool so that we don't leak it
        self.release(connection)
        raise

    return connection

https://github.com/andymccurdy/redis-py/blob/master/redis/connection.py#L1019

 def make_connection(self):
    "Create a new connection"
    if self._created_connections >= self.max_connections:  # <- where the bounding happens
        raise ConnectionError("Too many connections")
    self._created_connections += 1
    return self.connection_class(**self.connection_kwargs)

В любом случае, я бы поставилэто конкретное значение было выбрано, чтобы уменьшить вероятность того, что разработчик полностью истощит пул до нуля. Обратите внимание, что объекты подключения чрезвычайно легковесны, поэтому массив из тысяч или миллионов из них вряд ли остановит ваше приложение.И практически это не должно иметь никакого значения: большинство вызовов Redis возвращаются так быстро, что вам все равно будет трудно случайно запустить миллионы из них параллельно.(И если вы делаете это специально, вы, вероятно, знаете достаточно, чтобы настроить все под свои нужды.; -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...