Ausgangslage

Ein langes Projekt geht zu Ende, über viele Monate wurden Datenquellen angebunden, ein neues Data Warehouse aufgebaut, Analysemodelle erstellt und Reports gebaut – und jetzt können es die Endbenutzer kaum erwarten endlich ihre effizienten, modernen, schnellen und interaktiven Reports mit dem coolen Power BI zu verwenden…

Alles läuft gut, der Ladeprozess schafft es duch die Nacht, das Modell ist ein Power BI Premium Dataset und processed täglich, die komplexen DAX-Berechnungen ergeben immer noch vertretbare Reaktionszeiten im Report.
Aber was passiert, wenn jetzt 1.000 User gleichzeitig zugreifen?
Wird das System zusammenbrechen?
Verwenden wir lieber doch einen AAS (Azure Analysis Services)?
Brauchen wir einen Premium P2?

Also lieber vorher testen…

Aber wie?
Jedenfalls so realistisch wie möglich!
Da sich keine 1.000 Benutzer finden die wie wild für 2 Stunden Berichte aufrufen, wird es wohl ein automatisierter Test sein müssen.

Was wollen wir testen?

Ich habe drei Reports ausgewählt, die sehr intensiv sind, nicht nur die Datenmenge, sondern viele sehr komplexe DAX-Measures in einer Matrix-Liste.

Ziel soll sein, diese Abfrage wenn möglich mit dem Report immer wieder mit verschiedenen Filtern aufzurufen.

Wir begnügen uns mal zunächst mit 100 Usern, wenn das klappt, dann mit 500-700 User gleichzeitig.

Wie sieht das Modell aus?

Das Tabular Model als Premium Dataset ist nicht sehr groß (3 GB), aber recht komplex.

Model
Tabular Model

Wie kann man das testen?

Jetzt wird es interessant, denn dafür gibt es keine fertige Vorgangsweise oder gar ein Tool – es folgen also eine Reihe an teils aufwändigen Fehlschlägen…

Browser Refresh

Einfach den Bericht über den Browser immer wieder aufrufen, Filter ändern, erneut aufrufen.
Das kann man durchaus bauen, z.b. mit Javascript.
Aber für 100 Browser Instanzen oder gar 500?
Das konnte nur schief gehen, da ist der Client bei 30 Browser-Fenstern schon am Ende, letztendlich mißt man das Verhalten des Clients und nicht des Reports und 100 VMs einrichten wollte ich auch nicht.

Testing Tool JMeter

Da war ich gleich begeistert, man kann alles gut konfigurieren, bestimmen was man mitsendet, Filter austauschen, Interationen festlegen und auch die Parallelisierung einstellen.

Aber leider wird hier nur der Web-Traffic gemessen, d.h. die Query wird gar nicht angestossen und das HTML-Rendering des Berichts auch nicht.
Es wurde also bewiesen, dass man 100 mal parallel zur Report-URL und zurück kommt, nicht ganz das wir wir möchten…

Kompromiss DAX Query

Ich verwerfe also mal die Idee den Report als ganze Visualisierung zu testen und beschränke mich auf die Query.
Aus Power BI ermittle ich von der komplexen Matix das DAX-Statement und zerlege es in zwei Teile, damit ich einen Filter dazwischen immer auswechseln kann, da sonst der Cache zu leichtes Spiel hat, dazu ermittle ich noch 10 verschiedene Filterbedingungen die auch Daten bringen.

DAX mit dynamischen Filter für Jahr/Monat

Der Test bezieht sich jetzt also nicht mehr auf die ganze Reportseite, sondern nur ein Visual und auch die Renderzeit entfällt – die Query macht aber 90% der Ladezeit aus.

Wie fragt man nun eine DAX-Query automatisiert ab und erhält das Ergebnis?

PowerShell

Das ist bestimmt möglich, sich gegen das Premium Dataset anzumelden, mit XMLA zu hantieren und auch DAX zu senden und sicher kann man dann auch Schleifen programmieren und auch die Zeit messen, bleibt nur mehr die Frage ob 500 PowerShell gleichzeitig laufen können…

Wer mich kennt, weiß: ich versuche so lange es geht, ohne Code auszukommen…
Also habe ich einen anderen Weg zuerst versucht.

Integration Services (SSIS)

Nachdem SSIS bereits verwendet wird im Projekt und SSIS ein guter alter Bekannter von mir ist, habe ich einmal drei Pakete gebaut für die drei verschiedenen fachlichen Reports/Queries, dabei in einer Loop 10 Filter rotieren lassen mit 10 sec. Pause und das ganz noch 10 fach parallelisiert, leicht zeitversetzt.

Der Aufwand war gering, die Infrastruktur in der Azure Datafactory und die Netzwerkeinbindung stand auch schon zur Verfügung.

Mit den Loops und Parallelisierung kommt man bei 3 unterschiedlichen Queries mal auf maximal 30 gleichzeitige “User”.

SSIS “Masteloop”

Nachdem die parallelisierten Filterabfragen laufen, muss man ja das nurmehr vervielfachen, also habe ich ein Masterpaket erstellt, dass diese ganze Logik mehrmals aufruft und zwar so, dass es sich langsam steigert, also zeitlich versetzter Start.

Damit sollte man auf 100 User kommen.

Doch an dieser Stelle geht gar nichts mehr…

Die meisten Jobs beginnen erst gar nicht mehr zu laufen, alles steckt, es wird unkontrollierbar – denn jetzt wird wieder die Laufzeitumgebung gemessen anstatt der Reports.

Die erste Maßnahme ist die Integration Runtime ordentlich aufzublasen von einer D4 auf eine D16 mit 4 Nodes.

Aber auch das hilft nicht, denn das Problem liegt auch in SSIS, die zeitgesteuerte Parallelisierung funktioniert mit den Script-Tasks nicht mehr, wil die Zeitgebung nicht akurat ist und das Paket selbst so beschäftigt ist, dass die Timer nicht funktionieren.

Azure Datafactory mit SSIS

Ich bleibe im Kern bei SSIS, denn dort kann man bequem DAX abfragen, aber die Steuerung verlagere ich in die ADF.

ADF funktioniert perfekt, mit einer starken IR.


Nachdem 100 parallel ohne Fehler über 2 Stunden laufen, traue ich mich das nochmals zu kapseln und mehrfach zu parallelisieren, womit man thoeretisch auf 750 gleichzeitige Queries kommt.

ADF pipeline Masterbatch

Das Ergebnis

Nach einigen Durchläufen mit jeweils 1 bis 2 Stunden können die Logs analysiert werden.

Wenn das nur so einfach wäre…
Mehr dazu im Teil 2