No, no todas las máquinas virtuales son iguales

No, no todas las máquinas virtuales son iguales

Es muy habitual que nos encontremos en nuestros clientes situaciones de lo más variopintas en cuanto al rendimiento de las máquinas virtuales con SQL Server. En muchos casos lo que encontramos son casos donde el rendimiento está lejos del ideal, pero en general la virtualización en sí, no tiene la culpa. Lo que suele ocurrir es que cuando virtualizamos un SQL Server que teníamos en máquina física pasamos a disponer de una cantidad máxima o puntual de recursos (CPU/memoria/IO) sustancialmente distinta a las que teníamos en la máquina física. (más…)

Latencias de red < 1ms, ¿es suficiente para un buen rendimiento de SQL Server?

Latencias de red < 1ms, ¿es suficiente para un buen rendimiento de SQL Server?

Poco a poco, a medida que el almacenamiento se vuelve más rápido, va popularizándose el almacenamiento SSD local, etc. los tiempos de acceso a disco van bajando sustancialmente. El máximo exponente en este sentido lo encontramos en sistemas con SSDs Optane que se caracterizan por tener unas latencias de lectura/escritura mucho más bajas que los SSD tradicionales y además ir directamente conectados al bus PCIe: (más…)

Azure Files Premium + SQL Server Failover Cluster instance= OnPremise to Cloud simplificado

Azure Files Premium + SQL Server Failover Cluster instance= OnPremise to Cloud simplificado

Uno de los problemas que muchos clientes se encuentran al intentar migrar instancias OnPremise a Cloud es la ausencia de un «storage compartido» sencillo. Existen alternativas, apoyadas en software de terceros o bien soluciones SDS, que nos permiten configurar una instancia Failover Cluster en Azure pero no están exentas de complejidad y añaden bastante coste al TCO de la solución. (más…)

Estadísticas supersíncronas

Estadísticas supersíncronas

En nuestro día a día cuando hablamos de estadísticas en SQL Server casi siempre nos centramos en la necesidad de su mantenimiento periódico, a la recomendación de mantener activas las actualizaciones automáticas de estadísticas y, salvo en ciertos casos, las ventajas de la actualización asíncrona de estadísticas. (más…)

Combinando NGrams y FullText Search

Combinando NGrams y FullText Search

Con bastante frecuencia nos encontramos que nuestros clientes sufren problemas de rendimiento debido a filtros sobre campos de texto. Es bastante habitual que se quiera permitir filtrados “libres” sobre textos, descripciones, documentos, etc. pero no se tenga en cuenta que, en función del patrón de búsqueda, esto puede ser bastante pesado para SQL Server. (más…)

Cazando vampiros de memoria en SQL Server

Cazando vampiros de memoria en SQL Server

Un recurso muy valioso para cualquier motor de base de datos es la memoria. Esta memoria se utilizará con muchos fines, destacando especialmente el cacheo de páginas/segmentos de datos, así como planes de ejecución. También se necesitará memoria para la propia ejecución de las consultas, para mantener temporalmente los buffers necesarios para el procesamiento de los datos, para su ordenación, para almacenar tablas hash, etc. Desgraciadamente no existe un punto único desde donde podamos determinar y diagnosticar todos los consumos de memoria independientemente de su naturaleza por lo que al final tendremos que ir analizando desde un punto de vista más alto hasta uno más bajo para poder poner el dedo exactamente en la llaga que origina el dolor al servidor. (más…)

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

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

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:

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:

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

 

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:

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:

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:

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:

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

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:

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

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):

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:

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.

Rendimiento de SQL Server en sistemas de toma de decisión (OLAP)

Rendimiento de SQL Server en sistemas de toma de decisión (OLAP)

La enorme competencia que viene apoyada por el auge de las nuevas tecnologías obliga a las empresas a tomar decisiones de manera casi inmediata. Hoy día, las empresas son mucho más ágiles que hace 5-10 años y esta agilidad implica compromiso en todas las áreas de las organizaciones: desde la definición y preparación de nuevos productos y servicios, pasando por el análisis de cómo utilizan los usuarios esos servicios hasta la definición de estrategias corporativas. Las decisiones se deben tomar con datos, y esos datos deben estar disponibles cuanto antes para tomar esas decisiones. En medio de ese círculo, se encuentran las bases de datos que, naturalmente, deben proporcionar los datos de formas ágiles y rápidas; probablemente, detrás de este argumento se encuentre el auge de los sistemas BigData que ayudan a tomar decisiones con las famosas 3 V (Volumen, Velocidad, y Variedad), éstos sistemas se apoyan en diferentes modelos de tratamiento de datos. No obstante, en este artículo nos centraremos en una pequeña parte de los modelos de tomas de decisiones, concretamente en sistemas OLAP que cubren un espectro suficientemente grande de los sistemas de ayuda a toma de decisiones del mercado mundial.

(más…)

Curiosidades con Heaps y entornos con alto consumo de CPU

Curiosidades con Heaps y entornos con alto consumo de CPU

Es bastante habitual encontrarnos con el siguiente diálogo al aterrizar en un cliente:

  • SolidQ: ¿Me puedes comentar o mostrar los gráficos del consumo de CPU del servidor X?
  • Cliente: De CPU vamos bien, no es problema.
  • SolidQ: Si no te importa, ¿puedes mostrarme los datos que tienes al respecto?
  • Cliente: Claro. Mira, aquí puedes ver que tenemos medias (en periodos de 5 minutos) del 60% de CPU y en los momentos de más carga no pasamos del 85% de media. Está correcto, ¿verdad?

El problema de esta aproximación a la hora de interpretar a la utilización de recursos es que, intuitivamente, no solemos ser conscientes de qué implicaciones tienen estos grados de utilización tan altos. No debemos confundir la interpretación respecto a la que tendríamos del % de uso de memoria o del % de uso de disco, que únicamente indican cuanta cantidad de memoria/espacio estamos utilizando, pero no el grado de utilización de dicho recurso.

(más…)