2. Información importante
● Hay dulces
● Siempre se puede hacer mejor en un green
field proyect
● Ahorremos la pregunta de por que no fui a la
Prometheus School of Running Away From
Things *
● Suelo usar metáforas no actas para todo
público ^_^
* https://www.youtube.com/watch?v=-BWnTW4rL0U (spoilers alert)
3. Contexto
● Un sistema que permita consultar las gráficas de
valores para multitud de dispositivos, suena a
IoT pero no te dejes llevar por el hype
● RabbitMQ es un broker de mensajes. Uno de los
usos que tiene es desacoplar productores y
consumidores *
● Graphite es un sistema para almacenar y
mostrar gráficas separado en multiples
componentes
* http://www.eferro.net/2017/09/pub-sub-swiss-army-knife-tech-pill.html
6. Cambiar el io scheduler
a CFQ
The main aim of CFQ scheduler is to provide a fair allocation of the disk
I/O bandwidth for all the processes which requests an I/O operation.
CFQ maintains the per process queue for the processes which request I/O
operation(synchronous requests). In case of asynchronous requests, all the
requests from all the processes are batched together according to their
process's I/O priority.
https://www.kernel.org/doc/Documentation/block/cfq-iosched.txt
https://www.kernel.org/doc/Documentation/block/ioprio.txt - bola extra
vs I
13. vs IV
# Limits the number of whisper update_many() calls per second, which effectively
# means the number of write requests sent to the disk. This is intended to
# prevent over-utilizing the disk and thus starving the rest of the system.
# When the rate of required updates exceeds this, then carbon's caching will
# take effect and increase the overall throughput accordingly.
# MAX_UPDATES_PER_SECOND = 500
Comentar el sistema de procesos que recopilan metricas de dispositivos y las publican a rabbitmq para ser consumidas por graphite.
Si hacen menciones a kafka, comentar que kafka requiere que los consumers lleven el tracking de donde estan. https://content.pivotal.io/blog/understanding-when-to-use-rabbitmq-or-apache-kafka
Diagrama de como estaba originalmente
Hacer ssh en el servidor de métricas para disfrutar de tiempos de respuesta que hacen llorar. Problemas de tener todo en los mismos discos físicos, cuando hay mucho IO lo mejor es tener discos dedicados, sino te comes el atasco.
Razono en que el problema es el ciclo salvaje de lectura escritura que esta haciendo graphite, el cual es tan frecuente que deja al resto en inanición. Por lo que decido probar cambiando el planificador para tener canales disponibles para otros procesos. Ademas si la cosa se ponia fea se podia usar ionice.
Parece que hay otros nuevos planificadores en el kernel que valdra la pena probar.
https://lwn.net/Articles/720675/
Se migro graphite de maquina y de una vez se aprovecho y se puso en docker para ser lo suficientemente hipster (en realidad era para aprovechar y que próximas instalaciones del graphite fueran reproducibles). Lo curioso es que en el riemann se empezó a ver que habían tiempos de respuesta altos y errores en el NGINX que lo dejaban KO
Viendo los logs y recordando lo que había leído en un post de netflix, el libro de SRE sobre los fallos en cascada y después de hacer pruebas de carga con ab decidí usando la fuerza que si una gráfica tardaba más de 5 segundos nginx cancelara la operación. Como bien pone Dan Luu hay que poner deadlines para evitar zombie requests
https://danluu.com/google-sre-book/
Antes de hacer la migración (otra vez) de los servidores, decido hacer pruebas de carga en AWS. Es el momento mágico donde descubres que graphite leyendo metricas desde AMQP es una basura, llegando a tope de CPU antes de saturar los discos.
Al final para seguir haciendo pruebas tuve que empezar a usar los carbon-relay y editarles el código para que usaran la misma named queue.
Diagrama de como quedo
Revisando de nuevo los logs de nginx vi que muchas peticiones de gráficas no se cargaban porque tardan más de 5 segundos.
Al final después de un poco de syscall tracing veo que al estar el disco tan petado escribiendo a disco (si, en un disco dedicado) las lecturas no se podían atender, además de la motorización tenemos a gente con ventanitas abiertas para ver las gráficas como si fuera un NOC. Así que me puse a ver los updates por second, saque estadísticas de cual era el promedio / media para posteriormente bajar en la configuración del graphite este valor al 70% y así dar espacio para las lecturas. Quizás había que tocar queue depth y esas cosillas =)
Diagrama de como quedo
Tenia reciente la charla de @adrianco sobre chaos engineering y aprovechando que tenemos el graphite y broker duplicados, me sentía con ganas de ver si la configuración que teníamos puesta aguantaría de verdad un evento tan tonto como una actualización (si, había que hacer una actualización).
Uno de los datos que tenia que validar, es que el carbon-cache iba a tardar aproximadamente 5 horas y 30 minutos en terminar de manera limpia. Por lo que detenemos los relays y el cache. Esto causa que el broker acumule mensajes hasta que boom, se pierde la conexión a ambas máquinas y conectandome al hypervisor veo que el OOM Killer se cargo los procesos KVM.
Tan simple como reconfigurar el uso de memoria de las 2 máquinas virtuales para que no exploten si usan toda la memoria asignada.
Había ahora que actualizar la otra instancia, así que era una buena oportunidad para probar de nuevo el proceso de shutdown y restore. En este caso el shutdown no dio problemas, más alla del RabbitMQ al usar toda la memoria, dejó de recibir mensajes de los shovels.
La gracia fue restaurando el servicio. La cola estaba llena de mensajes y se leían muy lentamente. Pensaba que eran los relays, asi que ejecute aun más relays y la cosa no se arreglaba. Al final me di cuenta que el rabbitMQ estaba a tope de disco. Parece que le problema era que los mensajes a enviar no estaban en cache y tenían que leerse de disco mientras se seguía recibiendo una avalancha de mensajes.
Al final para mejorar la velocidad utilice una estrategia doble, por un lado vmtouch https://hoytech.com/vmtouch/
Para tener en cache los ficheros del mnesia y por otro lado bloquear el trafico de entrada al broker e aceptarlo poco a poco con iptables y el modulo de statistics, aprovechando que TCP baja la velocidad si se pierden muchos paquetes =)