# Netty3 + Localhost Adresse, Durchsatzdrosselung ?



## Kr0e (4. Apr 2011)

Hallo Zusammen,

ich arbeite seit geraumer Zeit an einer Art Dateiserver, ähnlich dem FTP aber mit ein paar Erweiterungen. Bislang lief alles problemlos, bei 100mbit Lan erreiche ich gut 11,48 MB/s. Bei diesem Test waren SATA Festplatten im Einsatz, sprich das Nadelöhr war das Lan.

Nun wollte ich mal eine Verbindung zu mir selbst aufbauen, um die Geschwindigkeit zu testen ohne Netzwerkverzögerung. Erwartet habe ich eine Rate von ca. 100 mb/s. Ich erreiche beim simplen Kopieren von Dateien etwa 110mb/s und dachte mir, dass das vlt. auch in etwa bei einer lokalen Verbindung so sein müsste oder vlt geringfügig darunter. Aber ich bekomme etwa 50mb/s hin. 

Allerdings rede ich von durchschnittlichen 50mb/s. Als ich mir das über eine Progressbar visualisiert habe, habe ich gemerkt, dass Netty anscheinend nach einer gewissen Zeit einfach das Attribut "writable" eines Channels für ein paar Sekunden auf false setzt. Sprich es wird einfach nix mehr gesendet, auch die CPU Last sinkt innerhalb dieser Phase auf fast null... Und wenn dann mal geschrieben wird, sind es wieder 105 mb/s.

Nach einigen Tests hab ich nun eine Theorie: Ich lese und schreibe (Datei) innerhalb der Workerthreads, die ich anfangs Netty zugewiesen habe. Ich habe nun einfach Puffer verschickt, ohne sie durch einen Lesevorgang zu füllen. Sprich buffer.position(buffer.limit). Nun erreiche ich knapp 290 mb/s Durchsatz.

Ich habe das Gefühl, dass Netty merkt, wieviel Zeit ein Workerthread beschäftigt ist und wenn diese Zeit nciht adequat zur Verbindung passt, wird der Channel schlafen gelegt, bzw solange nicht auf Writable gesetzt bis irgendeiner Art Timeout abgelaufen ist wonach dann wieder mit dem Senden fortgefahren wird. Ich vermute, damit soll einer Art Überlastung durch einzelne
Workerthreads entgegen gewirkt werden.

Nun stell ich mir natürlich die Frage, wie man dieses Verhalten ändern könnte, bzw. vlt sogar nutzen könnte, um die ganze Geschichte fix zu machen.

Also wenn die Festplatten schneller sind, als das Netzwerk (ist ja eigentlich fast immer der Fall), so müsste immer dann ein neuer Part geschickt werden, sobald ein Teil geschickt wurde. Das wäre auch recht eifnach zu realisieren: Jeder Sendevorgang gibt ein Future Objekt zurück, über das man sich benachrichtigen lassen kann, sobald diese Operation fertig ist.

Ist das Netzwerk schneller, so müsste der Dateizugriff gewisserweise mit Future-Objekten versehen werden, damit immer dann, sobald ein neuer Teil gelesen wurde, ein Paket verschickt wird. Interessant könnte es dann noch bei unterschiedlich schnellen Festplatten werden...

Mach ich einen Denkfehler ? Ist das wirkliche Problem vlt. ein ganz anderes ? 

@Tuxedo (Du wirst das ja bestimmt lesen ;-)):

Hast du ähnliche Erfahrungen schonmal mit MINA gemacht ? Weißt du zufälligerweise, wie sich dort Hochgeschwindigkeitsverbindungen verhalten ?

Gruß,

Chris


----------



## Kr0e (4. Apr 2011)

Ich denke, das Problem hat sich erledigt. Ich hatte gerade die Möglichkeit das Ganze mal im echten gigabit Lan zu testen.
Genau wie bei dem 100mbit Versuch zeigt auch der 1000mbit Versuch sehr gute Performance um die 98mb/s. 

Ich habe nun bei den lokalen Versuchen immerhin 70 mb/s, nachdem ich ein paar Pufferanpassungen gemacht habe und ein wenig mit den Futures rumgespielt hab.

Gruß,

Chris


----------



## Kr0e (4. Apr 2011)

Habe nun endlich das Problem gefunden, für alle die vlt ein ähnliches Problem haben (Es liegt weder an Java noch an Netty3):

Ich benutze Windows 7... Offenbar cached Windows 7 häufig kopierte Dateien z. T. Sprich wenn man ne Datei 5 mal von A nach B kopiert geht das iwann super schnell (fast wie verschieben). Wenn man nun eine Datei kopiert über eine lokale Verbindung und diese Datei ist Teil des Caches, dann zankt Windows anscheinend mit dem manuellem kopiervorgang über die lokale Verbindung. Wenn ich eine Datei mit Java ganz normal kopiere (ohne Sockets etc...), dann ist dieser Transfer auch super schnell nach ein paar mal... Aber darauf erstmal zu kommmen...  Als ich mal ne andere Datei genommen hab, gings dann mit der lokalen Verbindung direkt mit 100 mb/s...


Gruß,

Chris


----------



## maki (4. Apr 2011)

Jedes OS cacht, Linux sogar noch besser.

Solltest nicht Dateien zum testen wählen, sondern Daten die im Ram landen, so lässt du das Dateihandling (inkl. Festplatten) komplett aus.


----------



## Kr0e (4. Apr 2011)

Hab ich draus gelernt und werde ich zukünftig berücksichtigen...


----------



## tuxedo (5. Apr 2011)

Hab damit mit MINA und Win7 noch keine Probleme gehabt. Allerdings hab ich das auch nicht in dieser Hinsicht intensiv getestet.

Was ich bei MINA aber entdeckt hatte, waren grausame Performance-Werte wenn Win7 zu einem beliebigen anderen OS was übers Netzwerk geschickt hat. HIntergrund war der, dass MINA die Socket-TX-Puffergröße auf 1024 festgelegt hat, und Win7 im gegensatz zu WinXP hier nun allergisch drauf reagiert. Lässt man es bei 8k Puffer, geht's super flott. 

Hatte dazu auch nen MINA-Bug eingetütet, der aber mittlerweile in 2.x behoben wurde.

Werde bei Gelegenheit mal versuchen das Win7-Cache Problem mit MINA nachzustellen.

- Alex


----------



## Kr0e (3. Jul 2011)

Dieser Thread ist zwar schon was älter aber ich hatte vor kurzem wieder mal so ein Problem und dachte mir "hey, das Problem hatten wir doch schonmal erörtert". 

Ich hatte ja damals das Problem nicht gelöst, sondern einfach im GigaBit Lan getestet, wo es dann ging auf einmal... 

Ich glaub, dass war damals ein Zufall, da ich nämlich dafür auch direkt die Puffergrößen beim Senden verändert habn (Von 1024 * 64 auf 8192). 

Damals hab ich bei den ersten Tests (Wo es nie ging...) immer 1024*64 Byte Buffer verwendet, da ich wusste, dass Festplatten mit 8192Byte Buffern unterfordert sind und etwas langsamere Transferraten verursachen. Also wollte ich für die localhost-Tests ausschließen, dass Festplatten das Nadelöhr sind.

Lange Rede kurzer Sinn:

Die OS-Recv-Send-Buffer sind entscheident! Netty hat normalerweise 8192. Das Problem ist jetzt, wenn man beim Senden größere Puffer verwendet, als die Socketpuffer. Unter Win7 gilt anscheinend eine solche Verbindung als überlastet und es wird periodisch die Verbindung "schlafen gelegt". Darauf kam ich jetzt wieder, als ich in einigen Windowsforen darüber gelesen hab.

Also vlt für alle, die iwann mal ähnliche komische Probleme haben und sich auch nciht erklären können woran es liegt: Stets kleine Puffer auf Softwareebene verwenden, als die Socketpuffer. 

Meine Lösung nun ist einfach: Die Socketpuffer auf 128k setzen und die Software-Puffer ebenfalls. Damit sind die schnellen SATA-Platten gut ausgelastet und der Flow-Control von TCP dreht auch nicht durch.

Gruß,

Chris


----------

