© StonePictures/Shutterstock.com
Anomalieerkennung in Echtzeit mit Kafka und Isolation Forests

Finde die Ausreißer


Anomalien – oder auch Ausreißer – sind in Daten allgegenwärtig. Sei es durch Messfehler der Sensoren, unerwartete Ereignisse in der Umwelt oder fehlerhaftes Verhalten einer Maschine. In vielen Fällen ist es sinnvoll, solche Anomalien in Echtzeit zu erkennen, um unmittelbar darauf reagieren zu können. Das nötige Rüstzeug dafür gibt uns die Data-Streaming-Plattform Apache Kafka sowie die Python-Bibliothek scikit-learn an die Hand.

Anomalien in Datenreihen zu erkennen, kann in vielen Kontexten wertvoll sein: vom vorausschauenden Warten über das Monitoren von Ressourcenverbräuchen bis zur IT-Sicherheit. Bei der Erkennung spielt auch der Faktor Zeit eine Rolle: Je früher die Anomalie erkannt wird, desto besser. Ideal ist es, die Anomalien in Echtzeit und direkt nach dem Auftreten zu erkennen. Das kann mit wenigen Tools realisiert werden. Im Folgenden schauen wir uns Kafka, Docker und Python mit scikit-learn genauer an. Die komplette Implementierung der aufgeführten Codefragmente kann unter [1] gefunden werden.

Apache Kafka

Der Kern von Apache Kafka ist eine einfache Idee: ein Log, an das Daten beliebig angehängt werden können. Dieses fortlaufende Log nennt man dann einen Stream. Auf der einen Seite können sogenannte Producer Daten in den Stream schreiben, auf der anderen Seite können die Consumer diese Daten auslesen. Diese Einfachheit macht Kafka zugleich sehr mächtig und für viele Einsatzzwecke verwendbar. Beispielsweise können Sensordaten direkt nach der Messung in den Stream gesendet werden. Auf der anderen Seite kann eine Anomalieerkennungssoftware die Daten auslesen und verarbeiten. Wieso sollte sich aber überhaupt zwischen Datenquelle (Sensoren) und der Anomalieerkennung ein Stream befinden, anstatt die Daten direkt zur Anomalieerkennung zu senden?

Hierfür gibt es mindestens drei gute Gründe. Erstens kann Kafka verteilt in einem Cluster betrieben werden und hohe Ausfallsicherheit bieten (vorausgesetzt, dass es tatsächlich in einem Cluster von Servern läuft und im Fehlerfall ein anderer Server die Arbeit übernehmen kann). Falls die Anomalieerkennung ausfallen sollte, kann nach einem Neustart der Stream weiterverarbeitet und dort weitergemacht werden, wo zuletzt aufgehört wurde. Es gehen also keine Daten verloren. Zweitens bietet Kafka Vorteile in dem Szenario, wenn ein einzelner Container für die Anomalieerkennung in Echtzeit nicht schnell genug arbeitet. In diesem Fall würde ein Load Balancing zur Verteilung der Daten benötigt werden. Kafka löst dieses Problem durch Partitionen. Jeder Stream kann auf mehrere Partitionen (die auf potenziell mehreren Servern zur Verfügung stehen) aufgeteilt werden. Eine Partition wird dann einem Consumers zugeordnet. So können mehrere Consumer (auch Consumer Group genannt) an denselben Stream andocken. Damit lässt sich die Last zwischen mehreren Consumer verteilen. Drittens sei hier aufgeführt, dass Kafka eine Entkopplung der Funktionalitäten ermöglicht. Sollen die Sensordaten beispielsweise zusätzlich in einer Datenbank abgespeichert werden, kann das über eine zusätzliche Consumer-Gruppe realisiert werden, die sich an den Stream andockt und die Daten in der Datenbank ablegt. Daher haben Unternehmen wie LinkedIn, das Kafka ursprünglich entwickelt hat, Kafka zum zentralen Nervensystem erklärt, durch das alle Daten hindurchgeschleust werden.

Ein Kafka-Cluster kann problemlos mit Hilfe von Docker gestartet werden. Dafür eignet sich eine Docker-Compose-Datei [2]. Sie ermöglicht das Starten von mehreren Docker-Containern gleichzeitig. Dabei wird auch ein Docker-Netzwerk erstellt (hier mit Namen kafka_cluster_default), dem alle Container automatisch beitreten und das somit ihre Kommunikation ermöglicht. Mit den folgenden Kommandos wird das Cluster von der Kommandozeile aus gestartet (die Kommandos befinden sich zum Kopieren auch in der README.md im GitHub Repository):

git clone https://github.com/NKDataConv/anomalie-erkennung.git cd anomalie-erkennung/ docker-compose -f ./kafka_cluster/docker-compose.yml up -d --build

Das Kafka-Cluster besteht hier aus drei Komponenten:

  1. Der Broker ist das Herzstück und beinhaltet und verwaltet den Stream.

  2. ZooKeeper ist ein eigenständiges Tool und wird bei Kafka zur Koordinierung von mehreren Brokern eingesetzt. Auch wenn nur ein Broker gestartet wird, wird ZooKeeper dennoch benötigt.

  3. Die Schema Registry ist ein optionaler Bestandteil, hat sich allerdings als Best Practice im Zusammenhang mit Kafka etabliert.

Die Schema Registry löst folgende Problematik: In der Praxis sind die Verantwortlichkeiten für den Producer (also der Datenherkunft) häufig losgelöst von den Zuständigkeiten für den Consumer (also der Datenverarbeitung). Um diese Zusammenarbeit reibungslos zu gestalten, etabliert die Schema Registry eine Art Vertrag zwischen den beiden Parteien. Dieser Vertrag beinhaltet ein Schema für die Daten. Falls die Daten nicht dem Schema entsprechen, erlaubt die Schema Registry das Hinzufügen zum entsprechenden Stream nicht. Die Schema Registry überprüft also bei jedem Versenden die Einhaltung des Schemas. Dieses Schema dient gleichzeitig zur Serialisierung der Daten. Dabei handelt es sich um das Avro-Format. Die Serialisierung mit Avro erlaubt eine Weiterentwicklung des Schemas, beispielsweise das Hinzufügen von zusätzlichen Datenfeldern. Die Abwärtskompatibilität des Schemas wird dabei stets sichergestellt. Ein weiterer Vorteil der Schema Registry in Zusammenarbeit mit Avro ist, dass die Daten im Kafka Stream ohne das Schema landen, da es in der Schema Registry hinterlegt ist. Dadurch befinden sich im Stream nur die Daten an sich. Im Gegensatz dazu müsste beispielsweise beim Versenden der Daten im JSON-Format bei jeder Nachricht die Bezeichnungen für alle Felder mitgesendet werden. Das macht das Avro-Format für Kafka sehr effizient.

Um das Kafka-Cluster zu testen, können wir Daten von der Kommandozeile in den Stream schicken und mit einem Kommandozeilen-Consumer wieder auslesen. Dazu legen wir zuerst einen Stream an. Bei Kafka wird ein einzelner Stream auch als Topic bezeichnet. Der Befehl dafür besteht aus zwei Teilen. Zuerst muss ein Umweg über die Docker-Compose-Datei genommen werden, um Kafka anzusprechen. Der für Kafka wichtige Befehl startet mit kafka-topics. Im Folgenden wird das Topic test-stream angelegt:

docker-compose -f kafka_cluster/docker-compose...

Neugierig geworden?

Angebote für Teams

Für Firmen haben wir individuelle Teamlizenzen. Wir erstellen Ihnen gerne ein passendes Angebot.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang