¿La velocidad del almacenamiento es adecuada para etcd? Preguntemos a fio

¿La velocidad del almacenamiento es adecuada para etcd? Preguntemos a fio

Una breve historia sobre fio y etcd

Rendimiento del clúster etcd depende en gran medida del rendimiento de su almacenamiento. etcd exporta algunas métricas a Prometheus, para proporcionar la información necesaria sobre el rendimiento del almacenamiento. Por ejemplo, la métrica wal_fsync_duration_seconds. En la documentación de etcd se menciona: para que el almacenamiento se considere lo suficientemente rápido, el percentil 99 de esta métrica debe ser inferior a 10 ms. Si planea ejecutar un clúster de etcd en máquinas Linux y desea evaluar si su almacenamiento (como SSD) es lo suficientemente rápido, puede utilizar fio — una herramienta popular para probar operaciones de entrada/salida. Ejecute el siguiente comando, donde test-data es el directorio bajo el punto de montaje del almacenamiento:

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

Solo necesita revisar los resultados y verificar que el percentil 99 de la duración de fdatasync sea menor a 10 ms. Si es así, su almacenamiento es lo suficientemente rápido. Aquí hay un ejemplo de resultados:

  sync (usec): min=534, max=15766, avg=1273.08, stdev=1084.70
  percentiles de sync (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]

Notas

  • Hemos ajustado los valores de los parámetros —size y —bs para nuestro caso específico. Para obtener un resultado útil de fio, proporcione sus propios valores. ¿De dónde obtenerlos? Lea cómo aprendimos a configurar fio.
  • Durante la prueba, toda la carga de I/O proviene de fio. En un escenario real, es probable que también lleguen otras solicitudes de escritura al almacenamiento, además de las correspondientes a wal_fsync_duration_seconds. Carga adicional aumentará el valor de wal_fsync_duration_seconds. Así que si el percentil 99 casi alcanza 10 ms, su almacenamiento no tendrá la velocidad suficiente.
  • Asegúrese de utilizar la versión fio no inferior a 3.5 (las versiones anteriores no muestran percentiles de duración de fdatasync).
  • Lo anterior muestra solo una parte de los resultados de fio.

Una larga historia sobre fio y etcd

¿Qué es WAL en etcd?

Normalmente, las bases de datos utilizan un diario de escritura anticipada; etcd también lo utiliza. Aquí no discutiremos en detalle el registro de escritura anticipada (write-ahead log, WAL). Solo necesitamos saber que cada miembro del clúster etcd lo mantiene en un almacenamiento persistente. etcd registra cada operación con pares clave-valor (por ejemplo, una actualización) en el WAL, antes de aplicarlas al almacenamiento. Si entre las instantáneas uno de los miembros del almacenamiento se cierra inesperadamente y se reinicia, puede recuperar localmente las transacciones desde la última instantánea a partir del contenido del WAL.

Cuando un cliente añade una clave al almacenamiento de pares clave-valor o actualiza el valor de una clave existente, etcd registra esta operación en el WAL, que es un archivo común en el almacenamiento persistente. Antes de continuar con el procesamiento, etcd DEBE estar completamente seguro de que la escritura en el WAL realmente ha ocurrido. En Linux, esto no se logra con una sola llamada al sistema. write, ya que la escritura en el almacenamiento físico puede ser retardada. Por ejemplo, Linux puede mantener la escritura del WAL en memoria caché del núcleo durante un tiempo (por ejemplo, en caché de páginas). Y para asegurarse de que los datos se graban exactamente en el almacenamiento persistente, se necesita una llamada al sistema fdatasync después de la escritura, y etcd precisamente usa esto (como se puede ver en el resultado de la ejecución strace, donde 8 es el descriptor de archivo del WAL):

21:23:09.894875 lseek(8, 0, SEEK_CUR)   = 12808 
21:23:09.894911 write(8, ". 20210220361223255266632$10 20103026"34"rn3fo"..., 2296) = 2296 
21:23:09.895041 fdatasync(8)            = 0

Desafortunadamente, la escritura en el almacenamiento persistente no ocurre instantáneamente. Si la llamada a fdatasync se realiza lentamente, el rendimiento del sistema etcd se ve afectado. En la documentación de etcd se indica, que el almacenamiento se considera suficientemente rápido si en el percentil 99 de las llamadas fdatasync al escribir en el archivo WAL tardan menos de 10 ms. Hay otras métricas útiles para el almacenamiento, pero en esta publicación solo hablamos de esta métrica.

Evaluación del almacenamiento con fio

Si necesitas evaluar si tu almacenamiento es adecuado para etcd, utiliza fio, una herramienta de prueba de carga de entrada y salida muy popular. Es importante recordar que las operaciones en disco pueden ser muy variadas: sincrónicas y asincrónicas, múltiples clases de llamadas al sistema, etc. Como resultado, utilizar fio puede ser bastante complicado. Tiene una gran cantidad de parámetros, y diferentes combinaciones de estos valores producen cargas de entrada y salida completamente diferentes. Para obtener cifras adecuadas para etcd, debes asegurarte de que la carga de escritura de fio esté lo más cerca posible de la carga real de etcd al escribir archivos WAL.

