Честно казано не мога да реша дали това е въпрос SO или въпрос на MSO, но:
Преминаването към друга система никога по-бързо от заявяване на локална памет (стига да е с ключ); прост отговор:ние използваме и двете! Затова използваме:
- локална памет
- иначе проверете redis и актуализирайте локалната памет
- друго извличане от източника и актуализиране на redis и локалната памет
Това тогава, както казвате, причинява проблем с анулиране на кеша - въпреки че всъщност това не е критично на повечето места. Но за това - събитията на redis (pub/sub) позволяват лесен начин за излъчване на ключове, които се променят към всички възли, така че те да могат да пуснат своето локално копие - което означава:следващия път, когато е необходимо, ще вземем новото копие от redis . Следователно ние излъчваме имената на ключове, които се променят спрямо едно име на канал за събитие.
Инструменти:redis на ubuntu сървър; BookSleeve като редис обвивка; protobuf-net и GZipStream (автоматично активирани/деактивирани в зависимост от размера) за данни за опаковане.
И така:събитията на redis pub/sub се използват за анулиране на кеша за даден ключ от един възел (този, който знае, че състоянието се е променило) незабавно (почти) до всички възли.
По отношение на отделни процеси (от коментари, „използвате ли някакъв вид модел на споделена памет за множество отделни процеси, захранващи едни и същи данни?“):не, ние не правим това. Всяка кутия на уеб ниво наистина хоства само един процес (от всяко дадено ниво) с многократно наемане в рамките на това, така че вътре в същия процес може да имаме 70 сайта. Поради наследени причини (т.е. „работи и не се нуждае от коригиране“) ние използваме предимно http кеша с самоличността на сайта като част от ключа.
За няколкото части на системата с голямо количество данни, ние имаме механизми за запазване на диска, така че моделът в паметта да може да се предава между последователни домейни на приложения, докато мрежата естествено се рециклира (или се разгръща повторно), но това е несвързано с redis.
Ето свързан пример, който показва само широк вкус за това как може да работи това - завъртете няколко екземпляра от следното и след това въведете някои ключови имена:
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));
}
}
}
Това, което трябва да видите, е, че когато въведете име на ключ, то се показва незабавно във всички работещи екземпляри, които след това ще изхвърлят своето локално копие на този ключ. Очевидно при реална употреба двете връзки ще трябва да бъдат поставени някъде и държани отворени, така че не бъдете в using
изявления. За това използваме почти единичен.