Soy completamente nuevo en ZFS, así que, para empezar, pensé en hacer algunos puntos de referencia simples para tener una idea de cómo se comporta. Quería superar los límites de su rendimiento, así que aprovisioné una i2.8xlarge
instancia de Amazon EC2 (casi $ 7 / hora, ¡el tiempo realmente es dinero!). Esta instancia tiene 8 SSD de 800 GB.
Hice una fio
prueba en los SSD y obtuve el siguiente resultado (recortado):
$ sudo fio --name randwrite --ioengine=libaio --iodepth=2 --rw=randwrite --bs=4k --size=400G --numjobs=8 --runtime=300 --group_reporting --direct=1 --filename=/dev/xvdb
[trimmed]
write: io=67178MB, bw=229299KB/s, iops=57324, runt=300004msec
[trimmed]
57K IOPS para escrituras aleatorias 4K. Respetable.
Luego creé un volumen ZFS que abarcaba los 8. Al principio tenía un raidz1
vdev con los 8 SSD, pero leí sobre las razones por las que esto es malo para el rendimiento, así que terminé con cuatro mirror
vdevs, así:
$ sudo zpool create testpool mirror xvdb xvdc mirror xvdd xvde mirror xvdf xvdg mirror xvdh xvdi
$ sudo zpool list -v
NAME SIZE ALLOC FREE EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
testpool 2.91T 284K 2.91T - 0% 0% 1.00x ONLINE -
mirror 744G 112K 744G - 0% 0%
xvdb - - - - - -
xvdc - - - - - -
mirror 744G 60K 744G - 0% 0%
xvdd - - - - - -
xvde - - - - - -
mirror 744G 0 744G - 0% 0%
xvdf - - - - - -
xvdg - - - - - -
mirror 744G 112K 744G - 0% 0%
xvdh - - - - - -
xvdi - - - - - -
Configuré el tamaño de registro en 4K y ejecuté mi prueba:
$ sudo zfs set recordsize=4k testpool
$ sudo fio --name randwrite --ioengine=libaio --iodepth=2 --rw=randwrite --bs=4k --size=400G --numjobs=8 --runtime=300 --group_reporting --filename=/testpool/testfile --fallocate=none
[trimmed]
write: io=61500MB, bw=209919KB/s, iops=52479, runt=300001msec
slat (usec): min=13, max=155081, avg=145.24, stdev=901.21
clat (usec): min=3, max=155089, avg=154.37, stdev=930.54
lat (usec): min=35, max=155149, avg=300.91, stdev=1333.81
[trimmed]
Solo obtengo 52K IOPS en este grupo de ZFS. Eso es en realidad un poco peor que un SSD en sí.
No entiendo lo que estoy haciendo mal aquí. ¿He configurado ZFS incorrectamente o es una mala prueba del rendimiento de ZFS?
Tenga en cuenta que estoy usando la imagen oficial de CentOS 7 HVM de 64 bits, aunque he actualizado al kernel 4.4.5 elrepo:
$ uname -a
Linux ip-172-31-43-196.ec2.internal 4.4.5-1.el7.elrepo.x86_64 #1 SMP Thu Mar 10 11:45:51 EST 2016 x86_64 x86_64 x86_64 GNU/Linux
Instalé ZFS desde el repositorio de zfs enumerado aquí . Tengo la versión 0.6.5.5 del zfs
paquete.
ACTUALIZACIÓN : Por sugerencia de @ ewwhite probé ashift=12
y ashift=13
:
$ sudo zpool create testpool mirror xvdb xvdc mirror xvdd xvde mirror xvdf xvdg mirror xvdh xvdi -o ashift=12 -f
y
$ sudo zpool create testpool mirror xvdb xvdc mirror xvdd xvde mirror xvdf xvdg mirror xvdh xvdi -o ashift=13 -f
Ninguno de estos hizo ninguna diferencia. Por lo que entiendo, los últimos bits ZFS son lo suficientemente inteligentes como para identificar SSD 4K y usar valores predeterminados razonables.
Sin embargo, noté que el uso de la CPU está aumentando. @Tim sugirió esto, pero lo descarté, sin embargo, creo que no estaba mirando la CPU el tiempo suficiente para notarlo. Hay algo así como 30 núcleos de CPU en esta instancia, y el uso de CPU está aumentando hasta un 80%. El proceso de hambre? z_wr_iss
, muchas instancias de ello.
Confirmé que la compresión está desactivada, por lo que no es el motor de compresión.
No estoy usando raidz, por lo que no debería ser el cálculo de paridad.
Hice un perf top
y muestra la mayor parte del tiempo del kernel que pasé _raw_spin_unlock_irqrestore
adentro z_wr_int_4
y osq_lock
adentro z_wr_iss
.
Ahora creo que hay un componente de CPU en este cuello de botella de rendimiento, aunque no estoy más cerca de descubrir cuál podría ser.
ACTUALIZACIÓN 2 : Según la sugerencia de @ewwhite y otros de que es la naturaleza virtualizada de este entorno lo que crea incertidumbre sobre el rendimiento, solía fio
comparar las escrituras aleatorias 4K repartidas en cuatro de los SSD del entorno. Cada SSD por sí solo da ~ 55K IOPS, por lo que esperaba alrededor de 240K IOs en cuatro de ellos. Eso es más o menos lo que obtuve:
$ sudo fio --name randwrite --ioengine=libaio --iodepth=8 --rw=randwrite --bs=4k --size=398G --numjobs=8 --runtime=300 --group_reporting --filename=/dev/xvdb:/dev/xvdc:/dev/xvdd:/dev/xvde
randwrite: (g=0): rw=randwrite, bs=4K-4K/4K-4K/4K-4K, ioengine=libaio, iodepth=8
...
randwrite: (g=0): rw=randwrite, bs=4K-4K/4K-4K/4K-4K, ioengine=libaio, iodepth=8
fio-2.1.5
Starting 8 processes
[trimmed]
write: io=288550MB, bw=984860KB/s, iops=246215, runt=300017msec
slat (usec): min=1, max=24609, avg=30.27, stdev=566.55
clat (usec): min=3, max=2443.8K, avg=227.05, stdev=1834.40
lat (usec): min=27, max=2443.8K, avg=257.62, stdev=1917.54
[trimmed]
Esto muestra claramente que el entorno, por virtualizado que sea, puede mantener los IOPS mucho más altos de lo que estoy viendo. Algo sobre la forma en que se implementa ZFS es evitar que alcance la velocidad máxima. Simplemente no puedo entender qué es eso.
fuente
Respuestas:
Es posible que esta configuración no esté bien ajustada. Hay parámetros necesarios tanto para el archivo /etc/modprobe/zfs.conf como para el valor ashift cuando se usan SSD
Pruebe ashift = 12 o 13 y pruebe nuevamente.
Editar:
Esta sigue siendo una solución virtualizada, por lo que no sabemos demasiado sobre el hardware subyacente o cómo todo está interconectado. No sé si obtendrás un mejor rendimiento de esta solución.
Editar:
Supongo que no veo el punto de tratar de optimizar una instancia de la nube de esta manera. Porque si el máximo rendimiento fuera el objetivo, estarías usando hardware, ¿verdad?
Pero recuerda que ZFS tiene mucho configuraciones ajustables, y lo que obtiene de forma predeterminada no está cerca de su caso de uso.
Pruebe lo siguiente en su
/etc/modprobe.d/zfs.conf
y reinicie. Es lo que uso en mis agrupaciones de datos SSD para servidores de aplicaciones. Su cambio de ceniza debe ser 12 o 13. Punto de referencia con compresión = desactivado, pero use compresión = lz4 en producción. Establecer atime = off. Dejaría el tamaño de registro predeterminado (128K).fuente
zfs get compression
. Dedupe también está apagado.Parece probable que esté esperando un bloqueo mutex del kernel de Linux que a su vez puede estar esperando un búfer de anillo Xen. No puedo estar seguro de esto sin tener acceso a una máquina similar, pero no estoy interesado en pagarle a Amazon $ 7 / hora por ese privilegio.
Una descripción más larga está aquí: https://www.reddit.com/r/zfs/comments/4b4r1y/why_is_zfs_on_linux_unable_to_fully_utilize_8x/d1e91wo ; Prefiero que sea en un lugar que en dos.
fuente
He pasado una cantidad de tiempo decente tratando de rastrear esto. Mi desafío específico: un servidor Postgres y quiero usar ZFS para su volumen de datos. La línea de base es XFS.
En primer lugar, mis pruebas me dicen que eso
ashift=12
está mal. Si hay algúnashift
número mágico , no es 12. Estoy usando0
y obtengo muy buenos resultados.También he experimentado con un montón de opciones zfs y las que me dan los siguientes resultados son:
atime=off
- No necesito tiempos de accesochecksum=off
- Me estoy desnudando, no reflejandocompression=lz4
- El rendimiento es mejor con la compresión (¿compensación de CPU?)exec=off
- Esto es para datos, no ejecutableslogbias=throughput
- Lea en las páginas web esto es mejor para Postgresrecordsize=8k
- Tamaño de bloque 8k específico de PGsync=standard
- trató de desactivar la sincronización; no vi mucho beneficioMis pruebas a continuación muestran un rendimiento mejor que XFS (¡comente si ve errores en mis pruebas!).
Con esto, mi próximo paso es probar Postgres ejecutándose en un sistema de archivos 2 x EBS ZFS.
Mi configuración específica:
EC2:
m4.xlarge
instanciaEBS: 250 GB
gp2
volúmenes dekernel: Linux [...] 3.13.0-105-generic # 152-Ubuntu SMP [...] x86_64 x86_64 x86_64 GNU / Linux *
Primero, quería probar el rendimiento bruto de EBS. Usando una variación del
fio
comando anterior, se me ocurrió el encantamiento a continuación. Nota: Estoy usando bloques de 8k porque eso es lo que he leído que las escrituras de PostgreSQL son:El rendimiento bruto para el volumen EBS es
WRITE: io=3192.2MB
.Ahora, probando XFS con el mismo
fio
comando:Nuestra línea de base es
WRITE: io=3181.9MB
; muy cerca de la velocidad del disco sin formato.Ahora, en ZFS con
WRITE: io=3181.9MB
como referencia:Tenga en cuenta que esto funcionó mejor que XFS
WRITE: io=4191.7MB
. Estoy bastante seguro de que esto se debe a la compresión.Para las patadas, voy a agregar un segundo volumen:
Con un segundo volumen,
WRITE: io=5975.9MB
entonces ~ 1.8X las escrituras.Un tercer volumen nos da
WRITE: io=6667.5MB
, entonces ~ 2.1X las escrituras.Y nos da un cuarto volumen
WRITE: io=6552.9MB
. Para este tipo de instancia, parece que casi limito la red EBS con dos volúmenes, definitivamente con tres y no es mejor con 4 (750 * 3 = 2250 IOPS).* De este video, asegúrese de estar utilizando el núcleo de Linux 3.8+ para obtener toda la bondad de EBS.
fuente
WRITE: io=
; esa no es la velocidad, es la cantidad de datos escritos en ese momento. Relacionado con la velocidad sólo para pruebas de que tienen un tiempo de ejecución fija, pero por coherencia con otros puntos de referencia que es mejor centrarse en IOPS,iops=
. En su caso, los resultados son similares. Probablemente podría mejorar mucho si utiliza volúmenes IOPS EBS aprovisionados y una instancia más grande. Consulte esta página para ver los límites de EBS esperados por tamaño de instancia. ¡Solo tenga cuidado, los cargos de EBS se suman rápidamente si no tiene cuidado!/etc/modules.d/zfs.conf
. La siguiente pregunta sería cuál es el número apropiado de iops para una instancia de dar ec2. Mirando la página a la que hace referencia todavía es complicado, y no veo un rendimiento tan bueno como lo dicen los documentos.