php - ¿Por qué APC está incrementando el "Recuento completo de caché" para el caché de usuario a pesar de que tiene suficiente memoria disponible?
drupal caching (2)
He jugado con esto durante bastante tiempo, pero estoy un poco perdido en cuanto a qué hacer. Estoy usando APC 3.1.3p1 en CentOs 5 con PHP 5.2.5. APC actúa tanto como el caché de opcode como el caché de usuario. En su mayoría, este servidor ejecuta los sitios de Drupal 6 utilizando el módulo CacheRouter para el soporte de caché de APC. Estaba ejecutando APC 3.0.19 por un tiempo, pero estaba causando que Apache se bloqueara ocasionalmente (un error documentado en esa versión de APC), por eso estoy en 3.1.3p1.
He configurado APC para que tenga 512 MB de memoria (mmap).
Los síntomas son un poco intermitentes, pero a partir de un caché vacío, esto es generalmente lo que veo:
El caché del usuario se llena bastante despacio. A pesar de una tasa de inserción inicial de algo así como 20,000 inserciones / seg, la memoria caché del usuario solo reportará unos cientos, luego unas miles de entradas, y crecerá muy lentamente. Posiblemente pueda atribuir esto a write_locking, pero solo quiero mencionarlo en caso de que sea importante para resolver el problema. Después de varias horas alcanza un equilibrio de alrededor de 30k entradas.
La fragmentación se establece temprano y crece rápidamente. Dentro de unas 10 horas más o menos usualmente estoy al 100% de fragmentación.
El uso general del caché (opcode + user) se estabiliza alrededor de 240MB o menos. Prácticamente nunca irá por encima de ese nivel. Después de un día más o menos, comenzaré a ver incrementos en la Cuenta Completa de Caché de Caché de Usuario (UCCFC).
En el momento de escribir esto, mi UCCFC está en 62358 y está creciendo a pesar de que APC reporta 280MB gratis. Tengo un user_ttl de 7200, pero también he jugado con establecerlo en 0 u otras cantidades y tiene poco o ningún efecto sobre el problema.
Sospecho que el problema tiene algo que ver con la fragmentación. En este momento mi servidor está informando "Fragmentación: 100.00% (280.0 MBytes de 280.0 MBytes en 24740 fragmentos)" y 280 MB simplemente resulta ser la cantidad de espacio libre que APC está informando; una coincidencia reveladora, creo. Desafortunadamente, he encontrado muy poca información en los documentos o en otros lugares para indicar exactamente qué significa "fragmentación" en el mundo de APC, y parece que no hay prácticamente nada que puedas hacer para evitarlo.
¿Alguien puede arrojar algo de luz sobre este problema?
http://pecl.php.net/bugs/bug.php?id=13146 Creo que deberías continuar allí o abrir un nuevo informe de errores.
APC calcula el porcentaje de fragmentación usando la siguiente fórmula:
(total_size_of_free_blocks_lt_5M / total_size_of_all_free_blocks) * 100
* Tenga en cuenta que solo cuenta bloques más pequeños que 5M como fragmentados.
Traduciré tu caso específico al inglés simple:
Fragmentación: 100.00% (280.0 MBytes de 280.0 MBytes en 24740 fragmentos)
Esto significa que de los 280M de tus bloques libres, todos ellos son menores a 5M. Si divide su espacio libre por la cantidad de fragmentos, verá que esto equivale a un tamaño de fragmento promedio de ~ 11.6K.
Esto significa que si intenta almacenar un artículo que es más grande que todos los bloques disponibles, no encajará, y sucederá una de dos cosas, según la configuración de configuración de apc.user_ttl
. Si el TTL se establece en 0, se enjuaga todo el caché de usuario y se inserta el elemento. Si el TTL se configura como mayor que 0, eliminará las entradas caducadas e insertará el ítem. En ambos casos, el recuento completo de caché se incrementa. Tener este incremento tanto como en tu caso es un indicador de que podrías estar haciendo mal .
Aquí hay una visualización simple de lo que la fragmentación está haciendo a su caché a lo largo del tiempo. Representa un tamaño de caché de 32 bytes simple, cada bloque es 1B.
[--------------------------------] (starts empty) [A-------------------------------] (1B stored) [ABB-----------------------------] (2B stored) [ABBCCCC-------------------------] (4B stored) ... (time elapses) [A--CCCC-EEE--GGGGGG-III--KKKLLLL]
Entonces, si quiere almacenar el ítem M
, que es el tamaño 4B, no puede, porque el bloque más grande disponible es 2B. Esto desencadena un incremento de recuento completo de la memoria caché y una descarga total o parcial basada en el user_ttl explicado en detalle anteriormente.
Ahora la pregunta es: ¿es esto malo en tu caso?
Creo que podría ser. La fragmentación del 100% de la caché no es mala en sí misma. No es raro ver eso en cualquier servidor de producción en ejecución. Sin embargo, verlo al 100% con ese espacio libre es una señal de que algo podría estar mal.
- Podría estar almacenando en caché demasiado; El hecho de que el caché esté allí no significa que deba meterse todo en él.
- Puede almacenar en caché con un TTL demasiado corto (para una entrada), los TTL bajos significan que los bloques no libres se liberan con mayor frecuencia.
- También es posible que tenga un puñado de artículos realmente grandes que intenta almacenar. Con una fragmentación del 100%, se garantiza que ningún elemento> = 5M no cabrá. Con un tamaño promedio de bloque libre de 11.6K, es cada vez más probable que un determinado elemento no encaje, ya que su tamaño aumenta más allá de los 11.6K.
Es posible que desee intentar ordenar su caché de usuario por tamaño y ver cuáles son sus entradas más grandes y cuáles son sus TTL. Tal vez podrían aumentarse?
Realmente no es posible dar un diagnóstico exacto sin tener los codos en lo profundo de su (s) aplicación (es) y los patrones de uso, pero toda esta información debería ponerlo en el camino correcto. Es muy posible que no sea un problema y puedes dejar que APC lo haga en silencio.