ZURÜCK zur Blogliste
Learn About

DecisionRules Performance: Reale Latenz- und Durchsatzwerte aus unseren Lasttests

Zwei k6-Lasttests, 23,1 Millionen Anfragen, keine Ausfälle. Hier sind die gemessenen Latenzperzentile und Durchsatzwerte für DecisionRules auf Kubernetes — einschließlich des Punkts, an dem die Leistung nachlässt.

DecisionRules Performance: Reale Latenz- und Durchsatzwerte aus unseren Lasttests hero image

Die meisten Leistungsversprechen auf dem Markt für Regel-Engines sind nicht überprüfbar. „Antwortzeiten unter einer Sekunde.“ „Massive Skalierung.“ „Durchsatz auf Enterprise-Niveau.“ Nichts davon sagt Ihnen, was Sie in einen Kapazitätsplan aufnehmen sollen.

Dieser Artikel macht das Gegenteil. Nachfolgend finden Sie die gemessenen Ergebnisse von zwei k6-Lasttests für DecisionRules auf Kubernetes, einschließlich der Testbedingungen, der Perzentilverteilungen und des exakten Punkts, an dem sich die Latenz verschlechtert. Jede Zahl lässt sich anhand der k6-Rohberichte reproduzieren und bezieht sich auf die Konfiguration, die sie erzeugt hat.

Kurz gesagt: Eine einzelne Geschäftsregel mittlerer Komplexität wird im Durchschnitt in unter 10 Millisekunden aufgelöst und bleibt bis zu rund 8.900 Regelauflösungen pro Sekunde unter 10 ms. Bei maximalem Durchsatz verarbeitet dieselbe Plattform mehr als 15.000 Regelauflösungen pro Sekunde bei einer durchschnittlichen Latenz von nur 13,1 Millisekunden. Durchsatz und Latenz stehen nicht in dem Zielkonflikt, den die meisten erwarten — sofern die Bereitstellung horizontal skalieren kann.


Zusammenfassung der verifizierten Kennzahlen

MetrikWertBedingungen
Durchschnittliche Latenz, einzelne Entscheidungstabelle 8.1 ms ~5.200 Regelauflösungen/s, 50 gleichzeitige Clients
Durchschnittliche Latenz, einzelner Entscheidungsbaum 8.2 ms ~5.200 Regelauflösungen/s, 50 gleichzeitige Clients
Durchschnittliche Latenz, Flow-Regel mit 3 Tabellen 12.1 ms ~5.200 Regelauflösungen/s, 50 gleichzeitige Clients
Gemittelte durchschnittliche Latenz, moderate Last 9.5 ms ~5.200 Regelauflösungen/s, alle Regeltypen
Gemittelte durchschnittliche Latenz, maximaler Durchsatz 13.1 ms ~15.200 Regelauflösungen/s, 200 gleichzeitige Clients
p95-Latenz, maximaler Durchsatz 29.0 ms ~15.200 Regelauflösungen/s, 200 gleichzeitige Clients
Nachhaltiger Durchsatz, elastische Skalierung ~15,200 Regelauflösungen/s 200 gleichzeitige Clients, HPA-Limit 11 Replikate
Nachhaltiger Durchsatz, auf 5 Replikate begrenzt ~9,800 Regelauflösungen/s 200 gleichzeitige Clients, HPA-Limit 5 Replikate
Anfragen insgesamt über beide Läufe 23,170,203 ~42 Minuten kombinierte Testzeit
Fehlgeschlagene Anfragen über beide Läufe 0 Fehlerrate 0,000 %

Alle Latenzwerte sind vom Client beobachtete Round-Trip-Zeiten (http_req_duration in k6) — einschließlich der Netzwerkübertragung zum Ingress und zurück, nicht nur der serverseitigen Ausführung.

Was wir getestet haben — und wie

Beide Läufe verwendeten k6 zur Ansteuerung der DecisionRules-Rule Solver API über HTTP gegen DecisionRules auf Kubernetes mit einem Horizontal Pod Autoscaler. Die Lastgeneratoren liefen in derselben Region wie der Cluster. Die Antwortvalidierung war für jeden Aufruf aktiviert: Eine Anfrage zählt nur dann als erfolgreich, wenn sie HTTP 200 zurückgibt und die Entscheidungsantwort eine Inhaltsprüfung besteht. Bei 23,1 Millionen Aufrufen waren 100 % der Prüfungen erfolgreich.

