Ok, en un muy mal servidor que mantiene una base de datos que por alguna razón estaba haciendo un uso intenso de la memoria swap y el IO WAIT iba por las nubes y existe una marcada lentitud en el sistema
y ese es el escenario al que me enfrenté, como en su momento (y aun hasta hoy) no se mucho de mysql pero si conocía la tecnología de zram que básicamente monta un espacio swap en un espacio reservado de la memoria ram, lo que aumenta significativamente la velocidad de acceso a esa data disminuyendo el IO WAIT y mejorando el rendimiento (y bastante, al menos en ese servidor y dependiendo de cuanto utilicen la memoria swap)
Algunas consideraciones en este caso:
- El servidor cuenta con 32Gb de ram de las cuales usa 15G (zram incluido)
- utiliza LXC con varios contenedores prestando distintos servicios
- si, uno de esos contenedores es la base de datos
- cuenta con un procesador E5-2630 v4 @ 2.20GHz de 10 core y 20 hilos
- el promedio diario de IOWAIT del servidor era de entre 22% al 30%
con este escenario me encontraba por lo que decidí montar una cantidad significativa de ZRAM para notar efectivamente un cambio real
Aunque también existe la opción de Zswap que tiene un funcionamiento similar a ZRAM sin embargo me decante por la segunda opción meramente por que fue la primera que recordé
Manos a la masa
Zram esta por defecto desde el kernel 3.15 por lo que si tenemos una versión superior no habrá que instalar nada, en caso de tener una versión anterior hay que instalarlo mediante <>
lo primero que debemos hacer es invocar el modulo para que cargue en el kernel
modprobe zram
Si queremos crear mas de un bloque Zram agregamos la opción num_devices=<numero> esto puede ser útil para administrar la compresión de cada bloque haciendo que los primeros bloques que se utilicen no tengan compresión e ir aumentando la compresión a medida que se van llenando los bloques, en mi caso decidí colocar 20 bloques distintos ya que quería conocer que tanto se usaba la zwap (algo ridículo que pensé después)
modprobe zram num_devices=20
Luego de cargado el modulo hay que crear los bloques y lo primero que configuraremos será el tamaño de cada uno de ellos y para eso debemos crear el archivo sys/block/zramX/disksize donde X sera el numero de modulo y dentro colocamos el espacio que tendrá el bloque, en mi caso usare bloques de 1Gb
echo $((1024*1024*1024)) > /sys/block/zram0/disksize
Desconozco por que se utiliza el método anterior pero lo veo muy seguido, sin embargo tenemos otra forma de definir el tamaño del bloque con formato mas entendible
echo 1G > /sys/block/zram0/disksize
En mi caso como cree 20 bloques distintos hice uso de un pequeño ciclo for para definir este valor por cada bloque
for i in $(ls /sys/block/ | grep zram ) do echo $((1024*1024*1024)) > /sys/block/$i/disksize done
ya con esto tenemos agregado nuestro bloque ahora solo falta darle el formato correcto
mkswap /dev/zramX
aquí tenemos un pequeño detalle ya que esta técnica no solo sirve para la swap
mkfs.ext4 /dev/zramX
ya con el formato procedemos a montar los bloques
swapon /dev/zramX mount /dev/zramX /tmp
En mi caso deje un script final para hacer todo este trabajo con el ciclo for que les mostré hace unas lineas atrás
for i in $(ls /sys/block/ | grep zram ) do echo $((1024*1024*1024)) > /sys/block/$i/disksize && mkswap /dev/$i && swapon -p 50 /dev/$i done
por si se lo preguntan el «-p» en el comando swapon indica la prioridad que tendrá el bloque mientras mayor sea mas se utilizará y por defecto viene con una prioridad de -1 por lo que al darle prioridad de 50 primero se utilizaran estos bloques y luego la swap «normal», este valor de prioridad puede ir desde el -1 al 32767
Ya con esto tenemos nuestra swap mejorada (o directorio cof cof) con la velocidad de la RAM.
Importante mencionar que esta técnica solo aplica a runtime por lo que al reiniciar el equipo debemos nuevamente aplicar la configuración, lo cual podemos dejar por medio de un script al inicio del sistema
Fuentes: