mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-09 03:18:44 +00:00
fix: cap Redis connection pool max_connections to prevent unbounded growth
Without a cap, redis-py defaults to 2^31 max connections (effectively unlimited). Under high concurrency, this causes unbounded growth of lock/MutexValue objects and file descriptors — a secondary memory leak that contributes to worker RSS growth. Fix: Default max_connections to 100 (configurable via DEFAULT_REDIS_MAX_CONNECTIONS env var). Applied in both URL-based and kwargs-based connection pool creation paths. Users who explicitly set max_connections in their Redis config still get their custom value. Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
This commit is contained in:
parent
d931577678
commit
ab4899c318
2 changed files with 28 additions and 4 deletions
|
|
@ -18,7 +18,11 @@ import redis # type: ignore
|
|||
import redis.asyncio as async_redis # type: ignore
|
||||
|
||||
from litellm import get_secret, get_secret_str
|
||||
from litellm.constants import REDIS_CONNECTION_POOL_TIMEOUT, REDIS_SOCKET_TIMEOUT
|
||||
from litellm.constants import (
|
||||
DEFAULT_REDIS_MAX_CONNECTIONS,
|
||||
REDIS_CONNECTION_POOL_TIMEOUT,
|
||||
REDIS_SOCKET_TIMEOUT,
|
||||
)
|
||||
from litellm.litellm_core_utils.sensitive_data_masker import SensitiveDataMasker
|
||||
|
||||
from ._logging import verbose_logger
|
||||
|
|
@ -461,15 +465,31 @@ def get_redis_connection_pool(**env_overrides):
|
|||
redis_kwargs = _get_redis_client_logic(**env_overrides)
|
||||
verbose_logger.debug("get_redis_connection_pool: redis_kwargs", redis_kwargs)
|
||||
if "url" in redis_kwargs and redis_kwargs["url"] is not None:
|
||||
return async_redis.BlockingConnectionPool.from_url(
|
||||
timeout=REDIS_CONNECTION_POOL_TIMEOUT, url=redis_kwargs["url"]
|
||||
)
|
||||
pool_kwargs = {"timeout": REDIS_CONNECTION_POOL_TIMEOUT, "url": redis_kwargs["url"]}
|
||||
# MEMORY LEAK FIX: Apply max_connections if user provided it
|
||||
if "max_connections" in redis_kwargs:
|
||||
try:
|
||||
pool_kwargs["max_connections"] = int(redis_kwargs["max_connections"])
|
||||
except (TypeError, ValueError):
|
||||
verbose_logger.warning(
|
||||
"REDIS: invalid max_connections value %r, using default %d",
|
||||
redis_kwargs["max_connections"],
|
||||
DEFAULT_REDIS_MAX_CONNECTIONS,
|
||||
)
|
||||
pool_kwargs["max_connections"] = DEFAULT_REDIS_MAX_CONNECTIONS
|
||||
else:
|
||||
pool_kwargs["max_connections"] = DEFAULT_REDIS_MAX_CONNECTIONS
|
||||
return async_redis.BlockingConnectionPool.from_url(**pool_kwargs)
|
||||
connection_class = async_redis.Connection
|
||||
if "ssl" in redis_kwargs:
|
||||
connection_class = async_redis.SSLConnection
|
||||
redis_kwargs.pop("ssl", None)
|
||||
redis_kwargs["connection_class"] = connection_class
|
||||
redis_kwargs.pop("startup_nodes", None)
|
||||
# MEMORY LEAK FIX: Ensure max_connections is always set to prevent
|
||||
# unbounded connection pool growth (redis-py defaults to 2^31)
|
||||
if "max_connections" not in redis_kwargs:
|
||||
redis_kwargs["max_connections"] = DEFAULT_REDIS_MAX_CONNECTIONS
|
||||
return async_redis.BlockingConnectionPool(
|
||||
timeout=REDIS_CONNECTION_POOL_TIMEOUT, **redis_kwargs
|
||||
)
|
||||
|
|
|
|||
|
|
@ -256,6 +256,10 @@ AZURE_DOCUMENT_INTELLIGENCE_DEFAULT_DPI = int(
|
|||
)
|
||||
REDIS_SOCKET_TIMEOUT = float(os.getenv("REDIS_SOCKET_TIMEOUT", 0.1))
|
||||
REDIS_CONNECTION_POOL_TIMEOUT = int(os.getenv("REDIS_CONNECTION_POOL_TIMEOUT", 5))
|
||||
# MEMORY LEAK FIX: Default max connections for Redis connection pools.
|
||||
# Without a cap, redis-py defaults to 2^31 connections (effectively unlimited),
|
||||
# causing unbounded growth of lock/MutexValue objects and file descriptors.
|
||||
DEFAULT_REDIS_MAX_CONNECTIONS = int(os.getenv("DEFAULT_REDIS_MAX_CONNECTIONS", 100))
|
||||
# Default Redis major version to assume when version cannot be determined
|
||||
# Using 7 as it's the modern version that supports LPOP with count parameter
|
||||
DEFAULT_REDIS_MAJOR_VERSION = int(os.getenv("DEFAULT_REDIS_MAJOR_VERSION", 7))
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue