Redis
 sql >> Baza danych >  >> NoSQL >> Redis

Przepełnienie stosu, Redis i unieważnienie pamięci podręcznej

Szczerze mówiąc nie mogę zdecydować, czy to jest pytanie SO, czy pytanie MSO, ale:

Przejście do innego systemu nigdy szybsze niż odpytywanie pamięci lokalnej (o ile jest kluczowana); prosta odpowiedź:używamy obu! Więc używamy:

  • pamięć lokalna
  • w przeciwnym razie sprawdź redis i zaktualizuj pamięć lokalną
  • w przeciwnym razie pobierz ze źródeł i zaktualizuj redis i pamięć lokalną

To z kolei, jak mówisz, powoduje problem unieważnienia pamięci podręcznej – chociaż w rzeczywistości nie jest to krytyczne w większości miejsc. Ale w tym celu – zdarzenia redis (pub/sub) pozwalają w łatwy sposób rozgłaszać klucze, które zmieniają się do wszystkich węzłów, dzięki czemu mogą porzucić swoją lokalną kopię – co oznacza:następnym razem, gdy będzie to potrzebne, pobierzemy nową kopię z redis . Dlatego emitujemy nazwy klawiszy, które zmieniają się w odniesieniu do nazwy kanału pojedynczego zdarzenia.

Narzędzia:redis na serwerze ubuntu; BookSleeve jako opakowanie redis; protobuf-net i GZipStream (włączane / wyłączane automatycznie w zależności od rozmiaru) do pakowania danych.

A więc:zdarzenia redis pub/sub są używane do unieważnienia pamięci podręcznej dla danego klucza z jednego węzeł (ten, który wie, że stan się zmienił) natychmiast (prawie dużo) na wszystkie węzłów.

Odnośnie odrębnych procesów (z komentarzy, „czy używasz jakiegokolwiek modelu pamięci współdzielonej dla wielu odrębnych procesów żywiących się tymi samymi danymi?”):nie, nie robimy tego. Każde pole warstwy internetowej w rzeczywistości obsługuje tylko jeden proces (z dowolnego poziomu), z wielodostępnością w ramach więc w ramach tego samego procesu możemy mieć 70 witryn. Ze starszych powodów (tj. „działa i nie wymaga naprawy”) używamy głównie pamięci podręcznej http z tożsamością witryny jako częścią klucza.

W przypadku kilku części systemu intensywnie przetwarzających dane dysponujemy mechanizmami utrwalania na dysku, dzięki czemu model znajdujący się w pamięci może być przekazywany między kolejnymi domenami aplikacji w miarę naturalnego recyklingu (lub ponownego wdrażania) sieci. niezwiązane z redis.

Oto powiązany przykład, który pokazuje tylko szeroki smak jak to może działać - uruchom kilka wystąpień następujących elementów, a następnie wpisz kilka nazw kluczy:

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

Powinieneś zobaczyć, że po wpisaniu nazwy klucza jest ona natychmiast wyświetlana we wszystkich uruchomionych instancjach, które następnie zrzucają lokalną kopię tego klucza. Oczywiście w prawdziwym użyciu te dwa połączenia musiałyby być gdzieś umieszczone i pozostawione otwarte, więc nie być w using sprawozdania. Używamy do tego prawie jednego singletona.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Czekaj na wywołanie zwrotne funkcji asynchronicznej w ostatnim zdarzeniu stream.on('data')

  2. resque-scheduler nie powiedzie się podczas usuwania zadania

  3. Pomysły na skalowanie czatu w AWS?

  4. Pracownik kolejki Redis ulega awarii w utcparse

  5. Jak wykonać Persistence Store w Redis?