2008-09-09 16 views
8

Ich habe eine Anwendung, die eine Mischung aus Java und C++ auf Solaris ist. Die Java-Aspekte des Codes führen die Webbenutzeroberfläche aus und richten den Status auf den Geräten ein, mit denen wir uns unterhalten, und der C++ - Code verarbeitet die Daten in Echtzeit, die von den Geräten zurückkommen. Gemeinsam genutzter Speicher wird verwendet, um Gerätezustands- und Kontextinformationen vom Java-Code an den C++ - Code weiterzuleiten. Der Java-Code verwendet eine PostgreSQL-Datenbank, um den Status beizubehalten.Hohe Verfügbarkeit und skalierbare Plattform für Java/C++ unter Solaris

Wir stoßen auf einige ziemlich schwerwiegende Leistungsengpässe, und im Moment können wir nur die Speicher- und CPU-Anzahl erhöhen. Aufgrund des gemeinsamen Speicherdesigns stecken wir auf der einen physischen Box fest.


Der wirklich große Hit hier wird durch den C++ Code genommen. Die Webschnittstelle wird ziemlich leicht zum Konfigurieren der Geräte verwendet. wo wir wirklich Schwierigkeiten haben, ist die Handhabung der Datenmengen, die die Geräte liefern, sobald sie konfiguriert sind.

Alle Daten, die wir vom Gerät erhalten, haben eine Kennung, die auf den Gerätekontext verweist, und wir müssen nachsehen. Im Moment gibt es eine Reihe von Shared-Memory-Objekten, die vom Java/UI-Code verwaltet werden und auf die der C++ - Code verweist, und das ist der Engpass. Aufgrund dieser Architektur können wir die C++ - Datenbehandlung nicht auf einen anderen Rechner verlagern. Wir müssen in der Lage sein, so zu skalieren, dass verschiedene Teilmengen von Geräten von verschiedenen Rechnern gehandhabt werden können, aber dann verlieren wir die Fähigkeit, diese Kontext-Suche durchzuführen, und das ist das Problem, das ich zu lösen versuche: Zeitdatenverarbeitung zu anderen Boxen, während immer noch auf den Gerätekontext Bezug genommen werden kann.

Ich sollte beachten, wir haben keine Kontrolle über das Protokoll von den Geräten selbst verwendet, und es gibt keine Möglichkeit, dass sich die Situation ändern wird.


Wir wissen, wir müssen von dieser weg bewegen zu können horizontalen Skalierung von mehreren Maschinen zum Cluster hinzufügen, und ich bin in den frühen Stadien der genau herauszufinden, wie wir dies tun.

Momentan betrachte ich Terracotta als eine Möglichkeit, den Java-Code zu skalieren, aber ich bin noch nicht soweit, herauszufinden, wie man C++ skalieren kann.

Neben der Skalierung für die Leistung müssen wir auch eine hohe Verfügbarkeit in Betracht ziehen. Die Anwendung muss die ganze Zeit verfügbar sein - nicht absolut 100%, was nicht kosteneffektiv ist, aber wir müssen einen vernünftigen Job machen, um einen Maschinenausfall zu überstehen.

Wenn Sie die Aufgabe, die mir gegeben wurde, übernehmen mussten, was würden Sie tun?

EDIT: Basierend auf den Daten von @John Channing, ich gucke sowohl GigaSpaces und Gemstone. Oracle Coherence und IBM ObjectGrid scheinen Java-only zu sein.

Antwort

5

Das erste, was ich tun würde, ist ein Modell des Systems zu konstruieren, um den Datenfluss abzubilden und zu versuchen, genau zu verstehen, wo der Engpass liegt. Wenn Sie Ihr System als pipeline modellieren können, dann sollten Sie in der Lage sein, die Theorie der Einschränkungen zu verwenden (die meiste Literatur beschäftigt sich mit der Optimierung von Geschäftsprozessen, aber auch Software), um die Leistung kontinuierlich zu verbessern und Engpässe zu beseitigen.

