PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Verteilte Anwendung und Synchronisation der Datenbank


Djon
2010-11-05, 14:08:42
Hallo!

Ich entwickle zur Zeit eine einfache verteilte Anwendung. Es gibt mehrere Client, die gleichzeig auf eine Datenbank (MySQL) zugreifen, Daten verändern und Daten löschen können.
Jetzt stehe ich vor dem Problem der Synchronisation. Wie kann ein Client die Daten exclusiv für sich locken? Wie werden die Datenänderungen an andere Clients verteilt?
Das könnte man mit Hilfe der Client/Server-Architektur lösen, doch ich habe nur die Clients und eine MySQL-Datenbank, die bei einem Hoster läuft.
Eine andere Möglichkeit wäre ein ständiges Pollen, doch es ist relativ resourcenfressend und nicht perfomant :(

Sieht ihr vielleicht eine bessere Alternative für das Problem?

Gruß Djon

Frucht-Tiger
2010-11-05, 14:40:46
Welche Client Technologie verwendest du?

Sind Locks überhaupt nötig? Reicht Vllt. ein simples zurückrollen der Transaktion im Fall der Fälle?

Auf jeden Fall soviel Arbeit wie möglich auf das dbms verlagern und erst zum Schluss Gedanken über die Performanz machen. Alles außer Polling würde ja eine komplexe Kommunikation zwischen den clients voraussetzen, das wird schnell hässlich. Am besten den Client stateless aufbauen, d.h. dort erst gar keine Daten zwischenspeichern.

Djon
2010-11-05, 18:04:05
Hallo!

Ich programmiere mit C++/Qt und setze auf MySQL auf.

Mfg Djon

CrazyIvan
2010-11-05, 18:38:07
Beim MS SQL Server gibts dafür die Service Broker Architecture. Sie dient dem asynchronen Verteilen von Nachrichten an Clients, ohne dass diese pollen müssen.
Bei MySQL hab ich auf die schnelle nur sowas gefunden:
http://q4m.github.com/tutorial.html
und hier was, was auch in die Richtung Locking und Message Queuing geht:
http://www.xaprb.com/blog/2007/08/29/how-to-notify-event-listeners-in-mysql/

Bin mir aber noch nichtmal so sicher, ob es das ist, was Du suchst.
Die harte Tour bestünde darin, mittels Trigger an Deinen Datentabellen Nachrichten in eine andere Tabelle zu schreiben, die von den Clients gepollt wird. Allerdings ist der konzeptionelle wie auch der Implementierungsaufwand nicht zu verachten.

/edit:
Also von der Überlegung her:
Deine Anwendung müsste wissen, aus welchen Tabellen sie gerade welche Datensätze betrachtet und wann sie das letzt mal in die Message Queue geschaut hat. Die Trigger an den Tabellen müssen bei UPDATE/INSERT/DELETE eine Nachricht in die Queue absetzen, welche Tabelle und welche Datensätze betroffen sind. Daraufhin muss Deine Anwendung entscheiden, ob diese Nachricht für sie relevant ist und die eigentlichen Daten nachgeladen werden müssen.
War jetzt sehr laienhaft beschrieben, aber vielleicht hilfts Dir ja.

huha
2010-11-05, 22:40:32
Es gibt verschiedene Möglichkeiten, das zu machen. Was du konkret brauchst, hängt vor allem davon ab, wieviele Clients du hast, wie oft darauf zugegriffen werden soll etc. Im Prinzip ist eine einzige Stelle vorzuziehen, bei der die Clients anfragen, ob sie zugreifen dürfen und die das auch verwaltet. Das ist schnell, leicht zu programmieren und geht problemlos.
Eine weitere Frage ist, ob die Clients direkt untereinander kommunizieren können. Wenn das der Fall ist, einfach mal die klassischen Mutual-Exclusion-Techniken (Mutex) anschauen, da findet sich dann was.
Wenn die Kommunikation lediglich über die Datenbank geht, wird's häßlich. Man könnte sich allerdings z.B. folgendes implementieren:

Alle Clients sind durchnumeriert. In der Datenbank gibt's eine Tabelle mit den Feldern client_id und job_id, schlüssel z.B. job_id. Wenn ein Client nun was auf der Datenbank machen will, dann fügt er einen neuen Datensatz in der Tabelle ein mit seiner client_id. Die job_id, die er dann zugewiesen bekommt, merkt er sich natürlich und verknüft diese intern mit der Aktion, die er auf der Datenbank ausführen will. Jetzt wird periodisch eine Anfrage "select client_id, job_id from tabelle where job_id = min(job_id)" gestellt; der Client mit der client_id, die sich dort ergibt, darf dann so lange die anfragen mit der job_id ausführen, bis er genug davon hat, hat die db also für sich gesperrt. Wenn er damit fertig ist, wird der entsprechende Datensatz gelöscht. Im Prinzip also nichts anderes als eine Warteschlange mit der Datenbank. Da die gesendete Anfrage allerdings immer gleich ist, sollte die DB-Software das recht zügig merken und das Ergebnis effizient irgendwo cachen, dann ist das andauernde Polling auch nicht so schlimm.

-huha

Berni
2010-11-05, 23:04:00
Wieso nicht einfach "LOCK TABLES" in MySQL verwenden?

Zur Lösung der Datenverteilung würde ich einfach in einer Tabelle die Revision als Integerwert speichern (wird bei jedem Update hochgezählt; man könnte das auch über einen Trigger direkt datenbankseitig implementieren). Der Client speichert bei sich die aktuelle Revision und vergleicht regelmäßig mit der Datenbank. Wenn es große Tabellen sind könnte man auch Revision getrennt nach Tabelle abspeichern.

Djon
2010-11-07, 17:11:34
Hallo!

Danke für die zahlreichen Vorschläge.
Die einzelne Clients kennen sich gegenseitig nicht, die gesamte Kommunikation muss über die Datenbank ablaufen.

Gruß Djon