sql >> Base de Datos >  >> NoSQL >> Redis

Desbordamiento de pila, Redis e invalidación de caché

Honestamente, no puedo decidir si esta es una pregunta SO o una pregunta MSO, pero:

Pasar a otro sistema es nunca más rápido que consultar la memoria local (siempre y cuando esté codificado); respuesta simple:usamos ambos! Así que usamos:

  • memoria local
  • de lo contrario, verifique redis y actualice la memoria local
  • de lo contrario, obtenga de la fuente y actualice redis y la memoria local

Esto entonces, como usted dice, causa un problema de invalidación de caché, aunque en realidad eso no es crítico en la mayoría de los lugares. Pero para esto, los eventos de redis (pub/sub) permiten una manera fácil de transmitir claves que están cambiando a todos los nodos, para que puedan eliminar su copia local, lo que significa:la próxima vez que sea necesario, recogeremos la nueva copia de redis . Por lo tanto, transmitimos los nombres clave que están cambiando contra un solo nombre de canal de evento.

Herramientas:redis en el servidor ubuntu; BookSleeve como envoltorio redis; protobuf-net y GZipStream (activado/desactivado automáticamente según el tamaño) para empaquetar datos.

Por lo tanto:los eventos de publicación/suscripción de redis se utilizan para invalidar el caché de una clave dada de uno nodo (el que sabe que el estado ha cambiado) inmediatamente (más o menos) a todos nodos.

Con respecto a procesos distintos (de los comentarios, "¿utiliza algún tipo de modelo de memoria compartida para múltiples procesos distintos que se alimentan de los mismos datos?"):No, no hacemos eso. Cada cuadro de nivel web realmente solo aloja un proceso (de cualquier nivel dado), con multiusuario dentro eso, así que dentro del mismo proceso podríamos tener 70 sitios. Por motivos heredados (es decir, "funciona y no necesita reparación"), usamos principalmente la caché http con la identidad del sitio como parte de la clave.

Para las pocas partes del sistema que hacen un uso intensivo de datos de forma masiva, tenemos mecanismos para persistir en el disco de modo que el modelo en memoria se pueda pasar entre dominios de aplicaciones sucesivos a medida que la web se recicla naturalmente (o se vuelve a implementar), pero eso es sin relación con redis.

Aquí hay un ejemplo relacionado que muestra el solo sabor amplio de cómo podría funcionar esto:active una serie de instancias de lo siguiente y luego escriba algunos nombres clave en:

static class Program
{
    static void Main()
    {
        const string channelInvalidate = "cache/invalidate";
        using(var pub = new RedisConnection("127.0.0.1"))
        using(var sub = new RedisSubscriberConnection("127.0.0.1"))
        {
            pub.Open();
            sub.Open();

            sub.Subscribe(channelInvalidate, (channel, data) =>
            {
                string key = Encoding.UTF8.GetString(data);
                Console.WriteLine("Invalidated {0}", key);
            });
            Console.WriteLine(
                    "Enter a key to invalidate, or an empty line to exit");
            string line;
            do
            {
                line = Console.ReadLine();
                if(!string.IsNullOrEmpty(line))
                {
                    pub.Publish(channelInvalidate, line);
                }
            } while (!string.IsNullOrEmpty(line));
        }
    }
}

Lo que debería ver es que cuando escribe un nombre de clave, se muestra inmediatamente en todas las instancias en ejecución, que luego volcarían su copia local de esa clave. Obviamente, en uso real, las dos conexiones deberían colocarse en algún lugar y mantenerse abiertas, por lo que no estar en using declaraciones. Usamos casi un singleton para esto.