El uso de connection pooling es una técnica importante desde el punto de vista de rendimiento de SQL Server. Si cada petición que lanzáramos a la base de datos tuviera que pasar necesariamente por el proceso completo de conexión al servidor, con su autenticación, etc. el rendimiento sería muy pobre.

Desgraciadamente aún nos encontramos con aplicaciones, casi siempre heredadas, que no utilizan connection pooling y por tanto abren y cierran físicamente la conexión cada vez con la base de datos. Una buena forma de detectar si nuestras aplicaciones están utilizando o no connection pooling es analizando los contadores de rendimiento Login/sec y Logout/sec. Cuando estos valores sean elevados respecto al número de conexiones existentes entonces con una alta probabilidad estaremos teniendo este problema al menos en parte de las aplicaciones que conectan contra nuestro servidor.

En algunos casos extremos podemos tener valores elevados de estos valores si tenemos muchas aplicaciones que, aun utilizando pooling, generen picos de conexiones concurrentes elevadas. Esto hará que el tamaño del pool crezca para poder servir este número de conexiones que se necesitan de forma puntual, generando un pico de Login/sec. Pasado un tiempo de inactividad (por defecto suele ser 60 segundos) las conexiones se cerrarán por falta de uso generando un pico de Logout/sec. Si tenemos muchos clientes con este mismo comportamiento podemos llegar a tener, en todo momento, un número elevado de Login/sec y de Logout/sec causados por estas oscilaciones en los tamaños de los pools sin que realmente tengamos aplicaciones que no utilicen connection pooling. Este timeout de desconexión puede indicarse al proveedor vía cadena de conexión o también mediante configuración directa del proveedor.

En el caso de ODBC por ejemplo podemos controlar el pool timeout (CPTimeout) desde el administrador de Data Sources:

La importancia del connection pooling cuando usamos SSL/TLS sobre TDS

También tenemos casos en los que el mal uso del connection pooling es el problema de los problemas de rendimiento sufridos. Por ejemplo, imaginemos que para evitar el delay que ocurre cuando nos conectamos a un servidor a través de un pool y tenemos que abrir la conexión físicamente se decide configurar un mínimo de 100 conexiones abiertas en una aplicación cliente-servidor. Puede parecer excesiva esta medida, pero cuando la autenticación del usuario recae en Active Directory, tenemos muchos usuarios distintos y el AD se encuentra saturado o lejano geográficamente (y no tenemos AD secundarios locales) el proceso de login puede durar hasta varios segundos. Seguramente alguien se ha topado con este problema especialmente al intentar conectar con SQL Database desde el Microsoft SQL Management Studio. Por defecto el Microsoft SQL Management Studio utiliza 15 segundos como login timeout lo cual resulta insuficiente en ocasiones para completar el proceso de enrutado y login.

El problema de mantener un pool con un mínimo tan elevado de conexiones es que éstas no se cerrarán y si el número de usuarios de dicha aplicación cliente-servidor aumenta, el número de conexiones aumentará también de forma lineal. El límite de conexiones que una instancia de SQL Server puede aceptar es de 32767 por lo que con menos de 330 usuarios de la aplicación el servidor quedará saturado no aceptando más usuarios ni conexiones. Por tanto, la clave estará en configurar de forma equilibrada los valores mínimos para el pool de conexiones, el valor máximo y el tiempo que dichas conexiones permanecerán abiertas.

Una vez introducida la importancia del buen uso del connection pooling queremos mostrar otro escenario que puede amplificar más aún el impacto de no utilizar connection pooling. Concretamente un cliente nos contactó con problemas de rendimiento derivados de la activación de la encriptación SSL de las conexiones con SQL Server. No es habitual encontrarnos con este tipo de problemas ya que, aunque la encriptación SSL tiene un coste extra, en general es asumible y no supone más que un pequeño incremento en el consumo de CPU total del servidor. Sin embargo, en este caso el consumo de CPU no era excesivo y los tiempos de ejecución de las consultas similares, pero sin embargo lo que sí teníamos eran ralentizaciones durante el proceso de conexión. Por tanto, el problema de rendimiento era debido a esperas durante el proceso de conexión a la base de datos una vez se habilitaba y forzaba el uso de SSL.

