Ursachen von Linux UDP packet drops
Ich habe einen Linux-C++ - Anwendung, die erhält sequenziert UDP-Pakete. Wegen der Sequenzierung, kann ich leicht feststellen, wenn ein Paket verloren gegangen ist oder neu bestellt werden, D. H. wenn eine "Lücke" gefunden wird. Das system verfügt über eine recovery-Mechanismus zu behandeln Lücken, aber es ist am besten, um Lücken zu vermeiden in den ersten Platz. Mit einem einfachen libpcap-basierten packet-sniffer habe ich festgestellt, dass es keine Lücken in den Daten auf hardware-Ebene. Jedoch, ich sehe eine Menge Lücken in meiner Anwendung. Dies legt nahe, die kernel-Pakete verliert; es wird bestätigt durch die Betrachtung der /proc/net/snmp - Datei. Wenn mein Antrag auf eine Lücke, die Udp InErrors Zähler erhöht.
Auf der system-Ebene, wir haben erhöht die max receive buffer:
# sysctl net.core.rmem_max
net.core.rmem_max = 33554432
Ebene der Anwendung, wir haben erhöht die Empfangs-Puffer-Größe:
int sockbufsize = 33554432
int ret = setsockopt(my_socket_fd, SOL_SOCKET, SO_RCVBUF,
(char *)&sockbufsize, (int)sizeof(sockbufsize));
//check return code
sockbufsize = 0;
ret = getsockopt(my_socket_fd, SOL_SOCKET, SO_RCVBUF,
(char*)&sockbufsize, &size);
//print sockbufsize
Nach dem Aufruf von getsockopt () wird der Wert aufgedruckt ist, immer 2x was eingestellt ist (67108864 im Beispiel oben), aber ich glaube, das ist zu erwarten.
Ich weiß, dass das Versäumnis, Sie zu konsumieren, die Daten schnell genug, können in der Folge zu Paketverlusten. Jedoch, alle diese Anwendung tut, ist zu überprüfen die Sequenzierung, drücken Sie dann die Daten in eine Warteschlange; die eigentliche Verarbeitung erfolgt in einem anderen thread. Darüber hinaus die Maschine ist modern (dual Xeon X5560, 8 GB RAM) und sehr leicht beladen. Wir haben buchstäblich Dutzende von identischen Anwendungen empfangen von Daten an einem viel höhere rate, dass dieses problem nicht auftreten.
Neben einer zu-langsam-verbrauchende Anwendung, gibt es andere Gründe, warum der Linux-kernel kann drop UDP-Pakete?
FWIW, dies ist auf CentOS 4, mit kernel 2.6.9-89.0.25.ELlargesmp.
Die pcap-Anwendung bestätigt, dass die NIC-empfängt alle Pakete, es ist also keine Verkabelung oder switch-Problem. Als für das Programm selbst, ich bin mit dem exakt gleichen code, die gemeinsam von Dutzenden von anderen Anwendungen. Diese Verbindung ist die einzige mit dem problem.
könnte die eingehende Prüfsummen falsch sein?
InformationsquelleAutor Matt | 2011-05-06
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich hatte ein ähnliches problem mit meinem Programm. Seine Aufgabe ist das empfangen von udp-Paketen in einem thread und mit einer Warteschlange blockiert ist, schreiben Sie in der Datenbank mit einem anderen thread.
Bemerkte ich (mit
vmstat 1
), dass, wenn das system erlebt schwere I/O-wait-Operationen (liest) meine Bewerbung nicht erhalten Pakete, die Sie erhalten durch das system obwohl.War das problem - bei heavy I/O-wait ist aufgetreten, der thread wurde in die Datenbank geschrieben wurde, werden die I/O-verhungert, während man das queue mutex. Diese Art der udp-Puffer wurde überflogen von eingehenden Pakete, weil der Haupt-thread, der wurde empfangen, Sie hing an der
pthred_mutex_lock()
.Ich entschloss mich, es durch das spielen mit ioniceness (
ionice
Befehl) von meinem Prozess und den Datenbank-Prozess. Änderung der I/O sched-Klasse Best-Effort geholfen. Überraschenderweise bin ich nicht in der Lage dieses problem zu reproduzieren jetzt auch mit Standard-I/O-Nettigkeit.Mein kernel ist 2.6.32-71.el6.x86_64.
Ich bin noch immer in der Entwicklung dieses app, so dass ich versuchen werde zu aktualisieren meinem Beitrag, wenn ich mehr wissen.
InformationsquelleAutor racic
Wenn du mehr threads als Kerne und gleich der thread-Priorität zwischen Ihnen, ist es wahrscheinlich, dass der empfangende thread die starved für die Zeit, die zum Spülen des eingehenden Puffers. Sollten Sie in Erwägung ziehen, dass der thread mit einer höheren Priorität als die anderen.
Ähnlich, obwohl Sie oft weniger produktiv ist, binden Sie den thread für den Empfang zu einem Kern, so dass Sie nicht leiden Gemeinkosten für die Umschaltung zwischen den Kernen und zugehörigen cache flushes.
Nur um zu klären: durch "Spülen Sie die eingehenden Puffer" tun Sie einfach bedeuten, dass zu halten mit der rate von eingehenden Nachrichten, oder gibt es etwas subtiler?
ja, im Grunde Lesen Sie alles über die Buchse.
Wenn Sie
top
und geben1
zu ermöglichen, pro-CPU-display, tun alle CPUs/Kerne zeigen 0% idle-Zeit? Wenn dem so ist, dann Erhalt thread verhungern ist wahrscheinlich das Problem.InformationsquelleAutor Steve-o
int ret = setsockopt(my_socket_fd, SOL_SOCKET, SO_RCVBUF, (char *)&sockbufsize, (int)sizeof(sockbufsize));
Zunächst
setsockopt
dauert (int, int, int, void *, socklen_t), so gibt es keine casts notwendig.Er schlägt vor, dass Sie Ihre Umgebung nicht schnell genug. Packet capturing bekannt ist die Verarbeitung intensiver, und Sie beobachten, dass die Globale rate der übertragungen, die auf eine Oberfläche fallen, wie Sie beginnen, erfassen Programme wie iptraf-ng oder tcpdump auf einem.
Ich lief die pcap-Programm auf dem selben Rechner wie die Anwendung. Aber die drops auftreten, unabhängig davon, ob oder nicht das sniffer-Programm läuft. In anderen Worten, auch ohne dass der sniffer läuft, mein Anwendungsprotokolle Lücken, und die /proc/net/snmp Udp InErrors Zähler inkrementiert. (Bevor ich den sniffer, ich war nicht bewusst, dass der /proc/net/snmp-Datei.)
InformationsquelleAutor dgq7
Ich nicht genug Ruf zu kommentieren, aber ähnlich wie @racic, ich hatte ein Programm, wo ich hatte einen thread erhalten, und eine Bearbeitung thread eine blockierende Warteschlange zwischen Ihnen. Ich bemerkte das gleiche Problem mit Drop-Pakete, weil der empfangende thread wurde auf eine Sperre wartet auf die Warteschlange blockiert.
Diese zu lösen habe ich ein kleineren lokalen Puffer des empfangenden thread, und hatte es nur der push-Daten in den Puffer, dann war es nicht gesperrt (mit std::mutex::try_lock).
InformationsquelleAutor dfreese