Saltar al contenido principal

Memoria y desalojo

Clustron Zaris es un almacén en memoria: cada nodo mantiene sus datos en RAM, y cada nodo está acotado por un techo de memoria. Este artículo explica cómo funciona ese techo, qué ocurre a medida que un nodo se llena, y cómo el desalojo mantiene un nodo dentro de su límite.

El almacén es un búfer acotado​

Un nodo de Zaris no crece sin límite. Cada nodo contabiliza continuamente el tamaño de los datos que posee activamente y mantiene ese total por debajo de un techo configurado. La contabilidad nunca es opcional — un nodo es siempre un búfer acotado, y lo único que configuras es el tamaño del techo y qué hace el nodo cuando lo alcanza.

El techo predeterminado es 1 GiB de datos poseídos activamente por nodo. Deliberadamente no hay un ajuste "sin límite": si no estableces un techo, se aplica el predeterminado.

nota

El techo cubre los datos que un nodo posee activamente — las copias primarias que sirve. Las copias de réplica que un nodo mantiene para otras particiones se contabilizan por separado y no son lo que el techo del propietario activo tiene en cuenta.

Qué ocurre a medida que un nodo se llena​

Un nodo mantiene su techo de una de dos maneras, según esté habilitado el desalojo o no:

ModoComportamiento en el techoResultado de una escritura que lo excedería
Desalojo habilitado (predeterminado)El nodo desaloja datos más antiguos para hacer sitioLa escritura se admite; se desalojan otros datos
Desalojo deshabilitadoEl nodo rechaza datos nuevosLa escritura se rechaza con KvStatus.CapacityExceeded

Un nodo de Zaris se comporta como una caché acotada: bajo presión de memoria desaloja para mantenerse dentro del techo, de modo que las escrituras siguen teniendo éxito y los datos menos valiosos se descartan primero. La alternativa — un almacén que rechaza al llegar a su capacidad en lugar de descartar datos más antiguos — es el modo sin desalojo que se describe abajo.

nota

En la versión actual, un nodo siempre se ejecuta con el desalojo habilitado usando la política LRU. El modo sin desalojo y las políticas LFU / conscientes de TTL existen en el motor pero todavía no se pueden seleccionar mediante la configuración — el techo de memoria (memory.maxSizeBytes) es el ajuste que controlas.

Políticas de desalojo​

Cuando el desalojo está habilitado, una política decide qué elementos descartar primero. En la versión actual la política es siempre LRU — las demás políticas de abajo describen el modelo pero todavía no se pueden seleccionar mediante la configuración. Zaris muestrea un pequeño conjunto de candidatos y desaloja los de menor puntuación, en lugar de mantener un orden global estricto — el mismo enfoque muestreado que usa Redis.

PolíticaDesaloja primeroÚsala cuando
LRU (predeterminada)Los elementos accedidos menos recientementeEl acceso tiene sesgo de recencia — es probable que los datos recientes se vuelvan a leer
LFULos elementos accedidos con menos frecuenciaUn conjunto caliente estable se beneficia de conservarse frente a picos puntuales
Consciente de TTLLos elementos más cercanos a su expiración por TTLLa mayoría de los datos ya tienen un TTL y quieres un orden de expiración natural
Sin desalojoNada — el nodo rechaza al llegar a su capacidadNunca quieres que se descarten datos de forma implícita

La recencia y la frecuencia se rastrean como señales aproximadas e in situ estampadas en la ruta de lectura, de modo que cuestan casi nada de mantener y nunca requieren un índice separado.

Cómo funciona una ejecución de desalojo​

El desalojo lo impulsa un bucle en segundo plano, no cada escritura individual. El bucle usa histéresis — un disparo alto y un objetivo más bajo — para no dispararse continuamente al borde del techo:

  • Disparo: una ejecución comienza cuando el uso activo supera el 80% del techo.
  • Objetivo: una vez disparada, la ejecución continúa hasta que vuelve a quedar libre aproximadamente el 30% del techo — es decir, hasta que el uso baja a alrededor del 70%.
  • Cadencia: el bucle se despierta en un intervalo fijo (un segundo de forma predeterminada) y muestrea un conjunto acotado de elementos candidatos en cada ciclo.

Como el objetivo posterior al desalojo (70%) queda estrictamente por debajo del disparo (80%), una ejecución baja el uso hasta una banda tranquila en lugar de detenerse justo en el punto que lo volvería a disparar de inmediato.

El límite de tamaño por elemento​

Independientemente del techo global, un solo elemento no puede exceder un tamaño máximo de elemento — 4 MiB de forma predeterminada. Este límite se comprueba en cada escritura con independencia del modo de desalojo: un valor sobredimensionado nunca se admite, y ninguna cantidad de desalojo hará sitio para él. Una escritura que excede el límite se rechaza con KvStatus.ItemTooLarge.

Esto protege a un nodo de un único valor patológico y mantiene barata la contabilidad por elemento.

Gestionar las señales de capacidad en tu código​

Ambos resultados de capacidad afloran como estados tipados en el resultado que ya inspeccionas — no son excepciones, y son distintos para que puedas reaccionar a cada uno correctamente:

var result = await client.PutAsync("report:2026-07", payload);

if (!result.IsSuccess)
{
switch (result.Status)
{
case KvStatus.ItemTooLarge:
// The value itself is too big — split it or store a reference instead.
break;
case KvStatus.CapacityExceeded:
// The node is full and eviction is disabled — retry later or shed load.
break;
}
}

CapacityExceeded solo ocurre en el modo sin desalojo, que no se puede seleccionar en la versión actual, así que normalmente no lo encontrarás — un nodo lleno desaloja bajo la política LRU siempre activa en lugar de rechazar. ItemTooLarge, en cambio, es un resultado vivo y alcanzable y puede ocurrir en cualquier modo.

Configuración​

El techo de memoria del nodo forma parte de la configuración del almacén, bajo la sección memory:

{
"memory": {
"maxSizeBytes": 2147483648
}
}

Establecer maxSizeBytes a null (u omitirlo) aplica el predeterminado de 1 GiB. En la versión actual maxSizeBytes es el único ajuste de memoria configurable: la política de desalojo (LRU), los umbrales de disparo/objetivo, y el límite por elemento descritos arriba son valores predeterminados fijos, no controles de configuración. Consulta la referencia de configuración para el esquema completo de memoria.

Qué significa esto para la planificación de capacidad​

Como cada nodo es un búfer acotado, la capacidad total de un almacén es aproximadamente el techo por nodo multiplicado por el número de particiones que posee un nodo, ajustado por el factor de replicación (las réplicas contienen copias adicionales). Hoy un nodo ejecuta la caché LRU siempre activa, así que dimensiona el techo a tu conjunto de trabajo más un margen para la banda de desalojo; los datos fríos se descartan bajo presión en lugar de rechazarse.

Próximos pasos​