Laden...

Datenbankabfragen bei mehreren Servern parallelisieren

Letzter Beitrag vor 12 Jahren 7 Posts 1.155 Views
Datenbankabfragen bei mehreren Servern parallelisieren

verwendetes Datenbanksystem: SQL Server 2005 ( 2008 )
Betriebssystem: Windows Server 2003 ( 2008 )
Entwicklungsumgebung: Visual Studio 2010 Premium
.net Version: .net 3.5 -> Version 4 ist aktuell noch nicht ausgerollt in unserer Firma.

Hallo zusammen,

ich bin noch grün hinter den Ohren was programmieren angeht.
Die grundlegenden Dinge bekomme ich schon hin, und mit einigen Beispielen im Internet und Büchern habe ich noch immer alles hinbekommen was ich wollte.

Jetzt hänge ich aber schon einige Zeit an einem Problem, welches meiner Meinung nach nicht all zu schwer zu lösen sein sollte. Ich finde jedoch nicht die Antworten auf meine Fragen -> vielleicht suche ich auch einfach falsch. 😉

Situation:
Ich habe einen Monitoring Rechner. Dieser soll mit Hilfe eines selbstgeschriebenen Programms den Status von n Servern anzeigen.
Dafür soll das Programm parallel an alle Server einen SQL Befehl absetzen und das Ergebnis in eine Combobox schreiben (Jeder Server hat eine eigene Combobox).

Vielleicht kann mir jemand von euch ein paar Tips und Quellcodebeispiele hierfür geben.

Beispiel:
Server1 -> DB: Beispieldatenbank -> select name from TBL_Bsp
Server2 -> DB: Beispieldatenbank -> select name from TBL_Bsp
Server3 -> DB: Beispieldatenbank -> select name from TBL_Bsp

Combobox1 = Ergebnis von Abfrage Server1
Combobox2 = Ergebnis von Abfrage Server2
Combobox3 = Ergebnis von Abfrage Server3

So, viel geschrieben und wenig gesagt 😁
Ich hoffe ich konnte etwas verständlich rüberbringen was ich meine.

Bin auf eure Ansätze gespannt.

Hallo boon,

das kannst du machen indem du die einzelnen Operationen in einen **_:::

Schau dir das am Besten noch das hier an: [FAQ] Warum blockiert mein GUI?
Du musst nämlich aufpassen dass deine GUI nicht blockiert.

Gruß
Michael

Hallo Boon,

mach es doch genauso wie Du geschrieben hast : 3 SQL-Befehle absetzen und die Ergebnisse anzeigen (wieso Combo-Box ?).

Wie lange braucht die Ausführung der SQL-Befehle ?

Wenn sie länger als 2-3 sec. braucht dann würde dein Dialog einfrieren. Dann benutze die asynchronen Methoden des SQL-Servers :

try
{
	conn.Open();
	IAsyncResult result = cmd.BeginExecuteReader();
	...
	SqlDataReader dr = cmd.EndExecuteReader(result);
}

Eigene Threads sind m.E. nicht notwendig.

Dafür soll das Programm parallel an alle Server einen SQL Befehl absetzen und das Ergebnis in eine Combobox schreiben

Bei was brauchst Du Hilfe ?

Grüße Bernd

Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3

Guten Morgen,

@michlG: Vielen Dank für den Hinweis, das werde ich mir mal genauer anschauen. Klingt vielversprechend.

@BerndFfm: Danke.

Noch einige weitere Informationen:
Anzahl der Server die angefragt werden müssen: ca 50
Zur Zeit läuft noch ein altes Programm, dass diese Aufgabe übernimmt. Es fragt jedoch seriell alle Server an. Pro Server dauert die Anfrage etwa 10 Sekunden, was sich dementsprechen zu 500 Sekunden aufaddiert.
Natürlich vorausgesetzt, die Server sind alle komplett erreichbar. Ansonsten addieren sich natürlich auch noch Timeouts hinzu.

Grueße

Hallo,

wenn es absehbar ist, dass .NET 4 bei euch bald kommt, würde es sich auch Anbieten, jede Anfrage in einem Task auszulagern.
Hier musst Du im Gegensatz zu Thread nicht darauf achten, dass Du noch genug freien Speicher hast. Das macht das Betriebssystem Framework für Dich.

Eine weitere Möglichkeit wäre Parallel.Invoke() bzw. Parellel.ForEach(), die ebenfalls nur so viele Anfragen zeitgleich starten, wie Ressourcen verfügbar sind.

Gruß

50 hört sich doch nicht viel an. Ich würde mal 50 Asynchrone SQL-Befehle probieren.

Grüße Bernd

Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3

Hallo Abt,

Hier musst Du im Gegensatz zu Thread nicht darauf achten, dass Du noch genug freien Speicher hast. Das macht das Betriebssystem für Dich.

Ist so nicht ganz korrekt. Das Betriebssystem macht hier relativ wenig, außer die Threads zu erstellen und entsprechend des OS-Scheduler die Zeitscheiben für die Ausführung zuweisen. Der "wichtigere" Rest wird von .net erledigt, hier bei Task konkret vom verwendeten TaskScheduler bzw. letzten Endes vom (managed) ThreadPool. Das von dir angedachte Problem mit der sogenannten "Oversubscription" kommt nur dann zum Tragen, wenn explizit Threads mit new Thread() erstellt werden und selbst dann geht der Speicher erst bei sehr sehr vielen Threads aus. Zuvor geht sicher die Leistung in den Keller. Oversubscription kann auch bei ThreadPool-Threads passieren, allerdings versucht hier der TaskScheduler einen Kompromiss für optimalen Durchsatzt der Work-Items zu finden, indem er den Durchsatz laufend überwacht und diese "Kurve" maximiert.

Hallo zusammen,

vermutlich ist der Vorschlag von BerndFfm der idealste, da während der Abfrage keine CPU-Threads verbraucht werden die nur Warten, sondern aufgrund des Begin-/EndExecuteReader die Ausführung asynchron erledigt wird und nur am Ende der Abfrage IO-Abschlussthreads verwendet werden.

Mit den Tasks ist es auch möglich mit der FromAsync-Methode daraus einen Task zu erstellen, so dass mit dem so erstellen Task ganz normal weitergearbeiten werden kann (z.B. durch ContinueWith und damit die Ergebnisse anzeigen lassen).

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"