sql >> Databasteknik >  >> NoSQL >> Redis

Stack Overflow, Redis och Cache-ogiltigförklaring

Jag kan ärligt talat inte avgöra om detta är en SO-fråga eller en MSO-fråga, men:

Att gå till ett annat system är aldrig snabbare än att fråga lokalt minne (så länge det är nycklat); enkelt svar:vi använder båda! Så vi använder:

  • lokalt minne
  • annars kontrollera redis och uppdatera lokalt minne
  • annars hämta från källan och uppdatera redis och lokalt minne

Detta orsakar sedan, som du säger, ett problem med cache-ogiltigförklaring - även om det faktiskt inte är kritiskt på de flesta ställen. Men för detta - redis-händelser (pub/sub) tillåter ett enkelt sätt att sända nycklar som ändras till alla noder, så att de kan släppa sin lokala kopia - vilket betyder:nästa gång det behövs hämtar vi den nya kopian från redis . Därför sänder vi nyckelnamnen som ändras mot ett enda evenemangskanalnamn.

Verktyg:Redis på ubuntu-servern; BookSleeve som ett redis-omslag; protobuf-net och GZipStream (aktiverad / inaktiverad automatiskt beroende på storlek) för paketeringsdata.

Så:Redis pub/sub-händelserna används för att ogiltigförklara cachen för en given nyckel från ett nod (den som vet att tillståndet har ändrats) omedelbart (i stort sett) till alla noder.

Angående distinkta processer (från kommentarer, "använder du någon form av delat minnesmodell för flera distinkta processer som matar samma data?"):nej, det gör vi inte. Varje web-tier box är egentligen bara värd för en process (av en given nivå), med multi-tenancy inom det, så inom samma process kan vi ha 70 platser. Av äldre skäl (dvs. "det fungerar och behöver inte fixas") använder vi i första hand http-cachen med webbplatsens identitet som en del av nyckeln.

För de få massivt dataintensiva delarna av systemet har vi mekanismer för att kvarstå till disk så att in-memory-modellen kan överföras mellan på varandra följande app-domäner när webben naturligt återvinns (eller distribueras om), men det är orelaterade till redis.

Här är ett relaterat exempel som visar enbart den breda smaken om hur detta kan fungera - snurra upp ett antal instanser av följande och skriv sedan in några nyckelnamn:

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));
        }
    }
}

Vad du bör se är att när du skriver ett nyckelnamn, visas det omedelbart i alla körande instanser, som sedan skulle dumpa sin lokala kopia av den nyckeln. Uppenbarligen i verklig användning skulle de två anslutningarna behöva placeras någonstans och hållas öppna, så inte vara i using uttalanden. Vi använder nästan en singel för detta.




  1. Jag behöver hämta MongoDBs objekt bara med filtereds array-objekt

  2. vårdata mongodb id-fältkartläggning

  3. Vad är syftet med kolon inom Redis-nycklar

  4. Operativa faktorer att beakta under MongoDB-datamodellering