Jede k6-Iteration führte eine Geschäftstransaktion aus, bestehend aus drei separaten Rule-Solver-Aufrufen:


RegelTypKomplexität
Regel 1 Entscheidungstabelle, 20 Zeilen Mittel
Regel 2 Entscheidungsbaum Mittel
Regel 3 Flow — führt drei Entscheidungstabellen aus und berechnet anschließend Zusammenfassungen über deren kombinierte Ergebnisse Höher

Diese Zusammenstellung ist bewusst gewählt. Regel 1 und 2 stehen für den alltäglichen Fall: eine einzelne, in sich geschlossene Entscheidungslogik. Regel 3 steht für einen orchestrierten Entscheidungsprozess, bei dem ein API-Aufruf mehrere Regeln und eine Nachverarbeitung auslöst. Beide im selben Lauf zu testen, ermöglicht es uns, die Kosten für das Auflösen einer Regel von den Kosten für die Orchestrierung eines Prozesses.

k6 meldet Iterationen pro Sekunde, und jede Iteration entspricht hier drei Solver-Aufrufen. Alle Durchsatzwerte in diesem Artikel wurden in Regelauflösungen pro Sekunde umgerechnet.

Die Nutzlasten waren realistisch, aber nicht groß: rund 422 Byte Eingabe-JSON pro Aufruf und 1,2 KB Entscheidungsantwort pro Antwort.

Die Anzahl virtueller Benutzer wurde in den Schritten 50 → 100 → 150 → 200 erhöht; jede Stufe wurde fünf Minuten gehalten, damit sich der Autoscaler vor den Messungen stabilisieren konnte. Die beiden Läufe waren in jeder Hinsicht identisch, außer beim Autoscaler-Limit — 11 Replikate im einen, 5 im anderen.


Normale Last: Einzelne Regeln werden in unter 10 Millisekunden aufgelöst

Bei 50 gleichzeitigen Clients — einem nachhaltigen Durchsatz von 5.243 Regelauflösungen pro Sekunde, was bereits erheblichen Produktionsverkehr darstellt — ergeben sich pro Regel folgende Werte:

RegelDurchschnittMedianp90p95p99
Entscheidungstabelle (20 Zeilen) 8.1 ms 6.9 ms 13.0 ms 14.8 ms 18.1 ms
Entscheidungsbaum 8.2 ms 6.8 ms 13.4 ms 15.2 ms 18.7 ms
Flow (3 Tabellen + Berechnungen) 12.1 ms 10.2 ms 19.4 ms 21.3 ms 25.1 ms
Gemittelt, alle Aufrufe 9.5 ms 8.4 ms 16.2 ms 18.4 ms 22.9 ms

Eine Entscheidungstabelle oder ein Entscheidungsbaum mittlerer Komplexität wird in durchschnittlich rund 8 Millisekunden und im Median unter 7 Millisekunden aufgelöst, clientseitig gemessen einschließlich Netzwerk-Round-Trip. Zwei Drittel dieser Zeit entfallen auf das Auflösen der Regel; der Rest auf HTTP und Netzwerkübertragung.

Der Wert von unter 10 Millisekunden ist kein Artefakt geringer Last. Er bleibt auch bei steigendem Durchsatz erhalten:


DurchsatzEntscheidungstabelle (Durchschnitt)Entscheidungsbaum (Durchschnitt)Unter 10 ms?
5,243 Regelauflösungen/s 8.1 ms 8.2 ms Ja
8,908 Regelauflösungen/s 9.6 ms 9.7 ms Ja
12,302 Regelauflösungen/s 10.3 ms 10.6 ms Median weiterhin unter 10 ms
15,215 Regelauflösungen/s 11.1 ms 11.5 ms Nein — 11 ms

