Solaris: Memory Leak o ZFS usando cache ARC.

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 = 0x8f73c3200
    p = 0x90ad7189c
    c = 0x91ec7845a
    c_min = 0x7fa8c000
    c_max = 0xfb5180000
    hits = 0x7581c97
    misses = 0x2433a80
    deleted = 0x33c49ce
    recycle_miss = 0x285024
    mutex_miss = 0x1a9f6
    evict_skip = 0xc84d2e4
    hash_elements = 0x8fc5a
    hash_elements_max = 0xafcf5
    hash_collisions = 0x16d3def
    hash_chains = 0x1ae59
    hash_chain_max = 0x8
    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.

4 Responses

  1. antonio441@hotmail.es May 8, 2009 / 5:25 pm

    ¿que es una cache segun redes y segun el mru y mfu? ¿que son estas dos ultimas cosas?

  2. admin May 13, 2009 / 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)

  3. Oswaldo June 19, 2009 / 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

  4. admin June 23, 2009 / 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.

Comments are closed.