Si estas apuntado a la lista perf-discuss@opensolaris.org, habrás podido ver el revuelo que se ha generado durante esta semana debido a un posible problema de fuga de memoria en el Kernel de Solaris 10, todo ha sido un mal entendido, debido a que ZFS utiliza la cache ARC (Adaptive replacement cache). El este tipo de algoritmo de remplazo de cache mejora al clásico LRU (Least Recently Used), ZFS hace uso de la cache ARC para mejorar el rendimiento en el acceso a los datos de los distintos pools. La implementación de ARC en Solaris utiliza memoria del Kernel, esto puede llevarnos a una confusión, haciendonos creer que se está produciendo una fuga de memoria en el propio Kernel.
Vamos a ver un ejemplo lo que podríamos pensar que es una posible fuga de memoria en el Kernel y en realidad es la cache ARC la causante de la disminución de memoria disponible.
La forma mas fiable para comprobar como se está distribuyendo la memoria disponible en el sistema es mediante el comando mdb
root@jcbbdd01 # mdb -k Loading modules: [ unix krtld genunix specfs dtrace ufs sd mpt px md ip hook neti sctp arp usba nca fcp fctl emlxs zfs random cpc crypto wrsmd fcip logindmux ptm sppp ssd nfs ipc ] > ::memstat Page Summary Pages MB %Tot ------------ ---------------- ---------------- ---- Kernel 5053783 39482 60% Anon 1910637 14926 23% Exec and libs 58413 456 1% Page cache 747613 5840 9% Free (cachelist) 208281 1627 2% Free (freelist) 387545 3027 5% Total 8366272 65361 Physical 8212093 64156 >
Como podemos ver en el ejemplo, la memoria asignada al kernel es de 39.482 MB, una cantidad desorbitada en cualquier sistema y que nos puede dar una pista de un posible problema.
En nuestro sistema disponemos de varios volúmenes sobre ZFS, por lo que tenemos que chequear cuanta memoria está asignada a la cache ARC. Tenemos dos métodos para comprobar el tamaño de la cache ARC, utilizando el comando kstat o mdb:
root@host # kstat -p -m zfs zfs:0:arcstats:c 39171097690 zfs:0:arcstats:c_max 67462758400 zfs:0:arcstats:c_min 2141765632 zfs:0:arcstats:class misc zfs:0:arcstats:crtime 212.9728799 zfs:0:arcstats:deleted 54282702 zfs:0:arcstats:demand_data_hits 68060012 zfs:0:arcstats:demand_data_misses 217960 zfs:0:arcstats:demand_metadata_hits 37076627 zfs:0:arcstats:demand_metadata_misses 536492 zfs:0:arcstats:evict_skip 210031332 zfs:0:arcstats:hash_chain_max 8 zfs:0:arcstats:hash_chains 110169 zfs:0:arcstats:hash_collisions 23936495 zfs:0:arcstats:hash_elements 588890 zfs:0:arcstats:hash_elements_max 720117 zfs:0:arcstats:hits 123214999 zfs:0:arcstats:mfu_ghost_hits 6948998 zfs:0:arcstats:mfu_hits 46395981 zfs:0:arcstats:misses 37960320 zfs:0:arcstats:mru_ghost_hits 3436988 zfs:0:arcstats:mru_hits 62073376 zfs:0:arcstats:mutex_miss 109046 zfs:0:arcstats:p 38836574364 zfs:0:arcstats:prefetch_data_hits 18076239 zfs:0:arcstats:prefetch_data_misses 37205541 zfs:0:arcstats:prefetch_metadata_hits 2121 zfs:0:arcstats:prefetch_metadata_misses 327 zfs:0:arcstats:recycle_miss 2641956 zfs:0:arcstats:size 38507655680 zfs:0:arcstats:snaptime 10385718.5036351
Podemos comprobar en la salida del comando kstat, en la línea que hemos marcado con negrita, que el tamaño de la cache ARC es de 36.723 MB.
Otra forma de chequear el tamaño de la cache ARC es utilizando mdb.
root@host# mdb -k
Loading modules: [ unix krtld genunix specfs dtrace ufs sd mpt px md ip hook neti sctp arp usba nca
fcp fctl emlxs zfs random cpc crypto wrsmd fcip logindmux ptm sppp ssd nfs ipc ]
> ::arc
{
anon = ARC_anon
mru = ARC_mru
mru_ghost = ARC_mru_ghost
mfu = ARC_mfu
mfu_ghost = ARC_mfu_ghost
size = 0×8f73c3200
p = 0×90ad7189c
c = 0×91ec7845a
c_min = 0×7fa8c000
c_max = 0xfb5180000
hits = 0×7581c97
misses = 0×2433a80
deleted = 0×33c49ce
recycle_miss = 0×285024
mutex_miss = 0×1a9f6
evict_skip = 0xc84d2e4
hash_elements = 0×8fc5a
hash_elements_max = 0xafcf5
hash_collisions = 0×16d3def
hash_chains = 0×1ae59
hash_chain_max = 0×8
no_grow = 0
}
>
El comando de mdb ::arc, nos devuelve información sobre la cache ARC, la línea que hemos puesto en negrita indica el tamaño de la cache, es de b>36.723 MB.
Conclusión
ZFS hace uso de la cache ARC, la cual ocupa memoria del Kernel, esta memoria está asignada a la cache y por lo tanto será liberada cuando el sistema necesite memoria. No nos tenemos que preocupar si de los 64GB de memoria de nuestra máquina solo tenemos libre 3GB y asignados al Kernel 40GB siempre y cuando comprobemos que el tamaño de la cache ARC ronda el 90% del tamaño de la memoria asignado al Kernel.
Algunos derechos reservados. Licencia Creative Commons
8 May 2009 a las 5:25 pm
¿que es una cache segun redes y segun el mru y mfu? ¿que son estas dos ultimas cosas?
13 May 2009 a las 6:42 pm
Buenas tardes,
Antonio, me tienes que perdonar, pero no entiendo tu pregunta sobre:
” ¿que es una cache segun redes y segun el mru y mfu? ”
No se a que te quieres referir con “cache según redes”
En cuanto a tu segunda pregunta
” ¿que son estas dos ultimas cosas? ”
MRU es la abreviatura de Most Recently Used
MFU es la abreviatura de Most Frequently Used
ARC dispone de varios buffer LRU (Least Recently Used) para almacenar los objetos cacheados, dos de estos buffers son MRU y MFU, además tambien existen el MRU ghost (los objetos están recientemente usados pero no estan cacheados) y MFU ghost (los objetos estan frecuentemente usados pero no cacheados)
19 June 2009 a las 3:22 pm
Buenas,
Tengo el siguiente escenario, un servidor M4000 con 32gb de RAM usando ZFS, exactamente son 26 File System. La salida del memstat arroja que el kernel esta consumiendo 16418MB y el tamaño del ARC es de 13180MB, es decir sería aproximadamente un 90% del tamaño de la memoria asignado al kernel.
mdb -k
Loading modules: [ unix krtld genunix specfs dtrace ufs sd mpt px ssd fcp fctl md emlxs ip hook neti qlc sctp arp usba nca logindmux ptm cpc sppp random crypto zfs wrsmd fcip nfs ipc ]
> ::memstat
Page Summary Pages MB %Tot
———— —————- —————- —-
Kernel 2101536 16418 50%
Anon 1777140 13883 43%
Exec and libs 24300 189 1%
Page cache 58592 457 1%
Free (cachelist) 9608 75 0%
Free (freelist) 200824 1568 5%
Total 4172000 32593
Physical 4095211 3199
kstat -p -m zfs |grep size
zfs:0:arcstats:size 13858359296
Ahora bien, en dicho servidor se encuentran ejecutandose una base de datos Oracle y un par de aplicaciones, entre todas ellas hay un consumo promedio de 17gb de memoria. El promedio de FreeMem es de 1gb en este servidor.
Ahora me pregunto que sería mas conveniente con este escenario, si modificar el tamaño del ARC o adicionar memoria fisica al servidor?
Gracias de antemano por tu respuesta..
Saludos
23 June 2009 a las 10:56 pm
Oswaldo, lo primero es que perdones el retraso, pero he estado muy ocupado en el trabajo y no he podido atender los correos del blog.
La pregunta que planteas, no es fácil de responder, todo depende del uso que se esté haciendo de los FS de ZFS, como sabes el kernel tiende a asignar toda la memoria disponible a la cache ARC, he igual que coge memoria, por la única razón de que esta libre, tambien la liberará cuando otro proceso la necesite, en tu caso, el resto de aplicaciones de la máquina.
Creo que para tu caso, lo mas interesante es que pudieras a analizar cómo están trabajando los FS ZFS que tienes creados y de esta forma poder decidir si realmente la asignación de memoria para la cache ARC se justifica y por lo tanto tendrías que añadir mas memoria física a la máquina o por el contrario tus aplicaciones no están haciendo uso intensivo de los FS ZFS y por lo tanto no tendría justificación la compra de mas memoria.
Espero que mi comentario te ayude.