2009-03-12 7 views
1

Ich habe an der Lösung für die Finanzindustrie gearbeitet. Die Hauptfunktionalität der Anwendung ist die Fähigkeit, massive Eingabedateien zu laden, sie zu verdauen, den Status im persistenten Speicher zu aktualisieren und auf Anforderung Extrakte aus dem persistenten Speicher zu generieren. Ziemlich einfach.Skalierbarkeit der Java EE-Anwendung. Wie würdest du es angehen?

Die Eingabedateien sind Industriestandard formatierte XML große (mehr als Hunderte von Megabyte) Nachrichten, die viele wiederholte Einträge enthalten. Der persistente Speicher ist eine relationale Datenbank. Die Engine wurde als POJO-basierte (Spring Framework als Back-Bone) Java-Anwendung implementiert, die auf dem J2EE-Anwendungsserver implementiert werden kann.

Die Frage ist die Skalierbarkeit und Leistung der Lösung. Wenn die Anwendung sequenziell Einträge aus XML verarbeitet, ist die Skalierbarkeit der Lösung eher gering. Es gibt keine Möglichkeit, mehr als eine Instanz der Anwendung in die Verarbeitung der einzelnen Datei einzubeziehen. Aus diesem Grund habe ich die parallele Verarbeitung für Eingaben in die XML-Eingabedatei eingeführt. Grundsätzlich besteht die Idee darin, die Verarbeitung einzelner Einträge für Arbeiter aus dem Pool zu versenden. Ich entschied mich, JMS für das Dispatching zu verwenden. Die Komponente, die die Datei lädt, liest den Stream und extrahiert einfach einzelne Einträge und füttert die Dispatch-Warteschlange. Am anderen Ende der Warteschlange befindet sich eine Anzahl gleichzeitiger Benutzer. Jeder wählt eine Nachricht der Warteschlange aus und verarbeitet den Eintrag und ist sofort verfügbar, um einen anderen Eintrag zu verarbeiten. Dies ist den Servlets innerhalb des Webcontainers ziemlich ähnlich. Was mir an diesem Ansatz besonders gelungen ist, ist, dass die Worker in separaten Instanzen der auf Remote-Servern bereitgestellten Anwendung residieren können, solange die Warteschlange freigegeben ist. Leider verbinden sich alle Mitarbeiter mit der gleichen Datenbank, die Persistenzspeicher verwaltet, und dies kann ein Flaschenhals sein, wenn der Datenbankserver nicht leistungsfähig genug ist, um die Last von konkurrierenden Arbeitern zu verarbeiten.

Was ist Ihre Meinung zu dieser Architektur? Hatten Sie eine ähnliche Anwendung für das Design? Was war deine Designentscheidung?

Antwort

2

Ich denke, die Architektur ist im Allgemeinen solide. Wenn die Datenbank Probleme mit einer hohen Anzahl von gleichzeitigen Aktualisierungen durch die Worker hat, können Sie eine zweite Warteschlange auf der anderen "Seite" der App einführen: Wenn jeder Worker seine Aufgabe erledigt, fügt er der Task die Ergebnisse dieser Aufgabe hinzu Warteschlange. Dann ergreift ein einzelner Arbeitsprozess regelmäßig die Ergebnisobjekte aus der zweiten Warteschlange und aktualisiert die Datenbank in einem großen Stapelbetrieb? Dies würde den gemeinsamen Zugriff auf Datenbanken verringern und die Effizienz von Aktualisierungen erhöhen.

+0

In einem mehrstufigen System, das Sie vorschlagen, muss Pregst vorsichtig sein, wenn es um Transaktionsintegrität geht - wenn beispielsweise die Warteschlange der Maschine abstürzt, [s] kann er Daten verlieren. JMS enthält Transaktions-Awareness, aber die Leistungsmerkmale davon sind implementierungsabhängig. – joev

+0

Tatsächlich verwende ich XA-glabal-Transaktionen, die sich über JMS-Sitzung und JDBC-Verbindung erstrecken. Also, alles ist transaktional. Außerdem werden JMS-Nachrichten als persistent markiert.Damit kann ich einmal und nur einmal Liefermerkmale annehmen. –

+0

Sie können auch ein Tool wie Terracotta verwenden, das den Status Ihrer JVM-Heaps transparent auf der Festplatte widerspiegelt und nach Systemabstürzen wiederherstellt. –

3

Sie können sich auch Hadoop ansehen, eine sehr praktische Plattform für Map/Reduce-Jobs. Der große Vorteil besteht darin, dass die gesamte Infrastruktur von Hadoop bereitgestellt wird, sodass Sie nur neue Hardware-Knoten zum Skalieren anwenden. Die Implementierung der Map- und Reduce-Jobs sollte nur einmal durchgeführt werden. Danach können Sie Ihren Cluster mit enormer Last füttern.

+0