Para verificar que efectivamente existe un impacto medible realizamos una prueba de concepto donde estresaríamos una máquina virtual para comprobar el impacto de forzar la encriptación SSL. El primer paso es configurar SQL Server con un certificado SSL apropiado para ello. Es importante que el certificado cumpla ciertas condiciones ya que en caso contrario no será aceptado. En la sección de troubleshooting de este artículo podemos encontrar más información: (https://support.microsoft.com/en-us/help/316898/how-to-enable-ssl-encryption-for-an-instance-of-sql-server-by-using-mi)

Aunque nos salgamos un poco de contexto es conveniente indicar que este certificado no tiene nada que ver con el que necesitaríamos por ejemplo para una encriptación TDE. Para poder encriptar con TDE necesitaríamos un certificado obtenido siguiendo el siguiente proceso: https://blogs.msdn.microsoft.com/sql_pfe_blog/2014/02/04/generating-a-trusted-tde-certificate-in-the-proper-format-from-a-certificate-authority/ Si tuviéramos que reutilizar un pfx existente habría que hacer una conversión con esta herramienta para adaptarlo al formato requerido: https://support.microsoft.com/en-ph/help/2914662/how-to-use-pfx-formatted-certificates-in-sql-server

Para la prueba de concepto crearemos un certificado autofirmado con este comando powershell:

La importancia del connection pooling cuando usamos SSL/TLS sobre TDS

Con este comando el certificado creado se cargará en el store “personal”:

La importancia del connection pooling cuando usamos SSL/TLS sobre TDS

 

Para que la validez del certificado pueda ser validada tendremos que exportar dicho certificado e importarlo dentro la carpeta con los certificados raíz de confianza. Normalmente este proceso no será necesario ya que el certificado que utilicemos vendrá de una fuente de certificación de confianza:

La importancia del connection pooling cuando usamos SSL/TLS sobre TDS

Antes de forzar el uso de encriptación realizaremos una prueba donde lanzaremos una consulta extremadamente sencilla con 50 threads y 100 iteraciones. Antes de lanzar la carga configuraremos la conexión a la base de datos sin connection pooling:

La importancia del connection pooling cuando usamos SSL/TLS sobre TDS

La importancia del connection pooling cuando usamos SSL/TLS sobre TDS

Podemos ver que sin encriptación SSL tenemos un tiempo total de ejecución de 14 segundos y un tiempo de respuesta medio de 9 milisegundos que nos servirá como línea base cuando comparemos con el entorno con SSL. Si monitorizamos el número de logins por segundo que alcanzamos podemos ver que llegamos a un pico de 450 por segundo:

La importancia del connection pooling cuando usamos SSL/TLS sobre TDS

Para configurar la encriptación SSL abriremos el Configuration Manager de SQL Server y en la sección “protocols” editaremos sus propiedades y activaremos el flag para forzar la encriptación de las conexiones:

La importancia del connection pooling cuando usamos SSL/TLS sobre TDS

En la pestaña “certificate” seleccionaremos el certificado que hemos creado previamente y reiniciaremos el servicio de SQL Server:

La importancia del connection pooling cuando usamos SSL/TLS sobre TDS

Antes de lanzar la carga comprobaremos que efectivamente las conexiones que realicemos contra el servidor están efectivamente encriptadas consultando la DMV sys.dm_exec_connections:

La importancia del connection pooling cuando usamos SSL/TLS sobre TDS

El siguiente paso será volver a lanzar la carga anterior contra el servidor:

La importancia del connection pooling cuando usamos SSL/TLS sobre TDS

Podemos ver que el tiempo total ha subido a casi 19 segundos (un 35% más) y el tiempo medio por ejecución de 9ms a 46ms. En lo que respecta al número de conexiones por segundo que podemos procesar vemos que se estancan en menos de 300 (vs las 450 que alcanzábamos sin SSL):

La importancia del connection pooling cuando usamos SSL/TLS sobre TDS

Queda por tanto claro que el número de conexiones por segundo que podemos abrir depende de forma importante de si habilitamos el SSL o no. En casos donde no tengamos paralelismo o éste sea más moderado las latencias por conexión pueden tener un impacto mucho mayor ya que el aumento de la latencia será más significativo. En el siguiente gráfico mostramos un caso real donde podemos ver que pasamos de tiempos de 10 segundos para un proceso serial sin SSL a más de 30 segundos con el SSL activado para el mismo proceso:

La importancia del connection pooling cuando usamos SSL/TLS sobre TDS

En conclusión, en condiciones normales, donde el connection pooling es utilizado de forma correcta, el uso de SSL no supone una sobrecarga relevante ni genera problemas. Sin embargo, donde ya teníamos una situación problemática previa (no uso de connection pooling y un proceso serial)  la activación de SSL sí puede empeorar la situación de forma notable. Recomendamos por tanto antes de habilitar a ciegas el SSL realizar una revisión previa del servidor para asegurarnos que no tenemos ya un problema previo que pudiera verse amplificado con su activación.

0 Shares:
Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

You May Also Like