Cómo verificar discos con fio para un rendimiento suficiente para etcd

Nota. traducir: Este artículo es el resultado de una mini-investigación realizada por ingenieros de IBM Cloud en busca de una solución a un problema real relacionado con el funcionamiento de la base de datos etcd. Una tarea similar fue relevante para nosotros, sin embargo, el curso de reflexiones y acciones de los autores puede ser interesante en un contexto más amplio.

Cómo verificar discos con fio para un rendimiento suficiente para etcd

Breve resumen de todo el artículo: fio y etcd

El rendimiento de un clúster etcd depende en gran medida de la velocidad del almacenamiento subyacente. etcd exporta varias métricas de Prometheus para monitorear el rendimiento. Uno de ellos es wal_fsync_duration_seconds. En la documentación para etcd diceese almacenamiento puede considerarse lo suficientemente rápido si el percentil 99 de esta métrica no supera los 10 ms…

Si está considerando configurar un clúster etcd en máquinas Linux y desea probar si las unidades (como SSD) son lo suficientemente rápidas, le recomendamos que utilice el popular probador de E/S llamado fio. Basta con ejecutar el siguiente comando (directorio test-data debe estar ubicado en la partición montada de la unidad que se está probando):

fio --rw=write --ioengine=sync --fdatasync=1 --directory=test-data --size=22m --bs=2300 --name=mytest

Solo queda mirar la salida y verificar si el percentil 99 se ajusta fdatasync en 10ms Si es así, entonces su disco está funcionando lo suficientemente rápido. Aquí hay una salida de ejemplo:

fsync/fdatasync/sync_file_range:
  sync (usec): min=534, max=15766, avg=1273.08, stdev=1084.70
  sync percentiles (usec):
   | 1.00th=[ 553], 5.00th=[ 578], 10.00th=[ 594], 20.00th=[ 627],
   | 30.00th=[ 709], 40.00th=[ 750], 50.00th=[ 783], 60.00th=[ 1549],
   | 70.00th=[ 1729], 80.00th=[ 1991], 90.00th=[ 2180], 95.00th=[ 2278],
   | 99.00th=[ 2376], 99.50th=[ 9634], 99.90th=[15795], 99.95th=[15795],
   | 99.99th=[15795]

Algunas notas:

  1. En el ejemplo anterior, hemos ajustado los parámetros --size и --bs para un caso especifico. Para obtener un resultado significativo de fio, especifique valores apropiados para su caso de uso. Cómo elegirlos se discutirá a continuación.
  2. Solo durante la prueba fio carga el subsistema de disco. En la vida real, es probable que otros procesos escriban en el disco (además de los relacionados con wal_fsync_duration_seconds). Esta carga adicional puede aumentar wal_fsync_duration_seconds. En otras palabras, si el percentil 99 de la prueba con fio, solo un poco menos de 10 ms, existe una buena posibilidad de que el rendimiento del almacenamiento no sea suficiente.
  3. Para la prueba necesitarás la versión fio no menos de 3.5, porque las versiones anteriores no agregan resultados fdatasync en forma de percentiles.
  4. La conclusión anterior es solo un pequeño extracto de la conclusión general. fio.

Más sobre fio y etcd

Algunas palabras sobre WAL, etc.

En general, las bases de datos utilizan registro proactivo (registro de escritura anticipada, WAL). etcd también se ve afectado. Una discusión de WAL está más allá del alcance de este artículo, pero para nuestros propósitos, lo que necesita saber es que cada miembro del clúster etcd almacena WAL en almacenamiento persistente. etcd escribe algunas operaciones de almacenamiento de clave-valor (como actualizaciones) en WAL antes de ejecutarlas. Si un nodo falla y se reinicia entre instantáneas, etcd puede recuperar transacciones desde la instantánea anterior en función del contenido de WAL.

Por lo tanto, cada vez que un cliente agrega una clave a la tienda KV o actualiza el valor de una clave existente, etcd agrega la descripción de la operación al WAL, que es un archivo normal en la tienda persistente. etcd DEBE estar 100% seguro de que la entrada WAL realmente se ha guardado antes de continuar. Para lograr esto en Linux, no es suficiente usar la llamada al sistema write, ya que la propia operación de escritura en el medio físico puede retrasarse. Por ejemplo, Linux puede mantener una entrada WAL en un caché del kernel en memoria (por ejemplo, en el caché de la página) durante algún tiempo. Para asegurarse de que los datos se escriben en los medios, se debe invocar una llamada al sistema después de la escritura. fdatasync - esto es exactamente lo que hace etcd (como puede ver en el siguiente resultado strace; aquí 8 - Descriptor de archivo WAL):

21:23:09.894875 lseek(8, 0, SEEK_CUR)   = 12808 <0.000012>
21:23:09.894911 write(8, ".20210220361223255266632$1020103026"34"rn3fo"..., 2296) = 2296 <0.000130>
21:23:09.895041 fdatasync(8)            = 0 <0.008314>

Desafortunadamente, escribir en el almacenamiento persistente lleva algún tiempo. La ejecución prolongada de llamadas fdatasync puede afectar el rendimiento de etcd. En la documentación del repositorio esta indicado, que para un rendimiento suficiente es necesario que el percentil 99 de la duración de todas las llamadas fdatasync al escribir en un archivo WAL fue menos de 10 ms. Hay otras métricas relacionadas con el almacenamiento, pero este artículo se centrará en esa.

Valoración del almacenamiento con fio

Puede evaluar si un determinado almacenamiento es adecuado para usar con etcd usando la utilidad fio — un comprobador de E/S popular. Tenga en cuenta que la E/S del disco puede ocurrir de muchas maneras diferentes: sincronización/asincronía, muchas clases diferentes de llamadas al sistema, etc. La otra cara de la moneda es que fio extremadamente difícil de usar. La utilidad tiene muchos parámetros y diferentes combinaciones de sus valores conducen a resultados completamente diferentes. Para obtener una estimación razonable de etcd, debe asegurarse de que la carga de escritura generada por fio sea lo más parecida posible a la carga de escritura del archivo WAL de etcd:

  • Esto significa que lo generado fio la carga debe ser al menos una serie de escrituras consecutivas en el archivo, donde cada escritura consiste en una llamada al sistema writeseguido por fdatasync.
  • Para habilitar la escritura secuencial, debe especificar la bandera --rw=write.
  • Que fio escribió usando llamadas write (en lugar de otras llamadas al sistema, por ejemplo, pwrite), usa la bandera --ioengine=sync.
  • Finalmente, la bandera --fdatasync=1 asegura que cada write debería fdatasync.
  • Los otros dos parámetros en nuestro ejemplo son: --size и --bs - puede variar según el caso de uso específico. La siguiente sección describirá su configuración.

Por qué elegimos fio y cómo aprendimos a configurarlo

Esta nota proviene de un caso real que nos encontramos. Teníamos un clúster en Kubernetes v1.13 con monitoreo en Prometheus. Los SSD se utilizaron como almacenamiento para etcd v3.2.24. Las métricas de Etcd mostraron latencias demasiado altas fdatasync, incluso cuando el clúster estaba inactivo. Para nosotros, estas métricas parecían muy dudosas y no estábamos seguros de qué representaban exactamente. Además, el clúster constaba de máquinas virtuales, por lo que no era posible decir si el retraso se debió a la virtualización o al SSD.

Además, consideramos varios cambios en la configuración de hardware y software, por lo que necesitábamos una forma de evaluarlos. Por supuesto, sería posible ejecutar etcd en cada configuración y ver las métricas de Prometheus correspondientes, pero eso requeriría un esfuerzo significativo. Lo que necesitábamos era una forma sencilla de evaluar una configuración específica. Queríamos probar nuestra comprensión de las métricas de Prometheus provenientes de etcd.

Esto requirió resolver dos problemas:

  • Primero, ¿cómo se ve la carga de E/S generada por etcd al escribir en archivos WAL? ¿Qué llamadas al sistema se utilizan? ¿Cuál es el tamaño de los bloques de registro?
  • En segundo lugar, digamos que tenemos respuestas a las preguntas anteriores. Cómo reproducir la carga correspondiente con fio? Después de todo fio — utilidad extremadamente flexible con una gran cantidad de parámetros (esto es fácil de verificar, por ejemplo, aquí - aprox. trad.).

Resolvimos ambos problemas con el mismo enfoque basado en comandos lsof и strace:

  • Con lsof puede ver todos los descriptores de archivos utilizados por el proceso, así como los archivos a los que se refieren.
  • Con strace puede analizar un proceso que ya se está ejecutando o ejecutar un proceso y observarlo. El comando muestra todas las llamadas al sistema realizadas por este proceso y, si es necesario, sus descendientes. Este último es importante para los procesos que se bifurcan, y etcd es uno de esos procesos.

Lo primero que hicimos fue usar strace para examinar el servidor etcd en el clúster de Kubernetes mientras estaba inactivo.

Entonces se encontró que los bloques de registros WAL están muy densamente agrupados, el tamaño de la mayoría estaba en el rango de 2200-2400 bytes. Es por eso que el comando al principio de este artículo usa la bandera --bs=2300 (bs es el tamaño en bytes de cada bloque de escritura en fio).

Tenga en cuenta que el tamaño de los bloques de escritura etcd puede variar según la versión, la implementación, los valores de los parámetros, etc. - afecta la duración fdatasync. Si tiene un caso de uso similar, analice con strace sus procesos etcd para obtener valores actualizados.

Luego, para tener una idea clara y completa de cómo funciona etcd con el sistema de archivos, lo comenzamos desde abajo strace con banderas -ffttT. Esto hizo posible capturar procesos secundarios y escribir la salida de cada uno en un archivo separado. Además, se obtuvo información detallada sobre la hora de inicio y la duración de cada llamada al sistema.

También usamos el comando lsofpara confirmar su comprensión de la salida strace en términos de qué descriptor de archivo se usó para qué propósito. tengo la conclusión strace, similar al anterior. Manipulaciones estadísticas con tiempos de sincronización confirmaron que la métrica wal_fsync_duration_seconds de etcd coincide con las llamadas fdatasync con descriptores de archivo WAL.

para generar con fio una carga de trabajo similar a la de etcd, se estudió la documentación de la utilidad y se seleccionaron los parámetros adecuados para nuestra tarea. Hemos verificado que las llamadas al sistema correctas están en curso y confirmado su duración ejecutando fio de strace (como se hizo en el caso de etcd).

Se prestó especial atención a la determinación del valor del parámetro. --size. Representa la carga de E/S total generada por la utilidad fio. En nuestro caso, este es el número total de bytes escritos en los medios. Es directamente proporcional al número de llamadas. write (y fdatasync). para un especifico bs número de llamadas fdatasync igual size / bs.

Como estábamos interesados ​​en el percentil, queríamos que el número de muestras fuera lo suficientemente grande como para ser estadísticamente significativo. Y decidió que 10^4 (que corresponde a un tamaño de 22 MB) será suficiente. Valores de parámetros más pequeños --size dio un ruido más pronunciado (por ejemplo, llamadas fdatasync, que tardan mucho más de lo habitual y afectan al percentil 99).

Tu decides

El artículo muestra cómo usar fio uno puede juzgar si los medios destinados a usarse con etcd son lo suficientemente rápidos. ¡Ahora depende de ti! Puede explorar máquinas virtuales con almacenamiento basado en SSD en el servicio Nube de IBM.

PD del traductor

Con casos de uso listos para usar fio Para otras tareas, consulte documentación o directamente a repositorios de proyectos (hay muchos más de los mencionados en la documentación).

PPS del traductor

Lea también en nuestro blog:

Fuente: habr.com

Añadir un comentario