Redis
 sql >> Base de Dados >  >> NoSQL >> Redis

Stack Overflow, Redis e invalidação de cache


Sinceramente, não consigo decidir se esta é uma pergunta SO ou uma pergunta MSO, mas:

Ir para outro sistema nunca mais rápido do que consultar a memória local (desde que esteja com chave); resposta simples:usamos os dois! Então usamos:
  • memória local
  • verifique redis e atualize a memória local
  • buscar da fonte e atualizar redis e memória local

Isso então, como você diz, causa um problema de invalidação de cache - embora na verdade isso não seja crítico na maioria dos lugares. Mas para isso - os eventos redis (pub/sub) permitem uma maneira fácil de transmitir chaves que estão mudando para todos os nós, para que eles possam descartar sua cópia local - o que significa:da próxima vez que for necessário, pegaremos a nova cópia do redis . Portanto, transmitimos os nomes-chave que estão mudando em relação a um único nome de canal de evento.

Ferramentas:redis no servidor ubuntu; BookSleeve como um wrapper redis; protobuf-net e GZipStream (ativado/desativado automaticamente dependendo do tamanho) para dados de empacotamento.

Portanto:os eventos redis pub/sub são usados ​​para invalidar o cache de uma determinada chave de um node (aquele que sabe que o estado mudou) imediatamente (praticamente) para todos nós.

Em relação a processos distintos (dos comentários, "você usa algum tipo de modelo de memória compartilhada para vários processos distintos alimentando os mesmos dados?"):não, não fazemos isso. Cada caixa de camada da Web hospeda apenas um processo (de qualquer camada), com multilocação dentro isso, então dentro do mesmo processo podemos ter 70 sites. Por motivos herdados (ou seja, "funciona e não precisa de correção"), usamos principalmente o cache http com a identidade do site como parte da chave.

Para as poucas partes do sistema com uso intensivo de dados, temos mecanismos para persistir no disco para que o modelo na memória possa ser passado entre domínios de aplicativos sucessivos à medida que a Web recicla naturalmente (ou é reimplantada), mas isso é não relacionado ao redis.

Veja um exemplo relacionado que mostra o somente amplo de como isso pode funcionar - gire várias instâncias do seguinte e digite alguns nomes-chave:
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));
        }
    }
}

O que você deve ver é que quando você digita um nome de chave, ele é mostrado imediatamente em todas as instâncias em execução, que então despejariam sua cópia local dessa chave. Obviamente, em uso real, as duas conexões precisariam ser colocadas em algum lugar e mantidas abertas, então não estar em using declarações. Usamos quase um singleton para isso.