Vielleicht beim nächsten Mal :) Die Anwendung wurde bereits wie oben beschrieben implementiert. Ich möchte das Ganze nicht neu implementieren und ein neues Programmiermodell für Entwickler einführen. Aber Hadoop oder GridGain sind die Frameworks, die ich definitiv untersuchen würde. –

1

Werfen Sie auch einen Blick auf Terracota Clustering-Lösung.

1

Für die parallele Verarbeitung, wie Mork0075 sagte, ist hadoop eine großartige Lösung. Tatsächlich verwenden viele Firmen es für sehr große Protokollanalyse. Und ein interessanter Projekt-Hive wurde basierend auf hadoop für Data Warehousing erstellt.

Wie auch immer, ich denke Ihr aktuelles Design ist ziemlich skalierbar. Was Ihre Bedenken bezüglich aller Mitarbeiter betrifft, die auf die Datenbank zugreifen, können Sie einfach eine andere Nachrichtenwarteschlange zwischen Arbeitern und Datenbank einfügen. Arbeiter legen Verarbeitungsergebnisse in die Warteschlange, und Sie erstellen ein anderes Programm, um die Warteschlange zu abonnieren und die Datenbank zu aktualisieren. Der Nachteil ist, dass zwei Warteschlangen das System zu kompliziert machen. Natürlich können Sie dem vorhandenen MQ-System einfach ein weiteres Thema hinzufügen. Das wird das System einfacher machen. Ein anderer Ansatz besteht in der Verwendung eines gemeinsam genutzten Dateisystems wie NFS, wobei jeder Worker-Computer dasselbe Verzeichnis auf dem gemeinsam genutzten Dateiserver einbindet und jeder Worker seine Verarbeitungsergebnisse in eine separate Datei auf dem gemeinsam genutzten Dateiserver schreibt. Dann erstellen Sie ein Programm, um neue Dateien zu überprüfen, um die Datenbank zu aktualisieren.In diesem Ansatz führen Sie eine weitere Komplexität ein: Gemeinsamer Dateiserver. Sie können beurteilen, welcher in Ihrem Fall einfacher ist.

1

Ich habe vor kurzem einen Teil meiner Freizeit damit verbracht, Spring Batch 2.0 zu untersuchen. Dies ist eine neue Version der Java-Batch-Engine, die auf dem Spring-Framework basiert. Leute, die Spring Batch implementiert haben, konzentrierten sich auf Parallelität und Parallelisierung der Ausführung für diese Version. Ich muss sagen, es sieht vielversprechend aus!

0

Wenn Sie bereits Spring/Java EE verwenden, ist es nur natürlich, Spring Batch als Lösung für Ihre "Concurrence-Architektur" zu verwenden.

Zwei Vorteile rechts von der Fledermaus:

  1. Spring Batch (ab 2.0 Start) implementiert Partitionierung, das bedeutet, dass der Rahmen Pflege der Partitionierung Daten für Sie in separaten Partition Schritte unternehmen (StepExecution) und Delegieren der tatsächlichen Durchführung dieser Schritte, um mehrere Threads oder anderen verteilten Systemen (PartitionHandlers, zB TaskExecutorPartitionHandler oder mehr verteilt MessageChannelPartitionHandler, etc .. werden)

  2. Frühling für den Umgang mit XML + Spring Batch ha ein schönes OXM Paket hat s eine StaxEventItemReader, die Fragmente aus dem Eingabe-XML-Dokument extrahiert, die Aufzeichnungen für die Verarbeitung

Geben Spring Batch einen Versuch entsprechen würde. Lassen Sie mich wissen, wenn Sie irgendwelche Fragen haben, ich bin froh, zu helfen.

EDIT:

Schauen Sie auch bei Scala/AKKA Actors und/oder Scala parallel collections. Wenn Ihre Aufgabe zutreffend ist, sharded/partitioniert/verteilt zu werden => das, was das Actor-Modell ist.

Wenn Sie eine Nicht-JVM-Lösung in Betracht ziehen möchten, werfen Sie einen Blick auf Erlang OTP => einfach und elegant.

0

In Antwort auf Ihre Fragen:

Was ist Ihre Meinung zu dieser Architektur? Hatten Sie eine ähnliche Anwendung für das Design? Was war deine Designentscheidung?

Ich denke, es ist eine gute Architektur, und Sie haben recht, die DB ist Ihr Engpass. Da das Design flexibel genug ist, können Sie den Umfang der Eingabe in die Datenbank steuern.

Ich habe und Multi-Threading über Knoten funktioniert. Ich bin mir nicht ganz sicher, ob Haddoop oder ein anderes verteiltes Verarbeitungssystem Ihnen viel mehr bieten wird als das, was Sie bereits haben, da Sie einfach I/O zu einer Datenbank machen.

Ich habe etwas Similiar mit JMS-Warteschlangen für die zentrale Protokollierung implementiert, und es funktionierte ziemlich gut mit weniger Auswirkungen auf den Code dann Schreiben der Protokolle auf die Festplatte. Ich denke, es wird gut für Ihre Anwendung funktionieren.

Verwandte Themen