Die durchschnittliche Latenz einer einzelnen Regel bleibt bis ungefähr 8.900 Regelauflösungen pro Sekunde unter 10 Millisekunden, und der Median bleibt bis ungefähr 12,300 solves per second unter 10 Millisekunden. Erst bei der höchsten getesteten Last benötigt eine einzelne Regel mehr als 11 Millisekunden.

Wenn Ihre Arbeitslast von einzelnen Entscheidungstabellen und -bäumen statt von mehrstufiger Orchestrierung dominiert wird, ist eine durchschnittliche Antwortzeit unter 10 Millisekunden eine realistische Erwartung und nicht nur der Bestfall.

Die Kosten der Flow-Regel

Die Flow-Regel — drei Entscheidungstabellen plus Zusammenfassungsberechnungen hinter einem API-Aufruf — benötigte bei moderater Last durchschnittlich 12,1 ms und bei maximalem Durchsatz 16,6 ms. Gegenüber einer einzelnen Tabelle bei derselben Last ist das ein konstanter Faktor von 1,5×, der über alle getesteten Parallelitätsstufen stabil bleibt.

Dieses Verhältnis ist der interessante Teil. Der Flow verrichtet mindestens die dreifache Regelauflösungsarbeit einer einzelnen Entscheidungstabelle und aggregiert zusätzlich die Ergebnisse — bei etwa der anderthalbfachen Latenz. Würden diese drei Tabellen als drei separate Solver-API-Aufrufe ausgeführt, kostete das bei maximalem Durchsatz rund 33 Millisekunden: drei Round-Trips, drei HTTP-Verbindungen, drei Netzwerkübertragungen. Die Orchestrierung in einem Flow kostet 16,6 ms.

Die Konsolidierung mehrstufiger Entscheidungslogik in einem Flow ist ungefähr doppelt so schnell wie der einzelne Aufruf der Regeln aus Ihrer Anwendung.


Maximaler Durchsatz: 15.200 Regelauflösungen pro Sekunde

Erhöhung der Parallelität bei einer Bereitstellung, die auf 11 Replikate skalieren darf:


Gleichzeitige ClientsNachhaltiger DurchsatzMedianDurchschnittp90p95p99
50 5,243 Regelauflösungen/s 8.4 ms 9.5 ms 16.2 ms 18.4 ms 22.9 ms
100 8,908 Regelauflösungen/s 9.4 ms 11.2 ms 19.4 ms 23.1 ms 29.1 ms
150 12,302 Regelauflösungen/s 10.5 ms 12.1 ms 22.3 ms 27.2 ms 35.2 ms
200 15,215 Regelauflösungen/s 11.9 ms 13.1 ms 24.1 ms 29.0 ms 37.9 ms

Betrachten Sie die erste und letzte Zeile zusammen. Der Durchsatz stieg um 2.9×. Die durchschnittliche Latenz stieg um 3,6 Millisekunden. Die Medianlatenz stieg um 3,5 Millisekunden.

Das kommt einer linearen Skalierung nahe. Jeder Parallelitätsschritt von 50 Clients brachte rund 3.400 zusätzliche Regelauflösungen pro Sekunde, und die zusätzliche Latenz pro Schritt blieb unter 2 ms. Das System skalierte beim Ende des Tests noch immer — 15.215 Regelauflösungen/s ist die höchste von uns gemessene Rate, nicht ein ermitteltes Limit.

Nachhaltig entspricht diese Rate 54,8 Millionen Entscheidungen pro Stunde oder 1,31 Milliarden pro Tag. Bei allen 12.756.996 Aufrufen dieses Laufs schlug keine Anfrage fehl.

Latenz der vollständigen Transaktion

Da jede Iteration alle drei Aufrufe nacheinander ausführte, misst der Lauf auch die vollständige Geschäftstransaktion:


DurchsatzDurchschnitt der TransaktionMedianp95p99
5,243 Regelauflösungen/s 28.6 ms 24.3 ms 47.9 ms 53.5 ms
8,908 Regelauflösungen/s 33.7 ms 29.6 ms 62.2 ms 68.2 ms
12,302 Regelauflösungen/s 36.6 ms 35.1 ms 76.2 ms 82.8 ms
15,215 Regelauflösungen/s 39.4 ms 37.9 ms 82.4 ms 90.5 ms

