Interaktive Kundenkarte - Apache Spark Streaming und Yandex.Maps

    Bigdata drängt. Es reicht für Unternehmen nicht mehr aus, jeden Abend gesammelte Daten zu verarbeiten und Entscheidungen mit einer Verzögerung von einem Tag zu treffen. Sie möchten, dass das System Daten online analysiert und schnell auf Folgendes reagiert:
    • Änderung von Anführungszeichen
    • Benutzeraktionen in einem Online-Spiel
    • aggregierte Informationen aus sozialen Netzwerken in verschiedenen Projektionen angezeigt

    usw. Wenn Sie nicht wissen, wie, werden Smoothies nicht mehr gegossen.


    Immer öfter hören wir von Lambda-Architektur . Sie wollen zunehmend Online -Datenclustering . Wir hören immer mehr über den Einsatz von Online-Maschinellem Lernen (Umschulung). Die Wache


    Sie können anfangen, sich die Haare vom Kopf zu reißen, oder vielmehr müssen Sie methodisch trainieren, ein Verständnis für Technologien und Algorithmen entwickeln und in der Praxis unter Bedingungen eines "harten Kampfes" und hoher Belastung nützliche und effektive technologische Lösungen von akademischen Theorien trennen.

    Heute erzähle ich Ihnen, wie wir mithilfe von Apache Spark Streaming und der Yandex.Maps-API eine interaktive Karte unserer Kunden erstellt haben. Aber lassen Sie uns zunächst die architektonischen Ansätze wiederholen und die verfügbaren Werkzeuge in der Tat kurz durchgehen.

    Datenverarbeitungsansätze


    Dieses Problem ist über 50 Jahre alt. Unter dem Strich gibt es ungefähr zwei grundlegende Ansätze für die Verarbeitung großer Informationsmengen - Datenparallelismus und Aufgabenparallelismus .

    Im ersten Fall wird dieselbe Berechnungskette parallel über nicht zusammenhängende unveränderliche Teile der Quelldaten gestartet. Nach diesem Prinzip arbeiten Apache Spark und Hadoop MapReduce.
    Im zweiten Fall ist das Gegenteil der Fall: Mehrere Berechnungsketten werden parallel für ein Datenelement ausgeführt: Das beliebte Apache Spark Streaming , Apache Storm und, mit etwas Dehnung, Apache Flume arbeiten nach diesem Prinzip .

    Es ist sehr wichtig, diese Konzepte zu verstehen, da Systeme für die Stapel- und Streaming-Datenverarbeitung aufgrund ihrer relativen Einfachheit bereits eine Reihe von Pilzen nach dem Regen hervorgebracht haben, was natürlich Anfänger verwirrt.


    Tatsächlich implementiert das Apache Spark Streaming (dank UC Berkeley und DataBricks), das Apache Storm (danke, Twitter) das Konzept der Streaming-Datenverarbeitung in der Task Parallel-Architektur, jedoch ging das Spark Streaming noch weiter und ermöglicht es Ihnen, ein Paket (diskretisiertes RDD) auch parallel zu verarbeiten Daten parallel. Mit dieser Funktion können Sie das Online-Clustering des Pakets auf einfache Weise „beschleunigen“ - wir gruppieren die Daten zu Visualisierungszwecken in Clustern, laden die Mädchen zum Abendessen ein ... das meine ich also.


    So funktioniert Apache Spark Streaming


    Sie können die Dokumentation selbst lesen. Ich erkläre das Wesentliche nur mit 2-3 Worten. Ich hasse Populismus, Klugheit und das Jonglieren mit unbekannten Begriffen - ich möchte, dass Wissen in einer einfachen, zugänglichen Sprache vermittelt wird und der Transferprozess Spaß macht. Sie erfassen Daten, die mehrmals pro Sekunde eingehen:

    und wo immer die Seele will. Der Einfachheit halber werden Daten optimiert. Sie müssen jedes Datenelement verarbeiten:
    • Addiere einen Treffer zu den gesamten Treffern pro Tag
    • Clientkoordinate nach IP-Adresse registrieren
    • Senden Sie dem Benutzer eine Push-Benachrichtigung über den Vorgang


    Spark Streaming sammelt Datenelemente in einer geordneten unveränderlichen RDD für ein bestimmtes festes Zeitintervall (z. B. 10 Sekunden) und ruft Ihren Handler auf, wobei die RDD an die Eingabe übergeben wird. RDD ist nur eine Sammlung von Daten, die über ein Intervall gesammelt wurden, nicht mehr.
    Wenn es Ihnen gelungen ist, eine ziemlich große RDD während des Intervalls zu erfassen, sollten Sie versuchen, sie zu verarbeiten, bevor die nächste RDD für das nächste Intervall eintrifft. Daher ist es sinnvoll, RDD auf mehreren Servern in einem Cluster parallel zu verarbeiten. Je größer der Eingabedatenstrom ist, desto mehr Server werden dem Stream-Cluster hinzugefügt. Ich hoffe ich habe alles klar verstanden.

    Und wenn alles fiel? Ein Teil des Clusters ist abgefallen. In Ihrem Paket-Handler ist eine Nullzeiger-Ausnahme aufgetreten.


    Koscher und orthodoxe Nachrichtenwarteschlangenarchitekturen


    Ein kleiner Arcadeeinsatz. Vor nicht allzu langer Zeit, als RabbitMQ oder ZeroMQ erwähnt wurden, herrschte Stille, und eine Gruppe von Entwicklern, Architekten und ein zufällig verlorener Programmierer waren beeindruckt. Und erfahrene Kämpfer mit Überlebenserfahrung im Unternehmen erinnerten sich an Message-orientierte Middleware und vergossen eine Träne.

    Aber, wie wir zu Beginn des Beitrags sagten, pusht Bigdata. Und er tut es grob und kurzerhand. Zunehmend stellen wir fest, dass die Architektur von Nachrichtenwarteschlangen, in denen die Verbraucher zentral auf den Servern der Warteschlangen koordiniert und gemultiplext werden, "nicht koscher" wird, weil Wenn die Last und die Anzahl der Clients zunimmt, wird es für sie schlimm (dennoch müssen Sie alle Kontexte mit den Leistungsindikatoren aller Clients aufrechterhalten und die Sockets für die Verarbeitung durchlaufenauswählen / bündeln und anderen Sadomasochismus betreiben). Und die "orthodoxe" Architektur wird zunehmend als in Apache Kafka implementiert betrachtet, wo sich jeder Consumer-Client an seine Position in der Warteschlange erinnert und diese beibehält, und der oder die Server nur damit beschäftigt sind, Nachrichten gemäß dem vom Client übertragenen Iterator (oder vielmehr dem in der Datei übertragenen Offset) zu versenden welche Nachrichten auf einer alten, guten, bärtigen Festplatte gespeichert sind). Dies ist natürlich Hack-Arbeit und die Übertragung von Verantwortung auf Kunden - aber ... Bigdata - drückt und es stellte sich heraus, dass die Architektur nicht so verantwortungslos ist. Und sogar Amazon Kinesis nahm es in Dienst. Lesen Sie darüber - nützlich. Nur gibt es viel Text, eine größere Tasse Kaffee einschenken und mit Arabica.


    Notfallwiederherstellung


    Was haben wir dort aufgehört? Alles fiel ... wer, welche Mädchen? Oh, ich erinnerte mich. Wenn also alles schief gelaufen ist, muss der Verbraucher in diesem Fall seine Rolle vom Fahrer (es sind mehrere im Auslieferungszustand), der Nachrichten aus den Warteschlangen abruft, erneut die gespeicherte Position in die Warteschlange übertragen und erneut mit dem Lesen der Nachrichten beginnen. In unserem Fall lesen wir regelmäßig Nachrichten im Spark-Streaming von Amazon Kinesis und der Treiber (ist konfiguriert) speichert die aus der Warteschlange gelesene Position auf der DymanoDB-Platte (diese ist aus der Box erhältlich).

    Wie unser Projekt aufgebaut ist - "Interaktive Kundenkarte"



    Ereignisquellen


    Wenn Kunden mit Bitrix24-Portalen arbeiten, sendet Javascript ein Paket an die Cloud, in dem die Aktion des Kunden, die IP-Adresse und anonymisierte Informationen beschrieben werden, die im persönlichen Empfehlungssystem, in CRM , in Business Analytics und in verschiedenen Modellen des maschinellen Lernens innerhalb des Unternehmens verwendet werden.
    Mehr als 1000 Events finden pro Sekunde statt. Ereignisse versammeln sich bei Amazon Kinesis (das, wie wir uns erinnern, mit "koscherer Architektur").

    Spark-Streaming-Ereignisse


    Um diese> 1000 Ereignisse pro Sekunde zu verarbeiten, wurde ein kleiner Garncluster mit Spark Streaming (2 Maschinen) erstellt. Achten Sie auf die vom Spark-Treiber zugewiesene Speichermenge. Es scheint, dass Sie noch weniger Speicher zuweisen können:


    Noch interessanter ist der folgende Screenshot. Es zeigt, dass es uns gelingt, mehr als 1000 Treffer pro Sekunde zu verarbeiten, bevor das nächste Paket in einem Intervall von 30 Sekunden eintrifft:


    Ja, der Spark-Treiber verbraucht sicher weniger als 200 MB Speicher, also werden wir es jetzt auf ihn beschränken :-):

    Im Allgemeinen können Sie sehen Daß der Speicher ziemlich ausgelastet ist und die gesamte Verarbeitung des Streams problemlos auf 2 Stück Eisen passt, und falls gewünscht, können Sie dies auf einem tun, und niemand wird es bemerken. Cool. Effektive Technologie:> 1000 Ereignisse pro Sekunde auf toter Hardware.

    Ereignisbehandlung


    Nun der lustige Teil. Wir müssen die IP-Adresse jedes Kunden abrufen und ... seine Domain mit einem Punkt auf der Yandex.Map anzeigen, damit der Zoom auf der Karte funktioniert und nichts langsamer wird!

    Um IP-Adressen in Koordinaten zu übersetzen, verwenden wir eine der gängigen Bibliotheken . Ein Problem: Bibliotheksobjekte in Java werden nicht serialisiert, sodass die Übersetzung von IP-Adressen in Koordinaten immer noch in einem einzigen Thread im Spark-Treiber ausgeführt wird. Wenn Sie möchten, können Sie natürlich für jedes Partitions-RDD-Intervall einen eigenen Adress-Resolver auslösen - aber im Moment ist die Leistung für die Augen ausreichend.

    Als nächstes bestimmen wir für jeden Treffer die Projektdomäne und speichern ein Paar in der Hash-Tabelle: Domäne - Koordinaten und Aktualisierungszeit. Paare älter als ein paar Tage - entfernen.

    Datenupload für Yandex.Maps


    In bestimmten Zeitintervallen (konfigurierbar) wird die Bindung von Domänen an Koordinaten entladen, d. H. Zukünftige Punkte auf der Karte in einer JSON-Datei zur weiteren Anzeige auf Yandex.Map. Im Moment gibt es ungefähr 20.000 Punkte.


    Rasterizer-Clustering für Yandex.Maps


    Ich musste mich an javascript erinnern :-). Die Gefahr bei der Anzeige von Punkten auf Yandex.Map stellte sich heraus, dass 20.000 Punkte auf einer Karte mit integriertem Clustering den Browser des Clients erheblich verlangsamen und die Karte für Minuten geöffnet wird. Deshalb haben wir die Gelegenheit des Server-Clusters genutzt - wir haben unseren einfachen Rasterizer-Clusterizer geschrieben, an den wir eine Karte angeschlossen haben.

    Informationen zur Implementierung der Karte selbst, zur Server-Rasterisierung und zu Fallstricken - Ich werde einen separaten Beitrag verfassen. Wenn Sie interessiert sind, teilen Sie mir dies mit. Die allgemeine Architektur ist wie folgt:
    • Die Karte greift auf den Server-Rasterizer zu und übergibt die Koordinaten des angezeigten Bereichs
    • Der Rasterizer liest eine JSON-Datei mit Paaren: die Koordinatendomäne, gruppiert die Punkte im Handumdrehen und gibt das Ergebnis aus
    • Auf der Karte werden die Ergebnisse des serverseitigen Rasterungsclusters angezeigt

    Es stellte sich schnell und einfach heraus. Ja, Sie können die json-Datei nicht lesen, aber wenden Sie sich an NoSQL ... aber bisher funktioniert alles schnell und es gibt so ein Wort - Faulheit :-) Der

    Rasterizer ist in PHP geschrieben, und on the fly, um k-means auszuführen, natürlich Selbstmord - daher wird alles vereinfacht und stattdessen Clustering erfolgt durch Rasterung. Bei Interesse werde ich es als separaten Beitrag beschreiben.

    Zusammenfassung


    So sieht die aktive Domain-Karte des Bitrix24-Clients aus (https://www.bitrix24.ru/online-domains-map) :


    Hier der Zoom:


    Es stellte sich heraus, dass es sich um eine schöne Online-Domain-Karte von Bitrix24 handelt. Zoom und Server-Clustering funktionieren ziemlich schnell. Spark Streaming freute sich auch über den recht angenehmen Vorgang, eine Karte über die Yandex.Maps-API zu erstellen. Schreiben Sie, was zu diesem Thema noch interessant sein könnte - wir werden versuchen, es im Detail zu erzählen. Viel Glück an alle!

    Jetzt auch beliebt: