Defective Code Logo

Total Downloads Latest Stable Version Latest Stable Version

English | العربية | বাংলা | Bosanski | Deutsch | Español | Français | हिन्दी | Italiano | 日本語 | 한국어 | मराठी | Português | Русский | Kiswahili | தமிழ் | తెలుగు | Türkçe | اردو | Tiếng Việt | 中文

Introducción

Recall es un paquete de caché del lado del cliente de alto rendimiento para Redis en Laravel. Aprovecha la función de caché del lado del cliente de Redis 6 con invalidación automática para reducir drásticamente los viajes y la latencia de Redis. Diseñado específicamente para entornos de Laravel Octane, utiliza APCu o Swoole Table como una capa de caché local que permanece sincronizada con Redis a través de mensajes de invalidación.

Cuando obtienes un valor de Redis, Recall lo almacena localmente. Cuando ese valor cambia en Redis (desde cualquier cliente), Redis notifica automáticamente a Recall para invalidar la copia local. Esto te proporciona la velocidad de la caché en memoria con las garantías de consistencia de Redis.

Características Clave

Ejemplo

// Configura Recall como tu controlador de caché
// config/cache.php
'stores' => [
'recall' => [
'driver' => 'recall',
],
],
 
// Úsalo como cualquier caché de Laravel
use Illuminate\Support\Facades\Cache;
 
// Primera llamada: obtiene de Redis, almacena localmente
$user = Cache::store('recall')->get('user:1');
 
// Llamadas subsiguientes: servidas desde APCu/Swoole Table local (microsegundos)
$user = Cache::store('recall')->get('user:1');
 
// Cuando user:1 se actualiza en cualquier lugar, Redis notifica a Recall para invalidar
Cache::store('recall')->put('user:1', $newUserData, 3600);
// La caché local se invalida automáticamente en todos los trabajadores

Instalación

Instala el paquete a través de Composer:

composer require defectivecode/laravel-recall

Requisitos

Uso

Configuración Básica

  1. Agrega la tienda de caché Recall a tu config/cache.php:
'stores' => [
// ... otras tiendas
 
'recall' => [
'driver' => 'recall',
],
],
  1. Utiliza la tienda de caché en tu aplicación:
use Illuminate\Support\Facades\Cache;
 
// Almacena un valor (escribe en Redis)
Cache::store('recall')->put('key', 'value', 3600);
 
// Recupera un valor (la primera llamada accede a Redis, llamadas subsiguientes utilizan caché local)
$value = Cache::store('recall')->get('key');
 
// Elimina un valor
Cache::store('recall')->forget('key');

Cómo Funciona

  1. Primera Lectura: El valor se obtiene de Redis y se almacena en la caché local APCu/Swoole Table.
  2. Lecturas Subsiguientes: El valor se sirve directamente desde la memoria local (sub-milisegundos).
  3. Escritura en Cualquier Lugar: Cuando cualquier cliente modifica la clave en Redis, Redis envía un mensaje de invalidación.
  4. Invalidación Automática: Recall recibe el mensaje y elimina la clave de la caché local.
  5. Siguiente Lectura: Un valor fresco se obtiene de Redis y se almacena localmente nuevamente.

Este patrón es especialmente potente en entornos de Laravel Octane donde los trabajadores persisten entre solicitudes, permitiendo que la caché local se acumule y sirva muchas solicitudes desde la memoria.

Integración con Octane

Recall se integra automáticamente con Laravel Octane cuando está disponible:

No se requiere configuración adicional. La integración es automática cuando Octane está instalado.

Configuración

Publica el archivo de configuración:

php artisan vendor:publish --tag=recall-config

Esto crea config/recall.php con las siguientes opciones:

Habilitar/Deshabilitar

'enabled' => env('RECALL_ENABLED', true),

Cuando está deshabilitado, Recall pasa directamente a Redis sin utilizar la capa de caché local. Útil para depurar o desplegar gradualmente.

Tienda de Redis

'redis_store' => env('RECALL_REDIS_STORE', 'redis'),

La tienda de caché de Laravel a utilizar para las operaciones de Redis. Esto debe hacer referencia a una tienda de Redis configurada en tu config/cache.php.

Prefijos de Caché

'cache_prefixes' => [],

Solo almacena localmente claves que coincidan con estos prefijos. Déjalo vacío para almacenar todas las claves.

// Solo almacena claves de usuario y configuraciones localmente
'cache_prefixes' => ['users:', 'settings:', 'config:'],

Esto es útil cuando tienes claves de alto volumen que cambian con frecuencia y no deberían almacenarse localmente.

Configuración de Caché Local

'local_cache' => [
// Controlador: "apcu" o "swoole"
'driver' => env('RECALL_LOCAL_DRIVER', 'apcu'),
 
// Prefijo para las claves de caché local
'key_prefix' => env('RECALL_LOCAL_PREFIX', 'recall:'),
 
// TTL predeterminado en segundos (red de seguridad si la invalidación se pierde)
'default_ttl' => (int) env('RECALL_LOCAL_TTL', 3600),
 
// Tamaño de la tabla Swoole (potencia de 2, solo para el controlador swoole)
'table_size' => (int) env('RECALL_SWOOLE_TABLE_SIZE', 65536),
 
// Máximo de bytes por valor en la tabla Swoole (solo para el controlador swoole)
'value_size' => (int) env('RECALL_SWOOLE_VALUE_SIZE', 8192),
],

Controlador APCu (Predeterminado)

El controlador APCu funciona con todos los entornos PHP y servidores Octane (Swoole, RoadRunner, FrankenPHP). Almacena los valores en caché en memoria compartida accesible para todos los procesos PHP.

Requisitos:

Controlador de Tabla Swoole

El controlador de Tabla Swoole utiliza las tablas de memoria compartida de Swoole, proporcionando acceso consistente a través de corutinas dentro del mismo trabajador. Mejor para entornos Swoole/OpenSwoole.

Consejos de configuración:

Escuchas de Octane

'listeners' => [
// Conexión en caliente al inicio del trabajador (reduce la latencia en la primera solicitud)
'warm' => env('RECALL_LISTEN_WARM', true),
 
// Procesar invalidaciones en eventos de tick (más receptivo, ligero overhead)
'tick' => env('RECALL_LISTEN_TICK', false),
],

Conexiones en Caliente

Cuando está habilitado, Recall establece la suscripción de invalidación de Redis cuando el trabajador de Octane comienza. Esto elimina la latencia de conexión en la primera solicitud.

Procesamiento de Tick

Cuando está habilitado, Recall procesa mensajes de invalidación en eventos de tick de Octane además de eventos de solicitud. Esto proporciona una invalidación de caché más receptiva a costa de un ligero overhead adicional.

Uso Avanzado

Procesamiento Manual de Invalidaciones

Si necesitas procesar invalidaciones manualmente (por ejemplo, en un proceso de larga duración):

use DefectiveCode\Recall\RecallManager;
 
$manager = app(RecallManager::class);
$manager->processInvalidations();

Limpiar Caché Local

Para limpiar solo la caché local sin afectar a Redis:

use DefectiveCode\Recall\RecallManager;
 
$manager = app(RecallManager::class);
$manager->flushLocalCache();

Gestión de Conexiones

use DefectiveCode\Recall\RecallManager;
 
$manager = app(RecallManager::class);
 
// Verificar si la suscripción de invalidación está conectada
if ($manager->isConnected()) {
// ...
}
 
// Desconectar manualmente
$manager->disconnect();

Optimización

Límites de Solicitud del Trabajador

Laravel Octane cicla trabajadores después de un número configurable de solicitudes para prevenir fugas de memoria. Cuando un trabajador cicla, su caché local se borra. Aumentar este límite permite que la caché local de Recall persista más tiempo, mejorando las tasas de aciertos de caché.

En tu config/octane.php:

// El predeterminado es 500 solicitudes antes del ciclo
'max_requests' => 10000,

Valores más altos significan mejor utilización de caché, pero requieren confianza en que tu aplicación no tiene fugas de memoria. Monitorea el uso de memoria de tu trabajador al ajustar este valor.

Caché Selectiva con Prefijos

Utiliza cache_prefixes para controlar qué claves se almacenan localmente. Esto es valioso cuando:

// config/recall.php
'cache_prefixes' => [
'users:', // Almacena datos de usuario localmente
'settings:', // Almacena configuraciones de la aplicación
'products:', // Almacena catálogo de productos
],

Las claves que no coincidan con estos prefijos seguirán funcionando pero evitarán la caché local, yendo directamente a Redis.

Consideraciones de Memoria

Memoria APCu

APCu comparte memoria entre todos los procesos PHP. Configura el límite de memoria en php.ini:

; El predeterminado es 32MB, aumenta para necesidades de caché más grandes
apc.shm_size = 128M

Monitoriza el uso de APCu con apcu_cache_info():

$info = apcu_cache_info();
$memory = $info['mem_size']; // Uso de memoria actual en bytes

Dimensionamiento de Tabla Swoole

Las Tablas Swoole tienen una capacidad fija configurada en la creación. Planifica tu tamaño de caché esperado:

'local_cache' => [
// Entradas máximas (debe ser potencia de 2)
'table_size' => 65536, // 64K entradas
 
// Tamaño máximo de valor serializado en bytes
'value_size' => 8192, // 8KB por valor
],

Uso de memoria: table_size × (value_size + overhead). Una tabla con 65536 entradas y valores de 8KB utiliza aproximadamente 512MB.

Patrones Comunes

Configuración de la Aplicación

// Ciclos de caché de características y configuraciones
$features = Cache::store('recall')->remember('config:features', 3600, function () {
return Feature::all()->pluck('enabled', 'name')->toArray();
});
 
// Cuando los ajustes cambian, todos los trabajadores reciben automáticamente las actualizaciones

Datos de Referencia Accedidos Frecuentemente