Ein vollständiger Entscheidungsprozess — eine Entscheidungstabelle, ein Entscheidungsbaum und ein Flow mit drei Tabellen, sequenziell als drei API-Aufrufe ausgeführt — wird in 28,6 ms bei moderater Last und 39,4 ms bei maximalem Durchsatz. Die Transaktionslatenz folgt nahezu exakt der Summe ihrer Bestandteile. Der Overhead mehrerer sequenzieller Solver-Aufrufe ist also vernachlässigbar; die Kosten entstehen durch die Regeln selbst.


Die Konfiguration, die gesättigt war — und warum wir sie zeigen

Der zweite Lauf war in jeder Hinsicht identisch, mit einer Ausnahme: Das Autoscaler-Limit war auf 5 statt 11 Replikate. Dies ist das aufschlussreichste Ergebnis des Tests.


Gleichzeitige ClientsHPA max. 5HPA max. 11Durchsatzdifferenz
50 5,529 Regelauflösungen/s 5,243 Regelauflösungen/s
100 9,115 Regelauflösungen/s 8,908 Regelauflösungen/s
150 9,540 Regelauflösungen/s 12,302 Regelauflösungen/s - 23%
200 9,794 Regelauflösungen/s 15,215 Regelauflösungen/s - 36%

Und die entsprechende Latenz:

Gleichzeitige ClientsDurchschn. (max. 5)Durchschn. (max. 11)p95 (max. 5)p95 (max. 11)
50 9.0 ms 9.5 ms 15.1 ms 18.4 ms
100 10.9 ms 11.2 ms 22.2 ms 23.1 ms
150 15.7 ms 12.1 ms 27.9 ms 27.2 ms
200 20.3 ms 13.1 ms 35.4 ms 29.0 ms

Bis zu 100 gleichzeitige Clients sind die beiden Konfigurationen nicht zu unterscheiden — die begrenzte Bereitstellung ist sogar geringfügig schneller, weil fünf Replikate ausreichten und die Anfragen gleichmäßiger verteilt wurden. Danach gehen sie deutlich auseinander. Die begrenzte Bereitstellung erreicht bei rund 9.800 Regelauflösungen/s ihr Limit und steigert den Durchsatz nicht weiter; zusätzliche Last führt zu Warteschlangen, und die durchschnittliche Latenz mehr als verdoppelt sich von 9,0 ms auf 20,3 ms. Die Latenz einer einzelnen Regel verschlechtert sich entsprechend von 7,6 ms auf 17,4 ms.

Es lohnt sich, es klar auszusprechen: Die begrenzte Bereitstellung ist nicht ausgefallen. Bei 10,4 Millionen Anfragen gab es keine Fehler, p99 lag weiterhin unter 47 ms und alle konfigurierten Latenzschwellen wurden eingehalten. Sie wurde lediglich nicht mehr schneller.

Eine Regel-Engine, die sich unter Sättigung kontrolliert verhält, ist wohl wertvoller als eine, die nur schnell ist, solange sie nicht an ihre Grenzen stößt. Die Lehre für die Bereitstellung ist jedoch direkt: Wenn Ihre Spitzenlast das Replikatlimit übersteigt, erhöhen Sie das Limit. Die Engine skaliert; die Einschränkung lag hier in der Autoscaler-Konfiguration, nicht in der Software.


So nutzen Sie diese Kennzahlen

Wenn Sie eine Bereitstellung dimensionieren. Der gesättigte Lauf liefert die klarste Kennzahl pro Replikat: Fünf Replikate erreichten ein Plateau bei etwa 9.800 Regelauflösungen/s, also rund 1.950 Regelauflösungen/s pro Replikat bei Sättigung. Für Reserve planen Sie mit ~1.400 Regelauflösungen/s pro Replikat und legen Sie das HPA-Maximum über der resultierenden Anzahl fest, nicht genau darauf. (Pod-Anzahlen wurden in der k6-Ausgabe nicht erfasst; diese Werte sind daher aus den Autoscaler-Limits und nicht aus beobachteten Replikatzahlen abgeleitet.)

