2. Advertencia
No son historias épicas
Puedo ofender con mis comentarios subjetivos
y sesgados
Espero que tenga una duración razonable
3. About me
Fan del trolleo (a veces en exceso)
Me agota el uso de etiquetas fancy en la
industria
A veces me llaman Mr. Wolf
Twitter → @ae_bm (cuidado!)
You know my name (no es tan difícil)
5. JVM on Elm Street
Erase una vez un sistema critico para los
clientes que “va mal” …
6. JVM on Elm Street
Cola de procesos en estado running 6
Proceso java 100% CPU y 50% Mem
Máquina virtual con 1 CPU y 1GB RAM + 2 GB
swap
SIGTERM al java (un supervisor lo inicia)
¿Estaba a tope la memoria la JVM o haciendo
GC o quién sabe?
7. JVM on Elm Street
JVM configurado para usar 64M-512M
¿Qué hilos estaban pendientes de ejecución?
No hay rastros del desastre A.K.A OOM Killer
Ahora está funcionando
13. JVM on Elm Street
Algunos eventos importantes en 2013
- Año de la quinua según la FAO
- Año de la serpiente
- Año de la Fe
- Renuncia Benedicto XVI
- Muerte de Paul Walker
- Nacimiento del Príncipe Jorge de Cambridge
- Cumplí años (business as usual, por ahora )
- Etc
15. JVM on Elm Street
Intentando ejecutarlo en foreground muestra un
out of memory exception
Hay recursos en la máquina anfitrión
Power up a 4GB RAM y 4 CPUS
JVM hasta 1024M (2X)
16. JVM on Elm Street
Sigue sin servir y con 100% uso de CPU
Con ps eLo comm podre ver el nombre de
los threads de la JVM
Todos se llaman Java
¿Por que la JVM no registra los nombres de los
threads?
java version "1.6.0_16"
18. JVM on Elm Street
Después de un largo rato usando 100% de
CPU aparece el mágico Out of memory
Creo que el GC desesperado tratando de hacer
espacio
Subir el uso de memoria de la JVM a 2048M
19. JVM on Elm Street
Ya funciona
¿Qué paso para necesitar un crecimiento de
4X en recursos?
¿Continuara ...?
21. La gráfica queso suizo
Hay varios huecos en una gráfica de cacti ...
22. La gráfica queso suizo
Otra maravillosa integración con un sistema
legacy
Perdón por no incluir la gráfica
Hay logs que se quejan de un timeout de snmp
Cacti consulta una OID a snmpd
snmpd delega la gestión de la OID a un script
python
23. La gráfica queso suizo
Usando sysdig
- Cuesta filtrar por el contenido de los buffers
de red – Gracias ASN.1 (BER, DER, etc)
- Buscando en los buffers del script se ven los
dos tipos de mensajes que le envía snmpd
- No parecen problemas de permisos
24. La gráfica queso suizo
Usando sysdig
- Lee el mismo fichero de configuración más
de 1000 veces
- Lee otro fichero varias veces
25. La gráfica queso suizo
Edito el script y con un log estratégico para
saber cuanto tarda (si, son segundos)
27. La gráfica queso suizo
El mínimo es de risa 18s
El Máximo es para morir - 33 min
Que el percentil 58 sean 30s. Es decir el 42%
de las ejecuciones tardaron más de 30 seg
29. La gráfica queso suizo
Durante las ejecuciones el script usaba 100%
CPU en modo usuario
¿Usar Flame graphs? NOPE
Python 2.7.3 y no puedo instalar cosas
Después de varias sesiones de PDB y muchos
prints en funciones
30. La gráfica queso suizo
En la función del MAL
- Hay un while que procesa cada entrada de un
fichero
- Cada iteración se hace en mucho menos de
1s, pero acumulando, terminamos en 16 seg
promedio
- Ya sumando pasamos los 20 seg
31. La gráfica queso suizo
En la función del MAL
- El creador del código ya intuía que esta
función era lenta, así que tenia un cache con
un TTL de 20s
- Pero al crecer la cantidad de datos a
procesar...
32. La gráfica queso suizo
Solución (temporal) aumentar el TTL del cache
a 300s
Por lo menos se redujo la variabilidad en el
tiempo de ejecución
Ese mismo día me dicen que deje de dedicarle
a esto, que al final van a cambiar todo este
sistema legacy
35. Toysql y el delete bloqueante
Erase una BD (critica) con una tabla (MyISAM)
con millones de registros innecesarios ...
36. Toysql y el delete bloqueante
Es un problema sencillo
Sólo hay que hacer n veces
DELETE FROM table WHERE date < d LIMIT r
Si r es muy pequeño, habrá que repetir muchas veces
Si r es muy grande, se bloquean los inserts durante
mucho tiempo (Muy malo)
Bonus: La carga del sistema es variable
37. Toysql y el delete bloqueante
El plan
- Probar con una bd dummy
- Probar con un dump de la bd
- Pensar estrategias para elegir el valor de r
38. Toysql y el delete bloqueante
Con la bd dummy
r time (seconds)
1 0.00
10 0.00
100 0.02
1000 0.01
10000 0.05
100000 0.53
1000000 5.23
10000000 50.37
100000000 636.98
39. Toysql y el delete bloqueante
No tiene pinta de tener un crecimiento lineal
¿Será exponencial?
Haciendo un semi-log plot (no sabia que se
llamaba así)
40. Toysql y el delete bloqueante
Con la bd dummy (semi-log plot)
r ln(time)
1
10
100 -3.9120
1000 -4.6052
10000 -2.9957
100000 -0.6349
1000000 1.6544
10000000 3.9194
100000000 6.4567
41. Toysql y el delete bloqueante
Ya esto es más digerible
Luce como una recta
Parece que existe una relación exponencial el
numero de rows y el tiempo que tarda en
eliminarlas
Ahora toca ver como se comporta con datos de
verdad
42. Toysql y el delete bloqueante
Con la bd y datos reales
r time (seconds)
100 0.04
1000 0.05
10000 0.51
100000 4.44
1000000 38.41
43. Toysql y el delete bloqueante
Con la bd y datos reales (semi-log plot)
r time (seconds)
100 -3.2189
1000 -2.9957
10000 -0.6733
100000 1.4907
1000000 3.6483
44. Toysql y el delete bloqueante
Por si quereis entender lo que hace el semi-log
plot
46. Toysql y el delete bloqueante
Ya con una idea de como parece que se
comporta, vienen a la cabeza varias estrategias
(naive)
- Hacer un programa que vaya iterando haciendo
la query incrementando o decrementando en un
factor k el número de rows hasta llegar a la
latencia deseada
- Hemos pasado el problema de r a elegir el valor
de los incrementos k
47. Toysql y el delete bloqueante
Otra estrategia
- Usar el método de la bisectriz para hallar el
valor de r
- El problema es elegir el valor máximo de r a
intentar que no bloquee mucho la bd
- Recordar que la carga varia en el tiempo
48. Toysql y el delete bloqueante
Método de la bisectriz
49. Toysql y el delete bloqueante
Empezando la exquisitez
- En un momento llegue a pensar en ver si
podía apañar algo con el método de Newton–
Raphson
- No uso drogas BTW, pero tampoco estoy
contra su uso
50. Toysql y el delete bloqueante
No preguntéis
- Al final en un momento de extraño, decidí
darle vueltas al modelo a ver que sacaba
- Si, no revise la wikipedia
- Ya no recuerdo mucho como hice todo esto,
culpo a las vacaciones en Bulgaria y al rakia
51. Toysql y el delete bloqueante
#math #instamath #log #exp #secuence
55. Toysql y el delete bloqueante
Si, es un poco ...
56. Toysql y el delete bloqueante
Ya no pongo más matemática
57. Toysql y el delete bloqueante
Traduciendo del griego a español
- Con al menos dos ejecuciones de la query
con valores distintos de r
- Puedo calcular un valor para rows r + m que
estará justo en la latencia objetivo o por debajo
58. Toysql y el delete bloqueante
Llevando esto a un programa (fancy)
- Empezamos con r = 1
- Ya con al menos 2 iteraciones (con r distintos) se
calcula el valor de m para tener un r + m
- Repetir esto hasta borrar todo lo que hay que
borrar, en cuyo caso hacemos r = 1 hasta que se
acumulen registros suficientes para usar el algoritmo
de nuevo
59. Toysql y el delete bloqueante
Comparando el algoritmo naive y el fancy
250ms y sleep de 3s
Naive Iter Fancy iter % Iters
536 353 65.86
537 353 65.74
534 355 66.48
537 352 65.55
533 354 66.42
Naive Máx r Fancy Máx r
4540 5013
4630 4386
4550 4852
4520 8799
4590 4766
60. Toysql y el delete bloqueante
Comparando el algoritmo naive y el fancy
250ms y sleep de 3s
Naive fail r Fancy fail r Naive fail lat Fancy fail lat
4220 4826 0.49 0.6
3400 4238 0.64 1.02
780 4508 0.53 0.67
1790 4813 0.55 0.66
600 4636 0.87 0.58
61. Toysql y el delete bloqueante
Comparando el algoritmo naive y el fancy
250ms y sleep de 3s
Naive fails Fancy fails Naive fail % Fancy fail %
40 114 7.46 32.29
36 105 6.70 29.75
40 85 7.49 23.94
42 107 7.82 30.40
36 98 6.75 27.68
62. Toysql y el delete bloqueante
¿Cual debería utilizar?
Pendiente de ponerse en el sistema crítico de
algún afortunado ^_^