Heim  >  Artikel  >  Betrieb und Instandhaltung  >  Optimierung von Linux-System- und Kernelparametern unter Bedingungen hoher Parallelität

Optimierung von Linux-System- und Kernelparametern unter Bedingungen hoher Parallelität

Linux中文社区
Linux中文社区nach vorne
2023-08-04 16:41:19929Durchsuche

Es ist bekannt, dass Linux eine hohe Parallelität unter Standardparametern nicht gut unterstützt, was hauptsächlich durch die maximale Anzahl geöffneter Dateien in einem einzelnen Prozess, Kernel-TCP-Parameter und den IO-Ereignisverteilungsmechanismus begrenzt ist. Im Folgenden werden Anpassungen in mehreren Aspekten vorgenommen, damit das Linux-System Umgebungen mit hoher Parallelität unterstützen kann.

Iptables-bezogen

Wenn nicht erforderlich, schalten Sie die iptables-Firewall aus oder deinstallieren Sie sie und verhindern Sie, dass der Kernel das iptables-Modul lädt. Diese Module können die Parallelitätsleistung beeinträchtigen.

Begrenzung der maximalen Anzahl von Dateien, die von einem einzelnen Prozess geöffnet werden können

Allgemeine Distributionen begrenzen einen einzelnen Prozess auf maximal 1024 Dateien, was bei weitem nicht den hohen Anforderungen an die Parallelität entspricht. Der Anpassungsprozess ist wie folgt: Geben Sie bei ein # Eingabeaufforderung Geben Sie Folgendes ein:

# ulimit–n 65535

Legen Sie die maximale Anzahl von Dateien, die von einem einzelnen, von Root gestarteten Prozess geöffnet werden können, auf 65535 fest. Wenn das System etwas wie „Vorgang nicht zulässig“ ausgibt, bedeutet dies, dass die obige Grenzwertänderung fehlgeschlagen ist. Tatsächlich überschreitet der angegebene Wert das weiche oder harte Limit des Linux-Systems für die Anzahl der Dateien, die der Benutzer öffnen kann. Daher ist es notwendig, die Soft- und Hard-Limits des Linux-Systems für die Anzahl geöffneter Dateien für Benutzer zu ändern.

Der erste Schritt besteht darin, die Datei „limits.conf“ zu ändern und Folgendes hinzuzufügen:

# vim /etc/security/limits.conf
* softnofile 65536
* hard nofile65536

Das „*“-Zeichen gibt an, dass die Grenzwerte aller Benutzer geändert werden sollen; weich oder hart gibt an, ob der weiche Grenzwert oder der harte Grenzwert geändert werden soll diejenigen, die Sie ändern möchten. Der neue Grenzwert ist die maximale Anzahl geöffneter Dateien (bitte beachten Sie, dass der Soft-Limit-Wert kleiner oder gleich dem Hard-Limit sein muss). Speichern Sie die Datei, nachdem Sie Änderungen vorgenommen haben. Der zweite Schritt besteht darin, die Datei /etc/pam.d/login zu ändern und der Datei die folgende Zeile hinzuzufügen:

# vim /etc/pam.d/login
sessionrequired /lib/security/pam_limits.so

Dies teilt Linux mit, dass nach Abschluss der Systemanmeldung des Benutzers das Modul pam_limits.so zum Festlegen aufgerufen werden sollte das System, das dem Benutzer zur Verfügung stehen soll (einschließlich der Begrenzung der maximalen Anzahl von Dateien, die ein Benutzer öffnen kann), und das Modul pam_limits.so liest die Konfiguration aus /etc/. Sie können diese Grenzwerte in der Datei security/limits.conf festlegen. Speichern Sie diese Datei nach der Änderung.

第三步,查看Linux系统级的最大打开文件数限制,使用如下命令:

# cat/proc/sys/fs/file-max
32568

这表明这台Linux系统最多允许同时打开(即包含所有用户打开文件数总和)32568个文件,是Linux系统级硬限制,所有用户级的打开文件数限制都不应超过这个数值。通常这个系统级硬限制是Linux系统在启动时根据系统硬件资源状况计算出来的最佳的最大同时打开文件数限制,如果没有特殊需要,不应该修改此限制,除非想为用户级打开文件数限制设置超过此限制的值。修改此硬限制的方法是修改/etc/sysctl.conf文件内fs.file-max= 131072

这是让Linux在启动完成后强行将系统级打开文件数硬限制设置为131072。修改完后保存此文件。

完成上述步骤后重启系统,一般情况下就可以将Linux系统对指定用户的单一进程允许同时打开的最大文件数限制设为指定的数值。如果重启后用ulimit-n命令查看用户可打开文件数限制仍然低于上述步骤中设置的最大值,这可能是因为在用户登录脚本/etc/profile中使用ulimit-n命令已经将用户可同时打开的文件数做了限制。

由于通过ulimit-n修改系统对用户可同时打开文件的最大数限制时,新修改的值只能小于或等于上次ulimit-n设置的值,因此想用此命令增大这个限制值是不可能的。所以,如果有上述问题存在,就只能去打开/etc/profile脚本文件,在文件中查找是否使用了ulimit-n限制了用户可同时打开的最大文件数量,如果找到,则删除这行命令,或者将其设置的值改为合适的值,然后保存文件,用户退出并重新登录系统即可。

通过上述步骤,就为支持高并发TCP连接处理的通讯处理程序解除关于打开文件数量方面的系统限制。

内核TCP参数方面

Linux系统下,TCP连接断开后,会以TIME_WAIT状态保留一定的时间,然后才会释放端口。当并发请求过多的时候,就会产生大量的TIME_WAIT状态的连接,无法及时断开的话,会占用大量的端口资源和服务器资源。这个时候我们可以优化TCP的内核参数,来及时将TIME_WAIT状态的端口清理掉。

下面介绍的方法只对拥有大量TIME_WAIT状态的连接导致系统资源消耗有效,如果不是这种情况下,效果可能不明显。可以使用netstat命令去查TIME_WAIT状态的连接状态,输入下面的组合命令,查看当前TCP连接的状态和对应的连接数量:

# netstat-n | awk ‘/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}’

这个命令会输出类似下面的结果:

LAST_ACK16
SYN_RECV348
ESTABLISHED70
FIN_WAIT1229
FIN_WAIT230
CLOSING33
TIME_WAIT18098

我们只用关心TIME_WAIT的个数,在这里可以看到,有18000多个TIME_WAIT,这样就占用了18000多个端口。要知道端口的数量只有65535个,占用一个少一个,会严重的影响到后继的新连接。这种情况下,我们就有必要调整下Linux的TCP内核参数,让系统更快的释放TIME_WAIT连接。

编辑配置文件:/etc/sysctl.conf,在这个文件中,加入下面的几行内容:

# vim /etc/sysctl.conf
net.ipv4.tcp_syncookies= 1
net.ipv4.tcp_tw_reuse= 1
net.ipv4.tcp_tw_recycle= 1
net.ipv4.tcp_fin_timeout= 30

输入下面的命令,让内核参数生效:

# sysctl-p

简单的说明上面的参数的含义:

  • net.ipv4.tcp_syncookies= 1 表示开启SYNCookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;
  • net.ipv4.tcp_tw_reuse= 1 表示开启重用。允许将TIME-WAITsockets重新用于新的TCP连接,默认为0,表示关闭;
  • net.ipv4.tcp_tw_recycle= 1 表示开启TCP连接中TIME-WAITsockets的快速回收,默认为0,表示关闭;
  • net.ipv4.tcp_fin_timeout 修改系統默认的TIMEOUT 时间。

在经过这样的调整之后,除了会进一步提升服务器的负载能力之外,还能够防御小流量程度的DoS、CC和SYN攻击。

此外,如果你的连接数本身就很多,我们可以再优化一下TCP的可使用端口范围,进一步提升服务器的并发能力。依然是往上面的参数文件中,加入下面这些配置:

net.ipv4.tcp_keepalive_time= 1200
net.ipv4.ip_local_port_range= 1024 65535
net.ipv4.tcp_max_syn_backlog= 8192
net.ipv4.tcp_max_tw_buckets= 5000

