Durante una plática con amigos sobre cómo obtener un mejor performance de SQL Server, me hicieron la siguiente pregunta… ¿Existe alguna otra optimización para aplicar a un servidor de SQL Server, aparte de aplicación de Best Practice a nivel de sistema operativo y Aplicación? A lo cual les indique que también se podrían hacer optimizaciones a nivel Hardware, en este caso a nivel Storage.

Con lo anterior, empezamos a explicar el tema de SAN pero enfocándolo a Administradores de Base de Datos.

Son muchos factores los que afectan el buen rendimiento de I/O de los discos, factores como el Discos compartidos o dedicados, niveles de RAID, la velocidad del bus, configuraciones de adaptadores HBA, un punto muy importante que frecuentemente se pasa por alto es la alineación en las particiones de disco.

Algunos de los factores no-disco en los que se puede observar cuellos de botella son:

-          HBA (Host Bus Adapters) o tarjetas de interface de red

-          Capacidad de procesamiento de FC (Fibre Channel) o puertos iSCSI

-          Switch

-          Numero de paths entre el servidor y el storage.

Es importante considerar y entender los límites de los componentes envueltos en la arquitectura, algunos de los límites que se tienen establecidos en el mercado son:

Component

Limits

SAS cable

Theoretical: 1.5 gigabytes per second (GB/s)

Typical: 1.2 GB/s

PCI-X v1 bus

X4 slot: 750 MB/s

X8 slot: 1.5 GB/s

X16 slot: roughly 3 GB/s

PCI-X v2 bus

X4 slot: 1.5 – 1.8 GB/s

X8 slot: 3 GB/s

Note: Be aware that a PCI-X bus can be v2 compliant but still run at v1 speeds.

Fibre Channel HBAs, switch ports and front end Fibre Channel array ports

4 gigabits per second (Gbps): 360-400 MB/s

8 Gbps: Double the speed of 4 Gbps

Note: Make sure to consider the limits of the PCI bus. An 8-Gbps card requires a PCI-X4 v2 slot or faster.

Pero,  ¿Cómo se liga todo lo anterior con SQL Server? La unidad fundamental de almacenamiento de datos en SQL Server es la página (8KB), el espacio asignado a un archivo de datos (mdf o ndf) de una base de datos se divide lógicamente en páginas enumeradas de forma continua de 0 a n. La operación de I/O de disco se realiza a nivel página.

Los Discos duros están conformados por platos finos y circulares, en su superficie poseen medios de comunicación electrónicos que almacenan información. Cada lado de cada plato cuenta con miles de pistas o tracks, un set de tracks con el mismo diámetro en toda la superficie del plato conforman un cilindro (Para los nuevos dispositivos el concepto de cilindro no es relevante, ya que no están dispuestas en círculos concéntricos, sin embargo es útil entender el origen de los términos). Cada superficie de disco tiene dedicada una cabeza de I/O.  Las pistas o tracks se dividen en sectores. Un sector es el fragmento mínimo de datos  que se pueden leer o escribir en un disco duro. Las nuevas unidades pueden ofrecer sectores de 1KB, 3KB o 4 KB.

Con la tecnología RAID, la data es repartida a través de un grupo de discos físicos. El esquema de distribución de la data determina como el sistema operativo hace las operaciones de I/O de los datos. La granularidad con la cual la data es almacenada en un disco antes de que la data se almacena en otro de los discos del grupo de llama stripe unit size. La colección de stripe units, desde el primer disco al último del grupo se conoce como stripe.

Pero con todo esto que es la Alineación de las particiones? Y que efecto tiene en el performance de SQL Server???  En el siguiente diagrama se explica.. La línea verticl punteada negra que se superponen a un a la línea de color rojo corresponden a los límites entre diferentes discos físicos de un RAID. Las versiones anteriores a Windows Server 2008 nuestra los 63 sectores reservados reportados por el hardware del disco, inmediatamente después de lo cual el resto de la partición  son expuestas al usuario. En la figura, el tamaño común del sector que se utiliza es de 512 bytes. El tamaño del Stripe unit en el ejemplos  es de 64 KB, y 4KB para el tamaño de clúster NTFS, adecuado para, un file server. La falta de alineación de discos obliga a que el octavo clúster de 4KB de data se establezca a través de dos stripe units. Iniciando con el último sector vacío de 512 bytes del primer stripe unit y continuando con el segundo stripe unit. Esta situación se perpetua en el resto de la partición, ya que cada cierto numero el clúster de data se establecerá en dos stripe unit, por lo tanto dos I/O son requeridos para realizar una Lectura o Escritura.

El file allocation Unit size (Clúster size) recomendado para SQL Server es de 64KB; esta mejor practica en combinación con la desalineación de disco que existe por defecto fuerza que la data se establezca en dos stripe units, iniciando con el primer sector disponible del primer stripe unit y continuando con el segundo stripe unit. Esta situación es perpetuada en el resto de la partición. En esta configuración, cada clúster es escrito en dos stripe units, esto significa que todas las escrituras y lecturas se ven afectadas

El siguiente es un experimento en el cual se analizó el performance de disco, la prueba se realizó Windows Server 2003 y SQL Server 2005. Se ejecutó un query para extraer la información de SQL Server, durante cada ejecución se aplicó DBCC DROPCLEANBUFFERS para limpiar el buffer cache de SQL Server, con esto obtener pruebas satisfactorias. Los contadores de performance que se monitorearon fueron Avg. Disk Transfer/sec de los objetos PhysicalDisk y LogicalDisk los cuales son utilizados para la métrica de la latencia del disco. Los resultados muestran una mejoría significante comparando la alineación de discos, las métricas muestran una mejoría mayor al 30% entre latencia y duración.

Para la revisión de una correcta alineación de discos, es recomendable tener claro varios conceptos:

-          Starting Partition Offset: Es el punto inicial en la partición del volumen que garantiza la omisión de asignación de páginas de datos en n sectores ocultos al principio de los volúmenes. 

-          Stripe Unit Size: Es la granularidad a la que la data se almacena en un disco del arreglo antes de que la data subsiguiente sea almacenada en otro disco del arreglo. Este valor es proporcionado por su administrador de la SAN

-          File Allocation Unit Size: Es conocido también como Clúster Size, y representa la cantidad mínima de espacio de disco que puede ser suministrado para contener un archivo y se determina cuando la partición es formateada por el sistema operativo.

Existen dos reglas, que se deben cumplir para una correcta alineación de discos. Los resultados de los cálculos siguientes han de dar un valor entero.

Partition_Offset / Stripe_Unit_Size

Stripe_Unit_Size / File_Allocation_Unit_size

De las dos reglas anteriores, la primera es la más importante para conseguir un rendimiento óptimo.

Ejemplos de Escenarios con desalineación en los discos

Dada una partición con Starting Partition Offset de 32.256 bytes (31,5Kb) y con un tamaño en Stripe Unit Size de 65.536 bytes (64 Kb), el resultado de Partition_Offset ÷ Stripe_Unit_Size es de 0.4921875, no es un número entero, por lo que se consideran que los discos no están alineados.

Ejemplo de escenario con alineación en los discos

Dada una partición con Starting Partition Offset de 1048576 bytes (1Kb) y con un tamaño de Stripe Unit Size de 65.536 bytes (64 Kb), el resultado de Partition_Offset ÷ Stripe_Unit_Size es exactamente 8, un numero entero exacto, lo cual se puede decir que la alineación es correcta.

Después de todo lo anterior explicado, la pregunta que hace falta contestar es… ¿Y como puedo consultar el estado actual de los discos?

Para revisar el valor del Starting Offset en discos basicos, podemos utilizar el comando WMIC (Windows Management Instrumentation Command-line) para obtener los datos del disco, la sintaxis es la siguiente:

wmic partition get BlockSize, BootPartition, DeviceID, DiskIndex, HiddenSectors, NumberOfBlocks,  StartingOffset, Name, Index

El valor a verificar con el commando anterior es StartingOffset, en este ejemplo está alineado a 1024 kb.

También se puede obtener el resultado a través de DISKPART, seleccionando el disco a analizar y ejecutando el comando list partition, en el cual se obtendrá el Offset.

Para revisar el Starting Offset en discos básicos se deberá utilizar la utilidad dmdiag con el switch -v

Si se desea revisar el valor del File_Allocation_Unit_Size se puede ejecutar el comando

fsutil fsinfo ntfsinfo [drive]

El siguiente ejemplo muestra la ejecución de todos los comandos anteriormente escritos.

Conclusión

Muchos factores contribuyen para un óptimo performance de disco. Para las particiones de disco creadas con Windows Server 2003, es adecuado validar la correcta correlación entre el Stripe Unit Size y File Allocation Unit Size como best practice. Windows Server 2008 crea particiones alineadas por default y aunque para la mayoría de los casos es adecuada, es importante siempre preguntar y seguir las mejores practicas del Vendor de discos. Cuando los servidores son actualizados de Windows Server 2003 a Windows Server 2008, las particiones preexistentes no se alinean automáticamente, es recomendable reconstruirlas para un rendimiento óptimo.

“Las opiniones e ideas expresadas en este blog son las de los Autores y no necesariamente declaran o reflejan la opinión de Microsoft”

Este material tambien lo podras acceder en http://blogs.technet.com/b/sql_pfe_latam/