Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Multithreading und Datenbanken (https://www.delphipraxis.net/164900-multithreading-und-datenbanken.html)

QuickAndDirty 5. Dez 2011 14:39

Datenbank: FB • Version: 2.5 • Zugriff über: AnyDac

Multithreading und Datenbanken
 
Hallo,
Im moment arbeiten wird mit AnyDac auf Firebird und MSSql server es wird wohl noch Oracle 11g und MySQL hinzukommen.
Wir verwenden kein Storedprocedures alles wird eben über Parameter und Statements abgewickelt.

Das Problem: Wie kann ich einen Multithreaded zugriff auf die Datenbank umsetzen?

Es geht darum das man evtl. 2000 Zugriffe gleichzeitig hat...und wenn alles gequeued wird kann das mal für den letzten 2000 Minuten Dauern. Andererseits weiß ich auch nicht wie ich bei 2000 gleichzeitigen schreib oder lesezugriffen so eine Datenbank Konsistent halten könnte, außer ich mache laaaaange transaktionen auf, aber ich meine gehört zu haben das lange transaktionen böse sind.


Wie macht ihr das? Queuen bis der Arzt kommt oder irgendwie multithreaden und wie?

Bernhard Geyer 5. Dez 2011 14:44

AW: Multithreading und Datenbanken
 
Wieso denkst du das du in einem laufende Prozess deiner Anwendung 20.000 gleichzeitige Zugriffe benötist?

QuickAndDirty 5. Dez 2011 14:48

AW: Multithreading und Datenbanken
 
nur 2000 ...so als peek
Und nun wir haben hier einen Kunden der eine Webanwendug mit 2800 Benutzern sehr stark in Anspruch nimmt.
unter anderem werden viele Berichte gleichzeitig angefordert. Wir queuen diese Vorgänge dann... und je nach Bericht kann das sehr sehr lange dauern. Es kann auch mal eine Minute oder 3 Dauern PRO Bericht in der Queue! Wobei die Datenbank der eigentliche Flaschenhals ist.

Sir Rufo 5. Dez 2011 15:07

AW: Multithreading und Datenbanken
 
Hmmm, das mit der Queue ist ok, aber was hat das mit den Transaktionen zu schaffen?
So ein Bericht ist doch von der Kategorie Ausgabe und der schreibt eigentlich keine Daten zurück in die DB.

Die Transaktionen helfen doch nur dabei, dass gerade die Berichte keine inkonsistenten Daten anzeigen.

Und trotz Transaktion kann ich die Daten noch lesen (nur die aktuell in der Transaktion befindlichen gehen halt nicht - logisch).

Evtl. wäre es aber sinnvoll für die Abfrage einen Snapshot von der DB anzufordern, damit alle Informationen im Bericht die gleiche Basis haben.

Bernhard Geyer 5. Dez 2011 15:13

AW: Multithreading und Datenbanken
 
Zitat:

Zitat von Sir Rufo (Beitrag 1139481)
Und trotz Transaktion kann ich die Daten noch lesen (nur die aktuell in der Transaktion befindlichen gehen halt nicht - logisch).

Dann bekommt man halt die konsistenten etwas ältern Daten (Jedenfalls bei jeder DB die das Multiversion Concurrency Control unterstützt).

Zitat:

Zitat von Sir Rufo (Beitrag 1139481)
Evtl. wäre es aber sinnvoll für die Abfrage einen Snapshot von der DB anzufordern, damit alle Informationen im Bericht die gleiche Basis haben.

ich würde eher schauen ob es immer ähnliche Berichte sind so das man evt. die Daten vorkomprimiert, d.h. rechenintensive daten schon Vorberechnet und in schnell abrufbare Form bereitstellt.

QuickAndDirty 5. Dez 2011 15:22

AW: Multithreading und Datenbanken
 
Zitat:

Zitat von Sir Rufo (Beitrag 1139481)
Hmmm, das mit der Queue ist ok, aber was hat das mit den Transaktionen zu schaffen?
So ein Bericht ist doch von der Kategorie Ausgabe und der schreibt eigentlich keine Daten zurück in die DB.

Die Transaktionen helfen doch nur dabei, dass gerade die Berichte keine inkonsistenten Daten anzeigen.

Und trotz Transaktion kann ich die Daten noch lesen (nur die aktuell in der Transaktion befindlichen gehen halt nicht - logisch).

Evtl. wäre es aber sinnvoll für die Abfrage einen Snapshot von der DB anzufordern, damit alle Informationen im Bericht die gleiche Basis haben.

Kann FB das? Und kann MSSQL das? und wenn ja wie geht das mit anydac?

QuickAndDirty 5. Dez 2011 15:24

AW: Multithreading und Datenbanken
 
Aber Multithreading ist nicht möglich oder?

tsteinmaurer 5. Dez 2011 15:25

AW: Multithreading und Datenbanken
 
@QuickAndDirty: Das ist so eine Alles-oder-Nichts Problemstellung. Man kann schon mit ein paar Abfragen eine Datenbank dicht machen, wenn die Abfragen nicht optimiert sind. Noch besser SQL Server in einem Read/Write-Mischbetrieb, wenn keine Snapshots verwendet werden.

Prinzipiell kann Firebird mehrere Datenbankverbindungen mehr oder weniger "gleichzeitig" bedienen. Kommt halt drauf an wie viele CPUs/Cores du drinnen hast und wie schnell dein I/O-System ist. Vorausgesetzt, wir reden hier vom Firebird Classic oder SuperClassic Server, wo mehrere CPUs/Cores genutzt werden können.

Ich bezweifle, dass auch Oracle 2000 gleichzeitige physische Verbindungen, sofern diese auch etwas tun, einfach wegsteckt. Kann ich mir nicht vorstellen. Hier läuft es in der Regel dann auf ein Connection Pooling raus und wenn alles größer wird eine Architektur mit Load Balancer etc ...

Auf der Firebird Konferenz 2011 wurde eine Fallstudie vorgestellt, wo eine Firebird Datenbank mit ca. 120 GB und ~ 400 Benutzern verwendet wird. Also, technisch ist viel machbar. Kommt halt auf die Qualität des Produzierten etc ... drauf an.

Bernhard Geyer 5. Dez 2011 15:29

AW: Multithreading und Datenbanken
 
Zitat:

Zitat von tsteinmaurer (Beitrag 1139487)
Ich bezweifle, dass auch Oracle 2000 gleichzeitige physische Verbindungen, sofern diese auch etwas tun, einfach wegsteckt. ...

Also wir haben Oracle schon bei einem Kunden mit einem einzigen laufen Programm und optimierten Import (Ohne Threads) so in die Knie bekommen das sich selbst der Admin nicht mehr mit den Server per Admintools verbinden konnte :mrgreen:
Hat sich aber rausgestellt das der Server in HD-Platz-Mangel gelaufen ist ...

QuickAndDirty 5. Dez 2011 15:30

AW: Multithreading und Datenbanken
 
Zitat:

Zitat von Bernhard Geyer (Beitrag 1139483)
ich würde eher schauen ob es immer ähnliche Berichte sind so das man evt. die Daten vorkomprimiert, d.h. rechenintensive daten schon Vorberechnet und in schnell abrufbare Form bereitstellt.

nun, dann müssten wir das gesammte Berichtswesenändern. So das wir quasi auf alte Auswertungen unangetasteter Daten zurrückgreifen könnten und nur neu entstandenen Daten auswerten um dann alles entsprechend zu kombinieren. Das wäre sicher eine nicht ganz unwesentliche Änderung des Berichtswesens...andererseits müsste ich es nicht Programmieren :=) .

himitsu 5. Dez 2011 15:33

AW: Multithreading und Datenbanken
 
Mehrere Connections zur Datenbank (je Thread) und dann sollte es keine Probleme geben.

Die meisten Datenbanken verkraften es ja auch, wenn mehrere zigtaustend Programme (mit je einer Connection) drauf zugreifen,
also sollte ein Programm, mit zigtausend Connections auch zu schaffen sein. (von Seiten der DB ist es ja egal von wo die Connections kommen)

franktron 5. Dez 2011 15:44

AW: Multithreading und Datenbanken
 
Was ich etwas seltsam finde ist eine Webanwendung die alle User in eine Instanz laufen lässt.

Webserver stelle doch normalerweise pro User eine Instanz zur Verfügung, und damit wäre das mit der Zeit doch kein Problem mehr.

QuickAndDirty 5. Dez 2011 15:53

AW: Multithreading und Datenbanken
 
Zitat:

Zitat von franktron (Beitrag 1139495)
Was ich etwas seltsam finde ist eine Webanwendung die alle User in eine Instanz laufen lässt.

Webserver stelle doch normalerweise pro User eine Instanz zur Verfügung, und damit wäre das mit der Zeit doch kein Problem mehr.

Es ist ein A-To-Zed - Intrawebserver.

himitsu 5. Dez 2011 16:10

AW: Multithreading und Datenbanken
 
Es gibt quasi 3-4 Varianten, wie der Server das verwalten kann.

* eine Instanz der Serverklasse ... alle Befehlsaufrufe werden nacheinander behandelt

* eine Instanz der Serverklasse ... alle Befehlsaufrufe werden gleichzeitig behandelt

* je eine Instanz der Serverklasse pro eingehender Connection ... alle Befehlsaufrufe werden gleichzeitig behandelt
(in den Befehlsaufrufen könnte man diese aber wieder komplett/teilweise synchronisieren/blockieren/serialisieren)