// Almacena categorías de productos
$categories = Cache::store('recall')->remember('categories:all', 3600, function () {
return Category::with('children')->whereNull('parent_id')->get();
});
 
// Almacena tasas de cambio de divisas
$rates = Cache::store('recall')->remember('rates:exchange', 300, function () {
return ExchangeRate::all()->pluck('rate', 'currency')->toArray();
});

Alternativa a las Etiquetas de Caché

Recall no admite etiquetas de caché, pero puedes lograr funcionalidad similar con prefijos:

// En lugar de etiquetas, utiliza prefijos consistentes
Cache::store('recall')->put("blog:posts:{$id}", $post, 3600);
Cache::store('recall')->put("blog:comments:{$postId}", $comments, 3600);
 
// Limpia toda la caché relacionada con el blog por prefijo (requiere implementación manual)
// O confía en la invalidación automática cuando los datos cambian.

Limitaciones

Modo Cluster de Redis

Recall no admite el modo Cluster de Redis. La opción REDIRECT del comando CLIENT TRACKING requiere que tanto la conexión de datos como la conexión de suscriptor de invalidación estén en el mismo nodo de Redis. En un clúster, las claves se distribuyen entre múltiples nodos en función de los slots hash, lo que hace imposible recibir invalidaciones para claves almacenadas en nodos diferentes.

Para implementaciones de Redis en clúster, considera:

Directrices de Soporte

¡Gracias por elegir nuestro paquete de código abierto! Tómate un momento para revisar estas directrices de soporte. Te ayudarán a sacar el máximo provecho de nuestro proyecto.

Soporte Impulsado por la Comunidad

Nuestro proyecto de código abierto es impulsado por nuestra increíble comunidad. Si tienes preguntas o necesitas asistencia, StackOverflow y otros recursos en línea son tus mejores opciones.

Errores y Priorización de Funciones

La realidad de gestionar un proyecto de código abierto significa que no podemos abordar cada error reportado o solicitud de función de inmediato. Priorizamos los problemas en el siguiente orden:

1. Errores que Afectan Nuestros Productos de Pago

Los errores que impactan nuestros productos de pago siempre serán nuestra máxima prioridad. En algunos casos, solo abordaremos los errores que nos afectan directamente.

2. Solicitudes de Extracción de la Comunidad

Si has identificado un error y tienes una solución, por favor envía una solicitud de extracción. Después de los problemas que afectan a nuestros productos, damos la siguiente mayor prioridad a estas soluciones impulsadas por la comunidad. Una vez revisada y aprobada, integraremos tu solución y daremos crédito a tu contribución.

3. Apoyo Financiero

Para problemas fuera de las categorías mencionadas, puedes optar por financiar su resolución. Cada problema abierto está vinculado a un formulario de pedido donde puedes contribuir financieramente. Priorizamos estos problemas según la cantidad de financiamiento proporcionada.

Contribuciones de la Comunidad

El código abierto prospera cuando su comunidad está activa. Incluso si no estás solucionando errores, considera contribuir a través de mejoras de código, actualizaciones de documentación, tutoriales o asistiendo a otros en los canales de la comunidad. Animamos encarecidamente a todos, como comunidad, a ayudar a apoyar el trabajo de código abierto.

Para reiterar, DefectiveCode priorizará los errores en función de cómo impactan a nuestros productos de pago, las solicitudes de extracción de la comunidad y el apoyo financiero recibido para los problemas.

Licencia - Licencia MIT

Copyright © Defective Code, LLC. Todos los derechos reservados

Por la presente se otorga permiso, de forma gratuita, a cualquier persona que obtenga una copia de este software y los archivos de documentación asociados (el "Software"), para tratar el Software sin restricciones, incluyendo sin limitación los derechos a usar, copiar, modificar, fusionar, publicar, distribuir, sublicenciar y/o vender copias del Software, y a permitir a las personas a las que se les proporciona el Software hacerlo, sujeto a las siguientes condiciones:

La mención de copyright anterior y esta nota de permiso deberán incluirse en todas las copias o partes sustanciales del Software.

EL SOFTWARE SE PROPORCIONA "TAL CUAL", SIN GARANTÍA DE NINGÚN TIPO, EXPRESA O IMPLÍCITA, INCLUYENDO PERO NO LIMITÁNDOSE A LAS GARANTÍAS DE COMERCIALIZABILIDAD, ADECUACIÓN PARA UN PROPÓSITO PARTICULAR Y NO INFRACCIÓN. EN NINGÚN CASO LOS AUTORES O TITULARES DE LOS DERECHOS DE AUTOR SERÁN RESPONSABLES DE NINGUNA RECLAMACIÓN, DAÑO O OTRA RESPONSABILIDAD, YA SEA EN UNA ACCIÓN DE CONTRATO, AGRAVIO O DE OTRA MANERA, QUE SURJA DE, O EN CONEXIÓN CON EL SOFTWARE O EL USO O OTRAS NEGOCIACIONES EN EL SOFTWARE.