Als nächstes würde ich einige harte empirische Daten sammeln, die genau die Leistung Ihres Systems charakterisiert. Es ist so etwas wie ein Klischee, dass man nicht managen kann, was man nicht messen kann, aber ich habe viele Leute gesehen, die versuchen, ein Softwaresystem zu optimieren, das auf Ahnungen basiert und kläglich versagt.

Dann würde ich die Pareto Principle (80/20 rule) verwenden, um die kleine Anzahl von Dingen zu wählen, die die größten Gewinne erzeugen und sich nur auf diese konzentrieren.

Um eine Java-Anwendung horizontal zu skalieren, habe ich Oracle Coherence ausgiebig verwendet. Obwohl einige es als sehr teuer distributed hashtable ablehnen, ist die Funktionalität viel reicher und Sie können zum Beispiel direkt auf Daten im Cache von C++ code zugreifen. Weitere Alternativen für die horizontale Skalierung Ihres Java-Codes wären Giga Spaces, IBM Object Grid oder Gemstone Gemfire.

Wenn Ihr C++ - Code zustandslos ist und nur für die Berechnung von Zahlen verwendet wird, können Sie den Prozess unter Verwendung von ICE Grid mit Bindings für alle von Ihnen verwendeten Sprachen verteilen.

+0

Es gibt einige ausgezeichnete Links hier, John. Vielen Dank. Ich muss etwas vorlesen. – Andrew

1

Sie müssen seitlich und heraus skalieren. Vielleicht könnte so etwas wie ein message queue das Backend zwischen dem Frontend und dem Knirschen sein.

1

Andrew, (neben der Modellierung als Pipeline usw.), ist es wichtig, Dinge zu messen. Haben Sie einen Profiler über den Code laufen lassen und Metriken erhalten, wo die meiste Zeit verbracht wird?

Wie oft ändert sich der Datenbankcode? Schaust du gerade im Caching? Ich nehme an, Sie haben Indizes usw. über die Daten betrachtet, um das Db zu beschleunigen?

Welche Verkehrsstärke haben Sie am Frontend? Cachieren Sie Webseiten? (Es ist nicht schwer zu sagen, ein JMS-Typ api zu verwenden, um zwischen Komponenten zu kommunizieren. Sie können dann die Webseitenkomponente auf einen Computer (oder mehrere) setzen und dann den Integrationscode (C++) auf einen anderen und für viele JMS setzen Produkte gibt es in der Regel native C++ APIs dh ActiveMQ kommt in den Sinn), aber es hilft wirklich zu wissen, wie viel Zeit ist in Web (JSP?), C++, Datenbank ops.

Wird in der Datenbank Geschäftsdaten gespeichert oder werden auch Daten zwischen Java und C++ übertragen? Sie sagen, Sie verwenden Shared Mem nicht JNI? Welche Ebene von Multi-Threading gibt es derzeit in der APP? Würden Sie den Code als synchron oder asynchron beschreiben?

Gibt es eine physikalische Beziehung zwischen dem Solaris-Code und den Geräten, die gepflegt werden müssen (dh, registrieren sich alle Geräte mit dem C++ - Code oder können diese angegeben werden)? dh. Wenn Sie einen Web-Load-Balancer auf das Frontend setzen und nur zwei Maschinen aufstellen würden, ist die Beziehung zwischen den Geräten, die von einer Box initialisiert werden, im Voraus oder im Vorfeld initialisiert?

Was sind die HA-Anforderungen? dh. Informationen einfach angeben? Kann die HA nur durch das Clustering von Sitzungsdaten in der Webebene durchgeführt werden?

Wird die DB auf einer anderen Maschine ausgeführt?

Wie groß ist die DB? Haben Sie Ihre Anfragen optimiert, dh. versucht, explizite innere/äußere Joins zu verwenden, hilft manchmal im Vergleich zu verschachtelten Sub-Abfragen (manchmal). (Schau nochmal auf die sql stats).