* je eine Instanz der Serverklasse pro aufgerufenem Befehl jeder eingehenden Connection ... alle Befehlsaufrufe werden gleichzeitig behandelt
(in den Befehlsaufrufen könnte man diese aber wieder komplett/teilweise synchronisieren/blockieren/serialisieren)

QuickAndDirty 5. Dez 2011 17:24

AW: Multithreading und Datenbanken
 
Wir haben szenario 3
wo dann dennoch alles wieder in eine Queue zusammengeführt wird.
die Funktionen in der Queue haben 3 Ausführungsmodi:
1 = asyncron (quasi eigener Thread Fire and forget)
2 = syncron (von denen kann nur eine gleichzeitig laufen, neben anderen asnycronen...)
3 = Mainthread(die Function wartet auf das ende aller threads und blockiert dann das ausführen weiterer, sie wird im Hauptthread ausgeführt...wegen blöder VCL abhängigkeit)

leider kommt ohne das ganze nur matsche raus....

mjustin 5. Dez 2011 17:42

AW: Multithreading und Datenbanken
 
Zitat:

Zitat von QuickAndDirty (Beitrag 1139514)
1 = asyncron (quasi eigener Thread Fire and forget)
2 = syncron (von denen kann nur eine gleichzeitig laufen, neben anderen asnycronen...)
3 = Mainthread(die Function wartet auf das ende aller threads und blockiert dann das ausführen weiterer, sie wird im Hauptthread ausgeführt...wegen blöder VCL abhängigkeit)

1 = unproblematisch, kann parallel mehrere Clientanfragen entgegennehmen und auch multithreaded laufen?
2 = alle Clientanfragen müssen serialisiert werden (Queue) da es sonst "Matsche" gibt?
3 = in einem Atozed Intraweb Server werden VCL Teile verwendet?

Für den letzten Punkt wäre eine Alterative, seine Verarbeitung aus der Intraweb Anwendung auszulagern in externe Prozesse, damit das blockieren der anderen Threads nicht mehr nötig ist. Könnte man einen eigenen Prozess je Clientanfrage starten, der nach dem Beenden seine Ergebnis-Daten irgendwie an Intraweb zurückliefert, oder einen Pool ständig laufender VCL-Anwendungen verwenden, die sich gegenseitig nicht mehr behindern können? Damit wäre der Server bzw seine Kerne besser ausgelastet.

Ist in Punkt zwei gemeint, dass es global genutzte Resourcen gibt die verhindern, mehrere Clientanfragen parallel auszuführen? (zum Beispiel eine Datenbanktabelle die für die gesamte Dauer der Requestverarbetung exklusiv einem Client gehört)?

jobo 5. Dez 2011 20:17

AW: Multithreading und Datenbanken
 
zum Thema Transaktion in Oracle:
wir nutzen im Wesentlichen seit Jahren ADO / OLEDB ohne klientseitige Transaktionssteuerung. Andere Zugriffe (App.Server, ..) ebenfalls mit impliziten Transaktionen. Das geht wunderbar- für Datenpflege/-verarbeitung.
Für lesenden Zugriff bzw. Reporting sehe ich da allerdings gar keinen Sinn. Wenn ich commited lese, bekomme ich genau das, was zum Zeitpunkt des Aufrufs commited war.
Intensive DV lagern wir in Jobs aus, die nur aus dem Klient angestoßen werden. Den Verlauf kann sich dann im Klient anschauen, wenn man mag. In einem Fall gibt es noch ein kleines DW für extreme Reportingfragen auf einer 2. Hardware. Ansonsten läuft auch viel über Snapshots, das ist für massive Reportanfragen sicher ratsam. Man müsste sich allerdings etwas Gedanken machen, wie man bestimmte Basissnapshots aufbaut, damit möglichst viele Reports das nutzen können. Queueing brachen wir nicht, auch nicht in Intranet Systemen, die auf diese DBs gehen.

In meinen Augen gäbe es nur einen einzigen Nutzen für klientseitiges Transaktionshandling, wenn nämlich der Anwender nach einem Verarbeitungslauf, Import oder so sagen möchte, "alles Quatsch, nicht commiten, rollback". Das hab ich mir zwar schon ab und zu gewünscht, aber der Preis, den man dafür zahlt, ist zu hoch.

Allgemein (gilt nicht nur für Oracle):
Man kriegt natürlich jede DB in die Knie, relativ problemlos. Umgekehrt gibt es aber den gleichen Effekt, Application Tuning und Architektur kann locker mal einen 3 oder 4 stelligen Faktor Performance bringen (natürlich abhängig davon, wie schlecht es vorher umgesetzt war). Eine Größenordnung, die mit neuer Hardware niemals erreicht werden kann.
Wenn man eine DB allerdings stur als Blackbox betrachtet, darf man auch keine großen Erwartungen haben.

