C# Cache Synchron halten

ete

Cadet 4th Year
Registriert
Jan. 2011
Beiträge
89
Hallo Zusammen!
Ich bräuchte für folgendes Problem mal ein paar Denkanstöße, weil ich irgendwie gerade auf dem Schlauch stehe.
Ich habe ein Suchsystem, dass in einer Datenbank sucht (logisch :>). Um diese zu entlasten, habe ich einen Cache dazwischen gelegt, der die suchanfrage mit den dazu gehörigen Ergebnissen speichert. Wenn die selbe Anfrage nochmal kommt, wird dann das Cache Ergebnis zurück gegeben, um keinen Zugriff auf die Datenbank zu benötigen.
Jetzt (endlich) zu meinem Problem: Ich ändere jetzt einen Eintrag in der Datenbank. Wenn jetzt eine Anfrage kommt, die das betreffen würde, erhält man ja den Eintrag aus dem Cache, der dann aber nicht mehr aktuell ist, weil sich ja etwas geändert hat. Wie kann ich jetzt Cache und Datenbank synchron halten bzw. woher weiß der Cache, ob seine Einträge noch gültig sind?(in C# geschrieben)

Gruß ete
 
Es gibt doch den Cache für Lokale Datenbanken in .NET. Ich glaube ab 3.5.1.

Der synchronisiert automatisch wenn die SQL Server Nachverfolgung aktiviert ist.
Wenn du ne andere DB nimmst, musste wohl selber für die Synchronisierung sorgen.

EDIT: Wenn du das selber synchronisieren willst, könnte ich mir denken dass es mit einem Polling
seitens des Programms funktionieren. Man könnte sich beim ersten Laden des Caches den Wert
der letzen Änderung der Tabelle merken und dann alle paar Sekunden schauen ob es sich geändert hat.

Wenn das nicht geht weil die DB das nicht unterstützt könnte man einen Trigger auf die fragliche Tabelle setzen, die einen Zeitstempel in einer separaten Tabelle bei jedem Update und Insert aktualisiert. Diese Werte können dann mit dem Programm abgefragt werden um zu sehen ob sich der Tabelleninhalt geändert hat.
 
Zuletzt bearbeitet:
Ich würde eine Spalte "ChangeMoment" oder "RowVersion" hinzufügen. Den ChangeMoment erhöhst du immer wenn du eine ROW in der DB updatest (das macht RowVersion automatisch, das ist ein 64 Bit Integer der sich immer erhöht wenn ein Insert oder Update gemacht wird).

Dann machst du dir eine Stored Procedure die differenziell alle Änderungen seit dem letzten ChangeMoment (oder der letzten RowVersion) zurückliefert. Gleichzeitig liefert dieser Procedure auch den aktuellen Wert von ChangeMoment oder RowVersion.

Ein Timer in deinem Cache könnte nun alle X Sekunden diese Procedure aufrufen und die Änderungen nachladen und im Speicher updaten.
 
@ete:
Nur ein paar Verständnisfragen:

Wie hast du den Cache dazwischen gelegt, d.h. ist es ein Cache der auf jedem Client lokal ist und vor jeder Abfrage prüft ob die Daten da sind, oder ist es eine Servicekomponente die auf dem Server liegt und alle Clients verbinden sich mit diesem Cacheservice anstatt direkt mit der Datenbank und werden dann aus Cache oder frisch von der DB bedient, oder ist es eine Webapplikation, die ihrerseits zwar auf dem Server liegt, aber dennoch den Cache eigenständig pflegt?

Hast du Zugriff auf die Codes der Anwendung und kannst hier ggfs. Änderungen vornehmen oder nur Zugriff auf den Cache Code?

Welche Art von Daten sollen gecasht werden, alle möglichen Daten aus allen Tabellen oder nur spezifische Daten aus einigen wenigen Tabellen?

Wie ist die typische Struktur der gecashten Tabellen, d.h. gibts ID, TIMESTAMPS oder ähnliche von DB verwaltete/befüllte Spalten? Indizes?

Welches DBMS kommt zum Einsatz? Oracle, MS SQLServer, MySQL, Informix ... ? Welche Version wird verwendet?

Wie sehen die Abfragen in der DB aus? Gibt es spezielle verwendete Konstrukte, die den Zugriff extrem verlangsamen und deshalb gecasht werden sollen?

Werden Indizes in den Abfragen verwendet?

Wieviele konkurrierende User würden die DB beackern (ca. reicht aus, muss nicht bis auf den letzten User genau sein)? Hier gehts nur darum abschätzen zu können, wie stark die DB im Falle, dass kein Cache existiert, ausgelastet werden wird.

Ist es eine Webanwendung, die im Internet praktisch von jedem genutzt werden kann?

Soll eine Volltextrecherche möglich sein oder gehts hier nur um Werte aus einzelnen Spalten, die abgefragt werden?

Wie ist der Cache aufgebaut?
Wie wurde der Cache implementiert?
Welche Konstrukte, Klassen, Strukturen, Algorithmen kommen zum Einsatz?

So, das wären nun meine Fragen gewesen.

Worauf ich hinaus will: Es wäre gut etwas mehr über die Umgebung/Anwendung zu erfahren... Desweiteren hast du, wie schon von Dir festgestellt, bei einem Cache immer das Problem, dass die Daten nur bis zu einem gewissen Grad aktuell sein können. Wenn du jetzt aber anfängst, bei jeder Abfrage zu prüfen ob die Daten noch ok sind oder besser aus der Datenbank gezogen werden sollen, dann wirst du durch den Cache nichts an Performance gewinnen, da du nur den Aufwand geringfügig verlagerst und das zum Preis einer u.U. sehr komplexen Logik, die du dann für den Refresh des Caches implementieren musst. Desweiteren implementieren die meisten DBMS schon intern diverse Caches um bereits einmal abgefragte Daten schnellstmöglich bei erneuter Abfrage zu liefern.

Grüße,
Rossibaer
 
Zuletzt bearbeitet:
Puh, das sind mal viele Fragen :>
Versuche dann mal noch ein paar Informationen zu geben. An den Code komme ich ran bzw er kann auch verändert werden. Erstmal nochmal zur eigentlichen Anwendung. Es ist (wird) eine Produktsuche im Internet (User aufkommen kann also durchaus groß werden). Du gibst einen Suchbegriff ein und erhälst passende Produkte aus der Datenbank. Die Anfrage geht dabei zum Cache, dieser guckt, ob er was hat und leitet bei einem miss die Anfrage an den Suchservice weiter. Der Cache soll schoneinmal gesuchte Begriffe zwischenspeichern und bei gleicher Anfrage das Ergebnis liefern. Der Cache an sich beruht auf memcached.
Hab jetzt eben das Problem, dass jemand etwas sucht und das Ergabnis aus dem Cache nicht mehr aktuell ist und Dinge angezeigt werden die nicht mehr existieren oder Dinge fehlen die erst neu dazugekommen sind. Ein Lösungsansatz von mir wäre, die Cacheeinträge mit einer Gültigkeit zu signieren. Dadurch werden Einträge nach einer bestimmten Zeit wieder gelöscht und müssen neu gelesen werden. Ist aber keine besonders elegante Lösung, da viele Ressourcen verschenkt werden.
Die vielen Fragen lassen mich aber hoffen, dass du eine Lösung im Hinterkopf hast :>

Gruß ete
 
Ok, sorry wenn ich dich mit den unsortierten Fragen erstmal "überfallen" habe. Dann eben langsam Schritt für Schritt:

1. Welche Softwareumgebung, d.h. Webserver, Programmier-/Scriptsprachen, Datenbanksystem, Betriebssystem der Server?

2. memcached kenne ich bis jetzt noch nicht. Sieht mir nach C/C++ aus. Die Überschrift deines Threads spricht von C#. Schreib mal, wie das nun zusammengehört. Bin da verwirrt.
 
Ich würde mir überlegen, ob ein Cache wirklich Sinn macht, da die Datenbank einen eigenen hat und Queries gespeichert werden. Die macht von Haus aus das, was du willst.

Wenn du puffern willst, dann rate ich auch zu einem Timeout für den Cache-Eintrag.

Kannst auch überlegen, die Aktualisierung der Datenbank abzufangen von deinen Schnittstellen oder Web-Oberflächen. Normal fügt ja keiner manuell etwas in die Datenbank. Da kann man überlegen, sich einen WCF-Service zu schreiben, der nur für die Aktualisierung der DB und dem Chache für Sucheanfragen zuständig ist und in der Mitte sitzt. Aber ich halte das kaum für notwendig, selbst bei sehr vielen Anfragen. Die Last gibt man an die DB weiter und wenn die es nicht kann, könnte es an Indizies fehlen oder es mangelt dann an Ressourcen.
 
Zurück
Oben