LMAX Disruptor

Einhänge-Punkt


Die Sensor-Daten werden in den Hook-Implementierungen (Platform-Sensoren nicht berücksichtigt) erhoben und an den CoreService überreicht. Zukünftig könnte LMAX den CoreService (bzw. Teile davon) ersetzen und als Empfänger/Verarbeiter der Sensor-Daten fungieren. Die Applikations-Threads würden in diesem Scenario die Producer darstellen und während der Ausführung der "secondAfterBody"-Methode eines Hooks die Sensor-Daten an den RingBuffer übergeben.

Berücksichtigung der Design Goals:

  • Sensor-Daten werden direkt gedropt wenn der RingBuffer voll ist. Retries werden nicht versucht, da...
    • erhöhen die Zeit um die Sensor-Daten zu erheben (im Worst-Case muss nach Retries ebenfalls gedropt werden -> Netzstrecke unterbrochen / Firewall geschlossen)
    • erhöhen den Druck auf den ohnehin bereits unter Last stehenden RingBuffer


Wie/Welche Daten werden an den RingBuffer übergeben


Um möglichst wenig Garbage zu erzeugen, werden die Elemente im RingBuffer vorab allokiert und zur Laufzeit nur überschrieben. Daher kann der RingBuffer nur Objekte der gleichen Klasse aufnehmen. inspectIT hat für Sensor-Daten verschiedene Klassen die ohne Anpassungen nicht in denselben RingBuffer geschrieben werden können.

Dieses Thema ist auch in folgenden Quellen diskutiert:


Möglichkeiten zur Umsetzung

Nachfolgend betrachten wir welche Daten wir in welcher Form zur Benutzung in LMAX verwenden können. Vor- und Nachteile wurden unter Berücksichtigung der Design Goals betrachtet.


  • neues Daten Model -> the way to go (-> https://inspectit-performance.atlassian.net/wiki/display/VI/Invocation+trace+restructuring)
  • Ableitende Klassen von DefaultData direkt verwenden

    (plus)Objekte der Sensordaten-Klassen könnten direkt verwendet werden
    (minus)

    für jede Sensordaten-Klasse wird ein eigener RingBuffer benötigt

    • jeder RingBuffer benötigt einen Consumer -> Erhöhung der Threads
    • RingBuffer Sizing schwierig

    Erweiterungen schwierig / aufwendig / teuer

    • LMAX Klassen implementieren (question)
    • zusätzlicher RingBuffer
    • zusätzlicher Consumer-Thread
  • DefaultData-Monster-Class (Merge aller Sensor-Klassen in eine Klasse -> optimierbar durch Generierung

    (plus)Lösung verwendet nur einen RingBuffer (1 Consumer, RingBuffer Sizing einfacher)
    Implementierung kann aller Voraussicht nach mit fast keinem Garbage implementiert werden
    (warning)Erweiterbarkeit sollte durch Generationsansatz sichergestellt werden können (neue SensorDaten-Klasse -> Generator erstellt alle Hilfsklassen)
    (minus)
    • RingBuffer Element größer, da ein Element alle Ausprägungen von DefaultData kapselt => pro neuer Ausprägung steigt der Speicherbedarf
    • wirkt unsauber aus Sicht von OO
    • Generatoren und Transformatoren müssen erstellt
    • potentiell versenden wir größere Objekte (womöglich ist dies aber auch gar nicht der Fall, da wir vor Serialisierung das Objekt verkleinern können (-> kann Behoben werden)
  • Serialisierte Objekte der Sensordaten-Klassen

    (plus)
    • Lösung verwendet nur einen RingBuffer (1 Consumer, RingBuffer Sizing einfacher)
    • wirkt im Vergleich zu "DefaulData-Monster-Class als "saubere Lösung
    • einfach erweiterbar (Serialisierung muss sowieso erstellt werden)
    (minus)
    • der Applikations-Thread muss die Serialisierung vornehmen => Beeinflussung der Applikation erhöht (Impact unbekannt)
    • die Serialisierung wird nur verwendet um jegliches Objekt Garbage free im RingBuffer benutzen zu können
      • allerdings würden wir den Garbage dann wie bisher in den Hooks vor der Serialisierung erzeugen

Allgemeines Problem:

Unterschiedliche Größe der Objekte (vor allem durch Strings)

In den StackOverflow Antworten wird darauf hingewiesen, dass man wenn die fixed size des byte arrays nicht ausreicht temporär eine Erweiterung vornehmen kann und diese dann wieder zurück setzt