QuickAndDirty 6. Dez 2011 10:04

AW: Multithreading und Datenbanken
 
Zitat:

Zitat von mjustin (Beitrag 1139516)
Zitat:

Zitat von QuickAndDirty (Beitrag 1139514)
1 = asyncron (quasi eigener Thread Fire and forget)
2 = syncron (von denen kann nur eine gleichzeitig laufen, neben anderen asnycronen...)
3 = Mainthread(die Function wartet auf das ende aller threads und blockiert dann das ausführen weiterer, sie wird im Hauptthread ausgeführt...wegen blöder VCL abhängigkeit)


Zitat:

Zitat von mjustin (Beitrag 1139516)
1 = unproblematisch, kann parallel mehrere Clientanfragen entgegennehmen und auch multithreaded laufen?

Es ist so: Diese Aufgabe kann parallel oder zu irgendeiner aufgabe laufen, darf ruhig unterbrochen werden &c.
meist jedoch sind es so kleine aufgaben (abschicken eines Query ...) das da kein synchronisationsbedarf existiert,
Zitat:

Zitat von mjustin (Beitrag 1139516)
2 = alle Clientanfragen müssen serialisiert werden (Queue) da es sonst "Matsche" gibt?

Aufgaben vom Typ 2 kommen in eine queue mit den aufgaben von typ 3 und werden immer nur eine nach der anderen bearbeitet.
Zitat:

Zitat von mjustin (Beitrag 1139516)
3 = in einem Atozed Intraweb Server werden VCL Teile verwendet?

Nein wir haben 2 Programme einen Applikation server mit der Queue und den Funktionen und eben der Geschäftlogik &c. Der Atozed webserver rendert das ganze nur.


Zitat:

Zitat von mjustin (Beitrag 1139516)
Für den letzten Punkt wäre eine Alterative, seine Verarbeitung aus der Intraweb Anwendung auszulagern in externe Prozesse, damit das blockieren der anderen Threads nicht mehr nötig ist. Könnte man einen eigenen Prozess je Clientanfrage starten, der nach dem Beenden seine Ergebnis-Daten irgendwie an Intraweb zurückliefert, oder einen Pool ständig laufender VCL-Anwendungen verwenden, die sich gegenseitig nicht mehr behindern können? Damit wäre der Server bzw seine Kerne besser ausgelastet.

Vermutlich ist die beste lösung daran zu arbeiten das der Applicationserver MultiInstanzfähig wird.

Zitat:

Zitat von mjustin (Beitrag 1139516)
Ist in Punkt zwei gemeint, dass es global genutzte Resourcen gibt die verhindern, mehrere Clientanfragen parallel auszuführen? (zum Beispiel eine Datenbanktabelle die für die gesamte Dauer der Requestverarbetung exklusiv einem Client gehört)?

Nun, zu BDE zeiten gab es eine DB mit Localen Tabellen wenn da mehr als ein vorgang drauf gearbeitet hat gabs keine vernünftigen Ergebnisse...die sind allerdings mittlerweile abgeschafft bzw. als Durchnummerierte Temp_Tabellen in der normalen DB untergebracht.
Der andere Ultimative Grund ist der das wir sowas wie ein "Security Objekt" für den gerade angemeldeten benutzer haben (*facepalm*) alle möglichen alten Funktionen beziehen informationen von "DEM" im Applicationserver angemeldeten Benutzer.

Vermutlich macht es durchaus mittelfristig Sinn den Angemeldeten benutzer genauso wie im Webserver an den Thread zu kleben....leider ist der zur zeit noch Global.(*Aua*)

Das einfachste dürfte es wohl sein dem FB mehrere Prozessoren zu geben und mehrere instanzen des Applicationservers laufen zu lassen. Da müsste man dann noch drann arbeiten :(

wie geben ich dem FB mehrere Prozessoren?

tsteinmaurer 6. Dez 2011 11:06

AW: Multithreading und Datenbanken
 
Zitat:

wie geben ich dem FB mehrere Prozessoren?
Kommt auf deine verwendete Firebid Architektur drauf an. Classic und SuperClassic (neu in Firebird 2.5) Server verwenden von Haus aus mehrere CPUs/Cores. Für SuperServer muss der Konfigurationsparameter CpuAffinityMask entsprechend einer BitMask für die CPUS/Cores gesetzt werden. Aber, SuperServer in einer Produktionsumgebung mit mehreren CPUs/Cores macht eh nicht wirklich Sinn.

QuickAndDirty 6. Dez 2011 11:58

AW: Multithreading und Datenbanken
 
Ok,
also habe ich da schon mal keine Optimierungsmöglichkeit.


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:21 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz