Allgemeine JSOR-Probleme (nur Linux)
Verwenden Sie Java™ Sockets over Remote Direct Memory Access (JSOR), um die Vorteile von leistungsstarken Netzinfrastrukturen wie InfiniBandzu nutzen. Für die Verwendung von JSOR müssen Sie verschiedene Ressourcen installieren, konfigurieren und optimieren. Wenn dies nicht ordnungsgemäß ausgeführt wird, können Probleme auftreten.
Die RDMA-Implementierung, die zuvor veraltet war, wurde aus IBM® SDK, Java Technology Edition, Version 8 entfernt.
- RDMA-Socket- oder Threaderstellung ist fehlgeschlagen
- RDMA-Initialisierungsfehler bei Netzbetreiber
- RDMA-Verbindung fehlgeschlagen
- RDMA-Ausnahmebedingungen aufgrund einer Verbindungszurücksetzung
- RDMA-Kommunikation scheint blockiert zu sein
- Probleme mit der Zero-Copy-Funktion
- Probleme mit Verzweigungskompatibilitätsmodus
RDMA-Socket- oder Threaderstellung ist fehlgeschlagen
Ein JSOR-Problem kann auftreten, wenn ein Thread oder ein RDMA-Socket (RDMA - Remote Direct Memory Access) nicht erstellt werden kann. Dieses Problem kann auftreten, wenn gleichzeitig bestehende Verbindungen über RDMA-Transport ausgeführt werden.
Mögliche Ursachen
- RDMA-Socketpuffer sind standardmäßig fixiert oder im Speicher gesperrt. Eine Einschränkung bei der Einstellung memlock in Ihrer Umgebung kann dazu führen, dass neue RDMA-Sockets nicht erstellt oder registriert werden können.
- Wenn Sie gleichzeitig bestehende Verbindungen ausführen, verwendet jedes RDMA-Socket implizit einen Dateideskriptor für die Ereignisüberwachung. Wenn der Grenzwert für die maximale Anzahl von Benutzern geöffneter Dateien zu niedrig ist, schlägt die Socketerstellung fehl.
- Wenn Sie gleichzeitig bestehende Verbindungen ausführen, kann die Threaderstellung fehlschlagen, wenn der Grenzwert für die maximale Anzahl Benutzerprozesse zu niedrig ist. Weitere Informationen finden Sie in der folgenden Technote: java.lang.OutOfMemoryError beim Erstellen neuer Threads.
Minderung
- Um Fehler bei der Socketerstellung zu vermeiden, überprüfen Sie Ihre Einstellung für
ulimit -lund ändern Sie Ihre Einstellung für memlock auf der Basis der Socketpuffer in einen geeigneten Wert. - Prüfen Sie zur Vermeidung von Socketerstellungsfehlern bei Ausführung gleichzeitig
bestehender Verbindungen die Einstellung
ulimit -nund ändern Sie die Einstellung nofile auf der Basis der Skalierbarkeitsanforderungen der Anwendung in einen geeigneten Wert. - Prüfen Sie zur Vermeidung von Threaderstellungsfehlern bei Ausführung gleichzeitig
bestehender Verbindungen die Einstellung
ulimit -uund ändern Sie die Einstellung nproc auf der Basis der Skalierbarkeitsanforderungen der Anwendung in einen geeigneten Wert.
RDMA-Initialisierungsfehler bei Netzbetreiber
Ein JSOR-Problem kann auftreten, wenn bei der Ausführung einer 32-Bit-JVM (Java Virtual Machine) auf einem Linux-64-Bit-Betriebssystem die RDMA-Initialisierung (RDMA - Remote Direct Memory Access) des Netzbetreibers fehlschlägt.
Während der RDMA-Netzinitialisierungsphase prüft die JSOR-Laufzeitumgebung, ob kompatible OFED-Laufzeitbibliotheken verfügbar sind. Dieses Problem könnte auftreten, wenn die Laufzeitumgebung die 32-Bit-Bibliotheken librdmacm.so und libibverbs.so nicht finden und laden kann. Um das Problem zu vermeiden, installieren Sie die 32-Bit-OFED-Laufzeitbibliotheken neben den üblichen 64-Bit-Bibliotheken auf einer 64 -Bit- Linux® -Maschine.
RDMA-Verbindung fehlgeschlagen
Ein JSOR-Problem kann auftreten, wenn ein RDMA-Client (RDMA - Remote Direct Memory Access) keine Verbindung zu einem RDMA-Server herstellen kann.
Client und Server befinden sich auf demselben Host
Wenn sich der Client und der Server auf demselben Host befinden, wird dieses Verhalten erwartet, da es derzeit keine Unterstützung für ein RDMA-Loopback gibt. Für eine erfolgreiche Verbindung müssen sich der Client und der Server auf unterschiedlichen Hosts befinden, die über die RDMA-Netzschnittstellenadapter durch einen InfiniBand-Switch verbunden sind.
Client und Server in unterschiedlichen Teilnetzen
Der RDMA-Client und -Server sollten sich in demselben Netz befinden, durch einen gängigen InfiniBand-Switch verbunden sein und von einem einzelnen Teilnetzmanager verwaltet werden. Wenn es die jeweilige Situation erfordert, dass sich Ihr RDMA-Client und -Server in unterschiedlichen Teilnetzen befinden, müssen Sie sicherstellen, dass Internet-Switching und Paketweiterleitung auf der Hardware- und Softwareebene aktiviert sind.
Client und Server in demselben Teilnetz
Wenn sich der Client und Server in demselben Teilnetz befinden, könnte durch falsche Client- oder Serverkonfigurationsdateien oder durch eine falsche InfiniBand-Konfiguration auf einem Host oder beiden Hosts ein Verbindungsfehler verursacht werden.
Stellen Sie sicher, dass die Regeleinträge in Ihren Konfigurationsdateien korrekt definiert sind, wie in -Dcom.ibm.net.rdma.conf (Linux) beschrieben.
- Stellen Sie sicher, dass jeder an der Kommunikation beteiligte Host über einen geeigneten InfiniBand-Hostkanaladapter bzw. über eine geeignete RDMA-Netzschnittstellenkarte mit gültigen InfiniBand-Adressen (Schnittstellen, die mit dem Präfix ib beginnen) verfügt.
- Stellen Sie sicher, dass jeder InfiniBand-Port aktiv ist und die maximale Übertragungseinheit ordnungsgemäß festgelegt ist. Führen Sie einen der folgenden OFED-Laufzeitbefehle aus, um die maximale Übertragungseinheit zu prüfen: ibstat oder ibv_devinfo.
- Stellen Sie sicher, dass der Befehl ifconfig alle InfiniBand-Schnittstellen auflistet und jede Schnittstelle eine gültige IP-Adresse aufweist.
- Wählen Sie zwei gültige InfiniBand-Adressen, die beim Teilnetzmanager registriert sind, für die Erstellung von JSOR-Konfigurationsregeln aus und prüfen Sie dann, ob grundlegende RDMA-Kommunikation zwischen den Host- und Clientmaschinen möglich ist, indem Sie den Befehl rping mit Ihren ausgewählten InfiniBand-Adressen ausführen.
- Führen Sie analog den Befehl ibv_rc_pingpong aus.
- Führen Sie analog die Befehle ib_read_bw und ib_write_bw aus.
RDMA-Ausnahmebedingungen aufgrund einer Verbindungszurücksetzung
Gleichzeitig arbeitende RDMA-Clients (RDMA: Remote Direct Memory Access), die versuchen, Millionen Mal kleine Datenchunks an einen einzelnen RDMA-Server zu senden, können Ausnahmebedingungen aufgrund einer Verbindungszurücksetzung auslösen.
Java Sockets over Remote Direct Memory Access (JSOR) verwendet das R-Sockets-Protokoll als Grundlage für die Implementierung von APIs auf Socket-Ebene auf der Grundlage von RDMA. Das Protokoll R-Sockets verwendet die Größe der Sende- und Empfangswarteschlangen als Basis für die Implementierung von Datenfluss- und Ereignissteuerung zwischen Sender und Empfänger. Wenn mehrere parallel ausgeführte Clients versuchen, Millionen Mal kleine Datenmengen zu senden, könnten wegen unzureichender Warteschlangengrößen Ausnahmebedingungen aufgrund einer Verbindungszurücksetzung auftreten. Zu diesem Verhalten kommt es, da die Warteschlangengrößen das Arbeitsaufkommen diktieren, dass an beiden Enden in die Warteschlange gestellt werden kann.
Da die Standard-Warteschlangengrößen groß sind (siehe JSOR-Umgebungseinstellungen (Linux)), ist die Anpassung der Warteschlangengrößen nur in seltenen Fällen notwendig. Sie sollten die Warteschlangengrößen auf der Basis der Workloadkenndaten Ihrer Anwendung festlegen. Die maximale Anzahl und Häufigkeit von Sende- und Empfangsoperationen ist von besonderer Bedeutung. Es gibt keine allgemeine Formel zur Bestimmung der optimalen Warteschlangengrößen.
RDMA-Kommunikation scheint blockiert zu sein
Die RDMA-Kommunikation (Remote Direct Memory Access) zwischen Client und Server scheint blockiert zu sein, wenn Sie RPC-basierte Workloads mit unvorhersehbaren Nachrichtengrößen ausführen.
Java Sockets over Remote Direct Memory Access (JSOR) verwendet das R-Sockets-Protokoll als Grundlage für die Implementierung von APIs auf Socket-Ebene auf der Grundlage von RDMA. Für eine ordnungsgemäße Datenübertragung über das Protokoll R-Sockets müssen Sender und Empfänger aufeinander abgestimmt werden. Der einsatzbereite Empfänger muss im Voraus über einen Empfangspuffer verfügen, in den der Sender Daten stellen kann. Dieses Verhalten unterscheidet sich vom TCP/IP-Verhalten, bei dem Puffer nach Bedarf dynamisch zugeordnet werden. RDMA-Empfangsoperationen schlagen fehl, wenn im Voraus nicht ausreichend große Empfangspuffer zur Verfügung stehen. Weitere Informationen finden Sie im Abschnitt Flow Control des IETF-Entwurfs von Remote Direct Memory Access Transport for Remote Procedure Call.
Die JSOR-Implementierung stellt standardmäßig kleine Sende- und Empfangspuffer, die kleiner als 50 KB sind, zur Verfügung. Wenn ein RDMA-Client oder -Server versucht, eine große Menge Nutzdaten (z. B. 2 MB oder 4 MB) in beispielsweise 1-KB-Chunks in einer einzigen Richtung ohne synchronisierten Datenfluss zwischen Endpunkten zu senden, werden die Empfangspuffer ausgereizt, was zu einer Blockierung führt. Das Protokoll R-Socket versucht, die Empfangspuffer zu stoppen und erneut zu starten, aber wenn die Auffüllrate geringer ist als die Datensenderate, ist kein Verarbeitungsfortschritt möglich. Diese Effekte verstärken sich noch, wenn Hunderte von parallelen Clients versuchen, dieselben Operationen auf demselben RDMA-Transport auszuführen, da die Clients um dieselbe Gruppe von physischen Netzressourcen konkurrieren. Das Protokoll R-Sockets benötigt viel Zeit, um diese Situation zu handhaben, da es auf Neuversuche und negative Bestätigungen des Typs 'Empfänger nicht bereit' angewiesen ist, um die Verarbeitung fortsetzen zu können. Im schlimmsten Fall resultiert dieses Verhalten in einem Deadlock zwischen Endpunkten.
Analog muss auch die Größe des Sendepuffers ausreichend sein, um die Daten zum entsprechenden Empfangspuffer zu übertragen.
Minderung
Optimieren Sie für eine Java RPC-Anwendung die Puffergrößen, bevor Sie die Anwendung in einer Produktionsumgebung implementieren. Legen Sie die Puffergrößen entsprechend den Workloadkenndaten und der maximalen Nutzdatengröße der Anwendung fest. Es gibt keine allgemeine Formel zur Bestimmung der optimalen Puffergrößen. Weitere Informationen finden Sie unter JSOR-Umgebungseinstellungen (Linux).
Aktivieren Sie Zeitlimits für die Anwendung oder Laufzeitdatenübertragung, die es dem Client ermöglichen, die Datenübertragung abzubrechen und bei Bedarf mit höheren Werten für die Puffergrößen erneut zu versuchen. Siehe das folgende APAR für ein Beispiel: PM52124: OutOfMemoryError Fehler auf eXtreme Scale Clients können zum Ausfall des Grids führen. In diesem Beispiel hat sich der Server-Thread aufgrund von Speichermangel in der Methode socketWrite() aufgehängt. Als Lösung wird vorgeschlagen, die Eigenschaft com.ibm.CORBA.SocketWriteTimeout festzulegen.
Probleme mit der Zero-Copy-Funktion
Java-Anwendungen blockieren, wenn die Zero-Copy-Funktion aktiviert ist
Aufgrund der internen Synchronisation, die bei der Verwendung der Zero-Copy-Funktion zwischen der Datenquelle und der Datensenke erforderlich ist, blockiert eine Client- oder Serveranwendung möglicherweise, wenn die Zero-Copy-Funktion nur für einen einzigen Endpunkt aktiviert wird.
- Vermeiden Sie die Verwendung desselben Socketdeskriptors für parallele Lese- und Schreiboperationen, wenn die Zero-Copy-Funktion verwendet wird.
- Stellen Sie sicher, dass die Zero-Copy-Funktion auf beiden Endpunkten aktiviert ist. Weitere Informationen finden Sie unter -Dcom.ibm.net.rdma.zeroCopy (Linux).
- Stellen Sie sicher, dass auf beiden Endpunkten dieselben Zero-Copy-Schwellenwerte festgelegt wurden. Weitere Informationen finden Sie unter -Dcom.ibm.net.rdma.zeroCopyThreshold (Linux).
Java-Anwendungen verwenden die Zero-Copy-Funktion nicht
Java-Anwendungen verwenden die Zero-Copy-Funktion möglicherweise auch nach Angabe des Parameters -Dcom.ibm.net.rdma.zeroCopy=true nicht.
- Sie haben den Parameter -Dcom.ibm.net.rdma.zeroCopy=true angegeben.
- Die Puffergrößen, die in Java-Lese-und -Schreibaufrufen übergeben werden, überschreiten den durch den Parameter -Dcom.ibm.net.rdma.zeroCopyThreshold angegebenen Wert. Weitere Informationen zu diesem Parameter finden Sie unter -Dcom.ibm.net.rdma.zeroCopyThreshold (Linux).
- socketRead0Direct
- socketWrite0Direct
- RDMA_ReadDirect
- RDMA_SendDirect
Java-Anwendungen werden nicht skaliert
Die Zero-Copy-Funktion ist für wenige gleichzeitige, umfangreiche Datenübertragungen ausgelegt. Aufgrund der internen Synchronisation und des Aufwands für die Zuordnung und Verwaltung von Ressourcen ist die Skalierbarkeit durch die Größe der zu übertragenden Daten eingeschränkt.
Stellen Sie sicher, dass das Einsatzszenario ähnlich wie das Einsatzszenario bei FTP-Dateiübertragungen im Zero-Copy-Modus ist.
Probleme mit Verzweigungskompatibilitätsmodus
Es können mehrere Probleme im Zusammenhang mit dem Betrieb im Verzweigungskompatibilitätsmodus zwischen Java-Clients und nativen verzweigten Servern auftreten.
Fehlernachricht des nativen Servers librdmacm: Fatal: unable to open RDMA
device
- POWER ® -PC-Systeme mit einem Mellanox RDMA over Converged Ethernet-Adapter (RoCE) MT26448
- Redhat Enterprise Linux (RHEL) v6.4
- MLNX_OFED_LINUX-2.0-3.0.0
Wenn dieses Problem auftritt, führen Sie ein Upgrade auf die neueste Version des Betriebssystems und der OFED-Software durch. Bleibt das Problem bestehen, sollten Sie ein Upgrade auf die neueste Version des Mellanox-RoCE-Adapters durchführen.
Java-Clients blockieren
Im Verzweigungskompatibilitätsmodus können Java-Clients blockieren, wenn Systeme eine Verbindung zu nativen verzweigten Servern herstellen. Dieses Problem betrifft die RSocket-Vorabladebibliothek. Intern erstellt die Bibliothek einen benannten Semaphor /rsocket_fork bei der Verarbeitung der fork()-Unterstützung. Ist die Verarbeitung abgeschlossen, entfernt die R-Socket-Bibliothek den Semaphor jedoch nicht. Der Semaphor bleibt erhalten, bis das System neu gestartet wird. Jeder veraltete Link oder Wert für diesen benannten Semaphor aus einem früheren Aufruf führt dazu, dass der native Server keine Verbindungen zum fernen Client akzeptieren kann.
Verwenden Sie zur Umgehung dieses Problems den Befehl rm, um den Link des benannten Semaphors /rsocket_fork aufzuheben, bevor das Vorabladen von fork() beginnt. Unter Red Hat Enterprise Linux (RHEL) finden Sie die benannten Semaphore im Verzeichnis /dev/shm. Diese Dateien haben das Präfix sem..
Keine Skalierung für Java-Clients
Das RSockets-Protokoll bietet derzeit Vorabladeunterstützung für die Verzweigung nur für einfache Anwendungen, die unter idealen Bedingungen laufen. Beim Vorladen eines verzweigten Prozesses verwendet die RSockets-Bibliothek die Blocksemantik, um eine Verbindung zu RDMA zu migrieren.
Die aktuelle Unterstützung für die Methode fork() in RSocket ist daher nicht skalierbar. Bei Java-Multithread-Clients, die versuchen, über die native Interoperabilitätsfunktion eine Verbindung zu nativen verzweigten Servern herzustellen, kann es zu einer großen Anzahl fehlgeschlagener Verbindungen kommen. Zur Minderung dieses Problems können Sie den Wiederholungszähler für die Clientverbindung auf einen Wert größer als 1 setzen.