Por lo tanto, fio debe, al menos, generar una carga en forma de una serie de operaciones de escritura secuenciales en un archivo, cada escritura consistirá en una llamada al sistema write, seguida de una llamada al sistema fdatasync. Para las operaciones de escritura secuenciales, fio necesita el parámetro —rw=write. Para que fio utilice la llamada al sistema write al escribir, y no pwrite, es necesario especificar el parámetro —ioengine=sync. Por último, para que fdatasync se llame después de cada escritura, se debe agregar el parámetro —fdatasync=1. Los otros dos parámetros en este ejemplo (—size y —bs) dependen del escenario específico. En la siguiente sección, explicaremos cómo configurarlos.

¿Por qué fio y cómo aprendimos a configurarlo?

En esta publicación, describimos un caso real. Teníamos un clúster Kubernetes v1.13, que monitorizamos con Prometheus. etcd v3.2.24 se hospedaba en SSD. Las métricas de etcd mostraban latencias demasiado altas para fdatasync, incluso cuando el clúster no estaba haciendo nada. Las métricas eran extrañas, y no sabíamos exactamente qué significaban. El clúster constaba de máquinas virtuales, y necesitábamos entender dónde estaba el problema: en los SSD físicos o en la capa de virtualización. Además, a menudo hacíamos cambios en la configuración de hardware y software, y necesitábamos una forma de evaluar sus resultados. Podíamos ejecutar etcd en cada configuración y observar las métricas de Prometheus, pero eso era demasiado engorroso. Buscábamos una forma lo suficientemente simple de evaluar una configuración específica. Queríamos comprobar si entendíamos correctamente las métricas de Prometheus de etcd.

Pero para esto había que resolver dos problemas. Primero, ¿cuál es la carga de entrada-salida que crea etcd al escribir en el WAL? ¿Qué llamadas al sistema se utilizan? ¿Cuál es el tamaño de los registros? En segundo lugar, si respondemos a estas preguntas, ¿cómo reproducir una carga de trabajo similar con fio? No olvides que fio es una herramienta muy flexible con muchos parámetros. Resolvíamos ambos problemas con un solo enfoque: mediante comandos. lsof y strace. lsof muestra todos los descriptores de archivos utilizados por un proceso y los archivos asociados. Con strace se puede estudiar un proceso ya en ejecución o iniciar un proceso y analizarlo. strace presenta todas las llamadas al sistema del proceso que se está estudiando (y de sus procesos secundarios). Esto es especialmente importante, ya que etcd utiliza precisamente este enfoque.

Primero utilizamos strace para estudiar el servidor etcd para Kubernetes, cuando el clúster no tenía carga. Vimos que casi todos los registros del WAL eran de tamaño similar: entre 2200 y 2400 bytes. Por lo tanto, en el comando al principio de la publicación especificamos el parámetro —bs=2300 (bs significa tamaño en bytes para cada registro de fio). Ten en cuenta que el tamaño de registro de etcd depende de la versión de etcd, la distribución, los valores de los parámetros, etc., y afecta la duración de fdatasync. Si tienes un escenario similar, estudia tus procesos de etcd con strace para conocer las cifras exactas.

Luego, para tener una buena representación de las acciones en el sistema de archivos de etcd, la ejecutamos con strace y con los parámetros -ffttT. Así intentamos estudiar los procesos secundarios y grabar la salida de cada uno en un archivo separado, además de obtener informes detallados sobre el inicio y la duración de cada llamada al sistema. Utilizamos lsof para confirmar nuestro análisis de la salida de strace y ver qué descriptor de archivo se utilizó para qué propósito. Así, con strace obtuvimos los resultados que se muestran arriba. Las estadísticas sobre el tiempo de sincronización confirmaron que el indicador wal_fsync_duration_seconds de etcd corresponde a las llamadas fdatasync con los descriptores de archivo del WAL.

Estudiamos la documentación de fio y seleccionamos los parámetros para nuestro escenario, para que fio generara una carga de trabajo similar a la de etcd. También verficamos las llamadas al sistema y su duración, ejecutando fio a través de strace, de manera similar a etcd.

Seleccionamos cuidadosamente el significado del parámetro —size, que representa toda la carga de entrada/salida de fio. En nuestro caso, esto es el número total de bytes escritos en el almacenamiento. Resultó ser directamente proporcional a la cantidad de llamadas al sistema write (y fdatasync). Para un valor determinado de bs, la cantidad de llamadas a fdatasync = size/bs. Como nos interesaba el percentil, necesitábamos suficientes muestras para la validez, y calculamos que 10^4 (22 mebibytes) serían suficientes. Si —size es menor, pueden ocurrir desechos (por ejemplo, algunas llamadas a fdatasync tardan más de lo habitual y afectan al percentil 99).

Inténtalo tú mismo

Mostramos cómo usar fio y determinar si el almacenamiento tiene la velocidad suficiente para un alto rendimiento de etcd. Ahora puedes probarlo tú mismo en la práctica, utilizando, por ejemplo, máquinas virtuales con almacenamiento SSD en IBM Cloud.

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster