Alineamiento de particiones

Hola

Existe abundante información acerca del impacto que tiene este tema en el rendimiento de las cargas de trabajo que hacen un uso intensivo del sistema de almacenamiento. Si indagáis un poco es frecuente encontrar datos que justifican ganancias/pérdidas de rendimiento de hasta el 30-40% por el hecho de tener las particiones alineadas o desalineadas en sistemas que usan “arrays” de discos que usen diferentes niveles de tolerancia a fallos.

Los sistemas de almacenamiento modernos son lo suficientemente complejos como para que el viejo modelos para representar a los discos basado en Cilindros, Cabezas y Sectores (CHS), o el esquema LBA para direccionar la información que almacenan, se puedan considerar una mera simplificación conceptual. Sin embargo, estos tres factores tienen especial relevancia en el fenómeno del alineamiento/desalineamiento de las particiones de un array de discos.

  • Partition offset: Esta cifra representa el sector del disco a partir del cual empieza la partición y es la principal responsable de todo este jaleo. El Master Boot Record (MBR), que ocupa siempre el primer sector del disco (512 KB), alberga la tabla de particiones que localizan la ubicación física de los diferentes volúmenes, la famosa “firma” del disco y el código máquina que se encarga de recibir el control de la BIOS tras el POST e invoca el código del Boot Sector de la partición que esté activa, que será quien comience a cargar los binarios del sistema operativo. La primera partición no comienza inmediatamente después, en el segundo sector, sino que se desplaza un cierto número de ello. Esto es así porque históricamente muchos sistemas operativos, entre ellos Windows, obligaban a que las particiones empezaran en el principio de un cilindro, por lo que el MBR hacía que hubiese que descartar la primera pista del disco (p.e, 63 sectores = 63 x 512 B = 31,5 KB)
  • Stripe Unit Size: En los sistemas en los que un volumen comprende más de un disco físico, las controladoras definen un cierto tamaño por defecto para cada una de las bandas que se usarán para almacenar datos y paridades en los sistemas RAID. Estas bandas suelen comprender un cierto número de sectores de cada disco y por tanto su tamaño será un múltiplo del tamaño de sector. Por lo general este es un valor configurable que debe ser cuidadosamente elegido teniendo en cuenta cómo la carga de trabajo va a realizar las operaciones de lectura/escritura sobre el almacenamiento. El Windows Volume Manager define un valor de 64 KB para la Stripe Unit Size, y las diferentes soluciones hardware pueden especificar valores que van desde 4 KB hasta 1 MB, e incluso más.
  • Allocation Unit: También llamado “Cluster”, este valor representa el menor tamaño posible que puede ocupar un fichero. Su valor por defecto depende del tamaño del volumen, aunque se puede especificar explícitamente a la hora de formatear. En NTFS, y para volúmenes de más de 2 GB, es de 4 KB y puede tener un valor máximo de 64 KB. Sobre el papel, por cuestiones de aprovechamiento de espacio su valor debe aproximarse al tamaño medio de fichero, y por razones de rendimiento al del “average disk transfer size”.

El alineamiento de las particiones se basa en buscar una buena combinación de los tres parámetros anteriores, de manera que una cierta operación de lectura/escritura no suponga tener que ir a buscar los datos a más de un disco de los que conforman el volumen. Si para ciertas peticiones tenemos que acabar leyendo o escribiendo en diferentes discos, la acumulación de las mismas puede conllevar una pérdida de rendimiento muy significativa. Para evitar esto, es importante que las siguientes relaciones den como resultado un número entero:

  • Partition Offset / Stripe Size Unit
  • Stripe Size Unit / Allocation Unit

Esto se entiende muy bien con un el siguiente gráfico. En el vamos a suponer que la Stripe Size Unit es 64 KB y analizaremos cinco casos en los que usaremos diferentes Partition Offsets y tamaños de cluster. Lamentablemente no se puede pintar bien a escala, por lo que los guioncillos intermedios representan que la gráfica se “estira” por ellos. Cada sector representa 512 Bytes.

Alineamiento de particiones

  1. Partición “desalineada” con un offset de 63 sectores = 63 x 512 B = 32256 B = 31,5 KB, y con un tamaño de cluster de 4 KB: En este caso, el noveno bloque de 4 KB cae entre dos discos (recordemos que el dibujo no esta a escala y que (64-31,5)/4=8,1). Desafortunadamente este offset es un valor por defecto bastante común en el pasado.
  2. Partición “cuasi-alineada” con un offset de 64 sectores = 64 x 512 B = 32768 B = 32 KB, y con un tamaño de cluster de 4 KB: Aquí nos caben 8 bloques exactos de 4 KB en la primera banda y 16 en las siguientes, pero ningún cluster se expande a más de un disco. Como se puede observar, la división del Partiton Offset y la Stripe Size Unit no da un número entero, por lo que no nos podríamos fiar. Como veremos en el cuarto ejemplo, una variación del tamaño de cluster podría estropear las cosas.
  3. Partición “alineada” con un offset de 128 sectores = 128 x 512 B = 65536 B = 64 KB, y con un tamaño de cluster de 4 KB: En este caso, el offset coincide exactamente con el Stripe Set Unit. Por consiguiente, cualquier situación en la que este valor sea múltiplo del tamaño de cluster deja la partición alineada.
  4. Partición “desalineada” con un offset de 63 sectores = 63 x 512 B = 32256 B = 31,5 KB, y con un tamaño de cluster de 64 KB: Aquí hemos aumentado el tamaño del cluster al valor máximo permitido en NTFS (64 KB), que se recomienda por ejemplo para los volúmenes que vayan a almacenar bases de datos de Exchange o SQL. Esta es la peor situación posible, porque cada operación sobre un cluster siempre nos va a suponer una doble lectura o escritura en dos discos diferentes. Hemos usado 63 sectores como offset, pero lo mismo hubiera dado cualquier valor que no sea 128 sectores, que es justo el último ejemplo.
  5. Partición “alineada” con un offset de 128 sectores = 128 x 512 B = 65536 B = 64 KB, y con un tamaño de cluster de 64 KB: Ahora hemos elegido el mismo valor (64 KB) tanto para el Partition Offset, el Stripe Size Unit y la Allocation Unit, lo cual nos da de forma inmediata una partición alineada.

La buena noticia es que el desalineamiento es fácil de detectar, y también es fácil crear particiones alineadas. La mala es que corregir la situación a posteriori supone reparticionar y formatear de nuevo.

Comprobando si las particiones están o no alineadas

Habida cuenta de que conocemos el Stripe Set Unit que utiliza nuestro almacenamiento, el Partition Offset y el tamaño de cluster los podemos obtener así:

  • wmic partition get BlockSize, StartingOffset, Name, Index: De aquí sacamos el Offset de cada partición en bytes. BlockSize se refiere al tamaño de sector.

image

  • wmic volume get DriveLetter, BlockSize, DeviceId: En este caso el valor de BlockSize representa la Allocation Unit o tamaño de cluster del sistema de archivos. Puede utilizarse también el comando fsutil fsinfo ntfsinfo <letra unidad:>

image

El comando DISKPART también muestra el Offset de las particiones, sin embargo no es de fiar, porque lo da en KB y redondea. En el primer ejemplo de la gráfica anterior nos hubiera engañado miserablemente mostrando 32 KB.

Si nos salen las cuentas, estupendo. Si no, nos espera la tediosa tarea de rehacer nuestras particiones, con lo que eso supone en lo tocante al salvaguardado de los datos y su disponibilidad durante el proceso.

Generando particiones alineadas

  • Cuando creamos una partición sobre una LUN con Windows Server 2008, Windows Vista o posteriores, ya se incluye por defecto un offset de 1 MB (1048576 bytes). Esto produce un alineamiento automático para casi todos los Stripe Sizes presentes en los sistemas de almacenamiento, ya que 1 MB es un múltiplo de 64 KB, 128 KB, 256 KB y 512 KB. No obstante siempre es posible afinar o incrementar dicho valor exactamente igual que lo haremos en Windows Server 2003, o incluso de una manera más elegante. ¡Configurándolo en el registro!

image

Una vez creada la partición, la formatearemos usando el tamaño de cluster deseado, pero recordando que la relación Stripe Unit/Allocation Unit debe dar también un entero. Sin embargo es muy improbable que esto no sea así.

Eligiendo sabiamente los valores de la Stripe Set Unit y Allocation Unit antes de ponerse manos a la obra

Desafortunadamente, aquí no podemos hablar de a existencia de una regla general. Estos valores deben ser elegidos en función de la naturaleza de la carga de trabajo, teniendo en cuenta el balance entre lecturas y escritoras, si serán secuenciales o aleatorias, en bloques de qué tamaño se escribirá/leerá la información, etc., y también de como se comportan las cachés y cada almacenamiento en particular. Por eso es muy frecuente encontrar guías específicas de cada fabricante para las cargas de trabajo más frecuentes.

Así es que antes de hacer nada “sabiamente” no nos queda otra que leernos esto para empezar:

para posteriormente bucear entre los whitepapers de los fabricantes de nuestras cabinas.

Vamos a dejarlo aquí por ahora. Supongo que los que hayáis llegado a leer hasta aquí os estaréis preguntando cómo aplica todo esto a entornos virtualizados, tanto a nivel de host como de máquina virtual. Es de cajón que las LUN donde se almacenen las VMs, o los discos pass-through es importante que estén alienados. Pero, ¿y las propias particiones de las VMs?. ¿Que tamaños de cluster y Stripe Unit Set son adecuadas?. Lo veremos en otro post.

CREDITOS:

REFERENCIAS:

David Cervigón