Wenn Sie ein Latenz-SLA haben. Für eine einzelne Entscheidungstabelle oder einen Entscheidungsbaum mittlerer Komplexität unter normaler Last sollten Sie 20 ms bei p99, clientseitig in derselben Region gemessen, einplanen. Für einen Flow, der mehrere Tabellen orchestriert, planen Sie 25–41 ms bei p99 je nach Last ein. Für eine Geschäftstransaktion mit drei Aufrufen planen Sie 90 ms bei p99 bei maximalem Durchsatz ein.

Wenn Sie Entscheidungslogik entwerfen. Konsolidieren Sie. Drei einzeln aufgerufene Regeln kosten etwa doppelt so viel wie dieselben drei Regeln, die in einem Flow orchestriert werden, weil Sie den Netzwerk-Round-Trip einmal statt dreimal bezahlen.

Wenn Sie Engines vergleichen. Vergleichen Sie Perzentilverteilungen, nicht Durchschnittswerte. Mit schnellen Idealpfaden lässt sich ein guter Durchschnitt leicht erzielen. Die Spanne von p50 bis p99 zeigt, ob das System Warteschlangen bildet — und Warteschlangen bringen Produktionssysteme zum Scheitern.


Umfang und Einschränkungen

Diese Ergebnisse beschreiben die getesteten Konfigurationen und sollten nicht darüber hinaus verallgemeinert werden:

  • Die Regelkomplexität beeinflusst die Latenz stärker als jeder andere Faktor. Diese Tests verwendeten eine Entscheidungstabelle mit 20 Zeilen, einen Entscheidungsbaum und einen Flow mit drei Tabellen, alle mittlerer Komplexität. Eine Entscheidungstabelle mit 10.000 Zeilen, tief verschachtelte Workflows oder Regeln mit umfangreichem Scripting führen zu anderen Werten.
  • Die Größe der Nutzlast ist relevant. Diese Tests verwendeten Anfragen mit etwa 422 Byte und Antworten mit etwa 1,2 KB. Deutlich größere Nutzlasten verändern sowohl Latenz als auch Durchsatz.
  • Die Netzwerktopologie ist nicht berücksichtigt. Die Lastgeneratoren liefen in derselben Region. Anrufer aus anderen Regionen oder Kontinenten fügen Übertragungszeit hinzu, die nichts mit der Engine zu tun hat.
  • Dies sind keine maximal erreichbaren Werte. Der elastische Lauf skalierte bei seinem Ende noch linear. Wir berichten, was wir gemessen haben, nicht was wir hochrechnen.
  • Die Durchsatzwerte wurden neu berechnet, nicht aus der Anzeige des k6-Dashboards übernommen — aus dem Grund, der oben im Abschnitt „Was wir getestet haben — und wie“ beschrieben wird.

Tests wurden mit k6 gegen DecisionRules auf Kubernetes mit horizontaler Pod-Autoskalierung durchgeführt. Die Latenz wurde als clientseitig beobachtete HTTP-Round-Trip-Zeit (http_req_duration) gemessen. Der Durchsatz wurde aus den Rohzählungen je Intervall neu berechnet. Rohberichte von k6 sind auf Anfrage verfügbar.

Fazit

Jede Zahl hier stammt aus einem k6-Bericht, den Sie reproduzieren können: mit den genannten Bedingungen, veröffentlichten Perzentilen statt verschleiernder Mittelwerte und dem gesättigten Lauf neben demjenigen, der nicht gesättigt war. Genau das ist der Punkt. Ein Benchmark, der nur die Konfiguration zeigt, in der alles gut lief, sagt nichts darüber aus, was passiert, wenn es nicht gut läuft.

Wenn Sie eine Regel-Engine bewerten, verlangen Sie dasselbe. Wenn Perzentilverteilungen und angegebene Bedingungen nicht verfügbar sind, ist das Gezeigte keine Messung.

Um DecisionRules mit Ihren eigenen Regeln und Nutzlasten zu testen, vereinbaren Sie eine Demo oder starten Sie eine kostenlose Testphase.

Ondrej Brejla

Ondrej Brejla

Business Analyst