Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
El pooling de conexiones mejora el rendimiento de las aplicaciones al reutilizar conexiones a bases de datos en lugar de crear nuevas para cada solicitud. Abrir una conexión implica varios pasos que consumen mucho tiempo:
- El controlador establece un conector de red.
- El controlador completa el handshake TLS.
- El controlador se autentica con el servidor.
- El controlador valida los parámetros de conexión.
El pooling de conexiones mantiene las conexiones abiertas y disponibles para su reutilización, así que tu aplicación no necesita repetir estos pasos para cada solicitud.
Comportamiento predeterminado
El pooling de conexiones está activado por defecto cuando creas tu primera conexión. La configuración predeterminada es la siguiente:
| Configuración | Valor predeterminado | Descripción |
|---|---|---|
max_size |
100 | Número máximo de conexiones por cada cadena de conexión única. |
idle_timeout |
600 segundos (10 minutos) | Número de segundos antes de que se cierren las conexiones en reposo. |
import mssql_python
# Pooling is automatically enabled with defaults
conn = mssql_python.connect(connection_string)
Configuración de la agrupación de conexiones
Configura el pooling antes de crear cualquier conexión:
import mssql_python
# Configure custom pool settings
mssql_python.pooling(max_size=50, idle_timeout=300)
# Now create connections
conn = mssql_python.connect(connection_string)
Parameters
La pooling() función acepta los parámetros siguientes:
| Parámetro | Tipo | Default | Descripción |
|---|---|---|---|
max_size |
int | 100 | Número máximo de conexiones agrupadas por cadena de conexión. |
idle_timeout |
int | 600 | Segundos antes de que las conexiones inactivas sean desalojadas de la piscina. |
enabled |
bool | True | Activa o desactiva el pooling. |
Desactivar la agrupación de conexiones
Para desactivar la agrupación, llama a pooling() con enabled=False antes de crear conexiones:
import mssql_python
mssql_python.pooling(enabled=False)
# Connections are now created and destroyed per use
conn = mssql_python.connect(connection_string)
Note
Configura la configuración de pooling antes de establecer cualquier conexión. Llamar pooling() después de crear conexiones no tiene ningún efecto.
Cómo funciona la agrupación
Aislamiento de cadenas de conexión
Cada cadena de conexión distinta mantiene su propio grupo independiente. Los pools no comparten conexiones entre diferentes cadenas de conexión:
# These use separate pools
conn1 = mssql_python.connect("Server=<server1>;Database=<database1>;...")
conn2 = mssql_python.connect("Server=<server2>;Database=<database2>;...")
Ciclo de vida de la conexión
Conseguir (conseguir una conexión):
- La piscina elimina conexiones ranciadas (en reposo o expiradas).
- La piscina intenta reutilizar una conexión existente:
- Comprueba si la conexión está activa.
- Reinicia el estado de conexión.
- Si ambas comprobaciones tienen éxito, devuelve la conexión.
- Si no existe ninguna conexión reutilizable y el pool está bajo
max_size, el controlador crea una nueva conexión. - Si el pool está a plena capacidad sin conexiones válidas, el controlador genera un error.
Liberar (devolver una conexión):
- Si la piscina tiene capacidad, almacena la conexión para su reutilización.
- Si el pool está en
max_size, el driver cierra la conexión inmediatamente.
Chequeos de salud de la conexión
El controlador realiza comprobaciones de salud de la conexión antes de reutilizar una conexión agrupada.
- Comprobación de actividad: Garantiza que la conexión de red siga siendo válida.
- Comprobación de reinicio: Reinicia el estado de la sesión (nivel de aislamiento, ajustes) para una reutilización limpia.
Si alguna de las pruebas falla, el pool descarta la conexión y crea una nueva.
Limpieza automática
-
Tiempo de espera en reposo: El controlador cierra conexiones que no se usan durante más tiempo que el
idle_timeoutvalor. -
Salida del proceso: Un
atexitgestor cierra todas las conexiones agrupadas cuando el proceso en Python sale.
procedimientos recomendados
Dimensiona tu piscina adecuadamente
Ajusta el tamaño de tu grupo a la concurrencia de tu solicitud.
# For a web application with 20 concurrent requests
mssql_python.pooling(max_size=25) # Slightly more than expected concurrency
Utilizar gestores de contexto
Los gestores de contexto se aseguran de que devuelvas correctamente las conexiones al pool.
with mssql_python.connect(connection_string) as conn:
cursor = conn.cursor()
cursor.execute("SELECT TOP 5 Name, ListPrice FROM Production.Product")
rows = cursor.fetchall()
# Connection returned to pool
Mantén las cadenas de conexión consistentes
Diferentes parámetros en las cadenas de conexión crean pools separados.
# These create THREE separate pools (inefficient)
conn1 = mssql_python.connect("Server=<server>;Database=<database>;Encrypt=yes;")
conn2 = mssql_python.connect("SERVER=<server>;DATABASE=<database>;ENCRYPT=yes;") # Different case
conn3 = mssql_python.connect("Server=<server>;Database=<database>;Encrypt=yes;", timeout=30) # Extra parameter
# Use a constant connection string instead
CONNECTION_STRING = "Server=<server>;Database=<database>;Encrypt=yes;"
conn1 = mssql_python.connect(CONNECTION_STRING)
conn2 = mssql_python.connect(CONNECTION_STRING) # Same pool
Consideremos los límites de conexión de Azure SQL
Azure SQL Database aplica límites de conexión basados en el nivel de servicio. Los siguientes valores son aproximados; Consulta la documentación enlazada para conocer los límites actuales:
| Nivel de servicio | número máximo de conexiones simultáneas |
|---|---|
| Basic | 30 |
| S0-S2 estándar | 60-120 |
| Versiones estándar S3 y posteriores | 200 |
| Premium | 500 |
Ajusta el valor de max_size para que quede por debajo de estos límites.
# For Azure SQL Standard S2 (120 limit)
mssql_python.pooling(max_size=100) # Leave headroom
Ajusta el tiempo de espera de inactividad para tu carga de trabajo
-
Conexiones frecuentes: Usa un valor más largo
idle_timeoutpara mantener las conexiones calientes. -
Conexiones esporádicas: Usa un valor más
idle_timeoutcorto para liberar recursos.
# High-frequency API: keep connections warm
mssql_python.pooling(idle_timeout=1800) # 30 minutes
# Batch job running every hour: release between runs
mssql_python.pooling(idle_timeout=60) # 1 minute
Limitations
La implementación actual tiene algunas limitaciones en comparación con otros controladores:
| Feature | Situación |
|---|---|
ClearPool() / ClearAllPools() |
No está disponible. |
| Estadísticas/supervisión de grupos | No está disponible. |
| Sobrescritura del pool por conexión | No está disponible. |
| Tamaño mínimo de la piscina | No se puede configurar. |
Ejemplo: patrón de aplicación web
El siguiente ejemplo de Flask muestra cómo las conexiones se agrupan de forma transparente entre peticiones:
import mssql_python
from flask import Flask, g
app = Flask(__name__)
# Configure pooling at startup
mssql_python.pooling(max_size=20, idle_timeout=300)
def get_db():
if 'db' not in g:
g.db = mssql_python.connect(app.config['DATABASE_URL'])
return g.db
@app.teardown_appcontext
def close_db(error):
db = g.pop('db', None)
if db is not None:
db.close() # Returns to pool
@app.route('/products')
def list_products():
conn = get_db()
cursor = conn.cursor()
cursor.execute("SELECT TOP 5 Name, ListPrice FROM Production.Product")
return cursor.fetchall()
Reconoce el agotamiento en la piscina
Cuando todas las conexiones de la piscina están en uso y solicitas una nueva conexión, observas síntomas como:
- Las conexiones se quedan o se apagan mientras esperan una conexión libre.
- El rendimiento de la aplicación cae repentinamente bajo carga.
- El consumo de memoria aumenta a medida que el controlador crea conexiones que no puede reutilizar.
Causas comunes:
- Las conexiones no se devuelven a la piscina. Siempre cierra las conexiones cuando termines, o usa gestores de contexto. Una conexión que no está cerrada permanece comprobada.
- La piscina es demasiado pequeña para la carga de trabajo. Si tienes 50 solicitudes concurrentes pero
max_size=20tienes 30 solicitudes en espera. - Las consultas de larga duración mantienen conexiones. Divide las operaciones de larga duración o usa conexiones dedicadas para el procesamiento por lotes.
Cómo corregir:
# 1. Always use context managers to guarantee return
with mssql_python.connect(connection_string) as conn:
cursor = conn.cursor()
cursor.execute("SELECT ...")
rows = cursor.fetchall()
# Connection returned to pool here, even if an exception occurs
# 2. Size the pool to match your concurrency
mssql_python.pooling(max_size=50) # Match or slightly exceed expected concurrent connections
# 3. Reduce idle timeout if connections go stale
mssql_python.pooling(idle_timeout=120)