这几个参数,建议只在流量非常大的服务器上开启,会有显著的效果。一般的流量小的服务器上,没有必要去设置这几个参数。

  • net.ipv4.tcp_keepalive_time= 1200 gibt die Häufigkeit an, mit der TCP Keepalive-Nachrichten sendet, wenn Keepalive aktiviert ist. Der Standardwert ist 2 Stunden, ändern Sie ihn auf 20 Minuten.
  • ip_local_port_range= 1024 65535 gibt den Portbereich an, der für ausgehende Verbindungen verwendet wird. Der Standardwert ist sehr klein und wurde auf 1024 bis 65535 geändert.
  • net.ipv4.tcp_max_syn_backlog= 8192 gibt die Länge der SYN-Warteschlange an, der Standardwert ist 1024, eine Erhöhung der Warteschlangenlänge auf 8192 kann mehr Netzwerkverbindungen aufnehmen, die auf Verbindungen warten.
  • net.ipv4.tcp_max_tw_buckets= 5000 bedeutet, dass das System die maximale Anzahl von TIME_WAIT gleichzeitig beibehält. Wenn diese Anzahl überschritten wird, wird TIME_WAIT sofort gelöscht und eine Warnmeldung ausgegeben. Der Standardwert ist 180000, ändern Sie ihn auf 5000. Dieser Parameter kann die maximale Anzahl von TIME_WAIT steuern, solange diese überschritten wird. Beschreibung anderer TCP-Parameter des Kernels
  • net.ipv4.tcp_max_syn_backlog= 65536 Der Maximalwert der aufgezeichneten Verbindungsanfragen, die noch keine Client-Bestätigungsinformationen erhalten haben. Für Systeme mit 128 MB Speicher ist der Standardwert 1024 und für Systeme mit kleinem Speicher 128.
  • net.core.netdev_max_backlog= 32768 Die maximale Anzahl von Paketen, die in die Warteschlange gestellt werden dürfen, wenn jede Netzwerkschnittstelle Pakete schneller empfängt, als der Kernel sie verarbeiten kann.
  • net.core.somaxconn= 32768 Beispielsweise begrenzt der Rückstand der Listen-Funktion in einer Webanwendung den net.core.somaxconn unserer Kernel-Parameter standardmäßig auf 128, und der von nginx definierte NGX_LISTEN_BACKLOG ist standardmäßig auf 511 festgelegt Daher muss dieser Wert angepasst werden.
  • net.core.wmem_default= 8388608
  • net.core.rmem_default= 8388608
  • net.core.rmem_max= 16777216 #Maximaler Socket-Lesepuffer, Referenzoptimierungswert: 8732 00
  • netto .core.wmem_max= 16777216 #Maximaler Socket-Schreibpuffer, Referenzoptimierungswert: 873200
  • net.ipv4.tcp_timestsmps= 0 Der Zeitstempel kann das Umbrechen der Sequenznummer vermeiden. Bei einer 1-Gbit/s-Verbindung werden Sie auf jeden Fall auf Sequenznummern stoßen, die bereits zuvor verwendet wurden. Der Zeitstempel ermöglicht es dem Kernel, solche „abnormalen“ Pakete zu akzeptieren. Es muss hier ausgeschaltet werden.
  • net.ipv4.tcp_synack_retries= 2 Um eine Verbindung zum Peer zu öffnen, muss der Kernel ein SYN mit einem ACK als Antwort auf das vorherige SYN senden. Dies ist der zweite Handschlag beim sogenannten Drei-Wege-Handschlag. Diese Einstellung bestimmt die Anzahl der SYN+ACK-Pakete, die der Kernel sendet, bevor die Verbindung aufgegeben wird.
  • net.ipv4.tcp_syn_retries= 2 Die Anzahl der gesendeten SYN-Pakete, bevor der Kernel den Verbindungsaufbau aufgibt.
  • #net.ipv4.tcp_tw_len= 1
  • net.ipv4.tcp_tw_reuse= 1 Wiederverwendung aktivieren. Ermöglicht die Wiederverwendung von TIME-WAITsockets für neue TCP-Verbindungen.
  • net.ipv4.tcp_wmem= 8192 436600 873200 TCP-Schreibpuffer, Referenzoptimierungswert: 8192 436600 873200
  • net.ipv4.tcp_rmem = 32768 436600. 87 3200 TCP-Lesepuffer, Referenzoptimierungswert: 32768 436600 873200
  • net.ipv4.tcp_mem= 94500000 91500000 92700000 Es gibt auch 3 Werte, was bedeutet:
  • net.ipv4.tcp_mem[0]: Unter diesem Wert hat TCP keinen Speicherdruck.
  • net.ipv4.tcp_mem[1]: Geben Sie bei diesem Wert die Speicherdruckstufe ein.
  • net.ipv4.tcp_mem[2]: Über diesem Wert weigert sich TCP, einen Socket zuzuweisen. Die oben genannten Speichereinheiten sind Seiten, keine Bytes. Der Referenzoptimierungswert lautet: 7864321048576 1572864
  • net.ipv4.tcp_max_orphans= 3276800 Die maximale Anzahl von TCP-Sockets im System, die keinem Benutzerdateihandle zugeordnet sind. Bei Überschreitung dieser Zahl wird die Verbindung sofort zurückgesetzt und eine Warnmeldung ausgegeben. Diese Grenze dient nur der Verhinderung einfacher DoS-Angriffe. Sie können sich nicht zu sehr darauf verlassen oder diesen Wert künstlich verringern. Sie sollten diesen Wert erhöhen (wenn Sie den Speicher erhöhen).
  • net.ipv4.tcp_fin_timeout= 30 Wenn der Socket vom lokalen Ende geschlossen werden soll, bestimmt dieser Parameter, wie lange er im FIN-WAIT-2-Zustand bleibt. Der Peer kann Fehler machen und die Verbindung niemals schließen oder sogar unerwartet abstürzen. Der Standardwert beträgt 60 Sekunden. Der übliche Wert für den 2.2-Kernel beträgt 180 Sekunden. Sie können diese Einstellung drücken, aber denken Sie daran, dass aufgrund einer großen Anzahl toter Sockets die Gefahr eines Speicherüberlaufs besteht. 2 ist weniger gefährlich als FIN-WAIT-1, da es nur bis zu 1,5 KB Speicher beanspruchen kann, ihre Überlebenszeit ist jedoch länger.

Dabei handelt es sich auch um ein Problem mit dem TCP-Überlastungsalgorithmus. Sie können den folgenden Befehl verwenden, um das von dieser Maschine bereitgestellte Überlastungsalgorithmus-Kontrollmodul anzuzeigen:

  • sysctl net.ipv4.tcp_available_congestion_control

Für mehrere Algorithmen Zur Analyse Weitere Informationen finden Sie im Folgenden: Vor- und Nachteile, anwendbare Umgebung und Leistungsanalyse des TCP-Überlastungskontrollalgorithmus. Sie können beispielsweise Hybla für hohe Verzögerungen und den HTTP-Algorithmus für mittlere Verzögerungen usw. ausprobieren.

Wenn Sie den TCP-Überlastungsalgorithmus auf hybla net.ipv4.tcp_congestion_control=hybla einstellen möchten

Darüber hinaus können wir für Kernel-Versionen höher als 3.7.1 tcp_fastopen aktivieren: net.ipv4.tcp_fastopen= 3

IO Mechanismus zur Verteilung von Ereignissen

Um TCP-Verbindungen mit hoher Parallelität unter Linux zu ermöglichen, müssen Sie bestätigen, ob die Anwendung die entsprechende Netzwerk-E/A-Technologie und den E/A-Ereignisverteilungsmechanismus verwendet. Verfügbare I/O-Technologien sind synchrone I/O, nicht blockierende synchrone I/O und asynchrone I/O. Wenn bei hoher TCP-Parallelität synchrone E/A verwendet wird, wird die Ausführung des Programms ernsthaft blockiert, es sei denn, es wird ein Thread für E/A pro TCP-Verbindung erstellt. Allerdings verursachen zu viele Threads aufgrund der Thread-Planung des Systems einen enormen Overhead. Daher ist es nicht ratsam, synchrone E/A in Situationen mit hoher TCP-Parallelität zu verwenden. In diesem Fall können Sie die Verwendung nicht blockierender synchroner E/A oder asynchroner E/A in Betracht ziehen. Zu den nicht blockierenden synchronen E/A-Technologien gehört die Verwendung von select(), poll(), epoll und anderen Mechanismen. Die Technologie der asynchronen E/A besteht in der Verwendung von AIO.

Aus Sicht des I/O-Ereignis-Dispatch-Mechanismus ist die Verwendung von select() ungeeignet, da es eine begrenzte Anzahl gleichzeitiger Verbindungen unterstützt (normalerweise innerhalb von 1024). Unter Berücksichtigung der Leistung ist poll() ebenfalls ungeeignet. Obwohl es aufgrund seines „Polling“-Mechanismus eine höhere Anzahl von Parallelitäten unterstützen kann, ist seine Betriebseffizienz recht gering, und das kann der Fall sein E/A-Ereignisse sind ungleichmäßig verteilt, was bei einigen TCP-Verbindungen zu einem „E/A-Ausfall“ führt. Wenn Sie epoll oder AIO verwenden, besteht das oben genannte Problem nicht (die frühe Implementierung der AIO-Technologie im Linux-Kernel wurde durch die Erstellung eines Threads im Kernel für jede E/A-Anforderung erreicht. Dieser Implementierungsmechanismus ist bei hohen Anforderungen sehr effektiv gleichzeitige TCP-Verbindungen Es gibt tatsächlich ernsthafte Leistungsprobleme bei der Verwendung, aber im neuesten Linux-Kernel wurde die Implementierung von AIO verbessert.

Zusammenfassend lässt sich sagen, dass Sie bei der Entwicklung von Linux-Anwendungen, die viele gleichzeitige TCP-Verbindungen unterstützen, versuchen sollten, Epoll- oder AIO-Technologie zu verwenden, um die E/A-Steuerung für gleichzeitige TCP-Verbindungen zu erreichen. Dadurch wird die Fähigkeit des Programms verbessert, viele gleichzeitige TCP-Verbindungen zu verarbeiten Bietet effiziente I/O-Garantien.

Nach einer solchen optimierten Konfiguration wird die Fähigkeit des Servers zur gleichzeitigen TCP-Verarbeitung erheblich verbessert. Die obige Konfiguration dient nur als Referenz. Wenn Sie sie in einer Produktionsumgebung verwenden, beachten Sie sie bitte und passen Sie sie entsprechend Ihrer tatsächlichen Situation an.

Das obige ist der detaillierte Inhalt vonOptimierung von Linux-System- und Kernelparametern unter Bedingungen hoher Parallelität. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:Linux中文社区. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen