>  기사  >  운영 및 유지보수  >  높은 동시성 조건에서 Linux 시스템 및 커널 매개변수 최적화

높은 동시성 조건에서 Linux 시스템 및 커널 매개변수 최적화

Linux中文社区
Linux中文社区앞으로
2023-08-04 16:41:19840검색

Linux는 기본 매개변수 하에서 높은 동시성을 잘 지원하지 않는다는 것은 잘 알려져 있습니다. 이는 주로 단일 프로세스에서 열려 있는 최대 파일 수, 커널 TCP 매개변수 및 IO 이벤트 배포 메커니즘에 의해 제한됩니다. 다음은 Linux 시스템이 높은 동시성 환경을 지원할 수 있도록 여러 측면에서 조정됩니다.

Iptables 관련

필요하지 않은 경우 iptables 방화벽을 끄거나 제거하고 커널이 iptables 모듈을 로드하지 못하게 하세요. 이러한 모듈은 동시성 성능에 영향을 미칠 수 있습니다.

단일 프로세스에서 열 수 있는 최대 파일 수 제한

일반 배포에서는 단일 프로세스를 최대 1024개 파일로 제한합니다. 이는 높은 동시성 요구 사항을 충족하지 못합니다. 조정 프로세스는 다음과 같습니다. # 프롬프트 Enter:

# ulimit–n 65535

루트로 시작된 단일 프로세스로 열 수 있는 최대 파일 수를 65535로 설정합니다. 시스템에서 "작업이 허용되지 않음"과 같은 메시지가 표시되면 위의 제한 수정이 실패했음을 의미합니다. 실제로 지정된 값은 사용자가 열 수 있는 파일 수에 대한 Linux 시스템의 소프트 제한 또는 하드 제한을 초과한 것입니다. 따라서 사용자를 위해 열린 파일 수에 대한 Linux 시스템의 소프트 제한과 하드 제한을 수정해야 합니다.

첫 번째 단계는 Limits.conf 파일을 수정하고 다음을 추가하는 것입니다.

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

'*' 기호는 모든 사용자의 제한을 수정함을 나타냅니다. 소프트 또는 하드는 소프트 제한을 수정할지 여부를 지정합니다. 수정하려는 항목 새 제한 값은 최대 열린 파일 수입니다(소프트 제한 값은 하드 제한보다 작거나 같아야 합니다). 변경 후 파일을 저장합니다. 두 번째 단계는 /etc/pam.d/login 파일을 수정하고 파일에 다음 줄을 추가하는 것입니다:

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

이것은 사용자가 시스템 로그인을 완료한 후 pam_limits.so 모듈을 호출하여 설정해야 함을 Linux에 알려줍니다. 사용자가 사용할 수 있는 시스템의 최대 제한(사용자가 열 수 있는 최대 파일 수 제한 포함) 및 pam_limits.so 모듈은 /etc/에서 구성을 읽습니다. security/limits.conf 파일을 사용하여 이러한 제한 값을 설정하십시오. 수정 후 이 파일을 저장하세요.

第三步,查看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은 Keepalive가 활성화된 경우 TCP가 Keepalive 메시지를 보내는 빈도를 나타냅니다. 기본값은 2시간이고 20분으로 변경합니다.
  • ip_local_port_range= 1024 65535는 아웃바운드 연결에 사용되는 포트 범위를 나타냅니다. 기본값은 매우 작으며 1024~65535로 변경되었습니다.
  • net.ipv4.tcp_max_syn_backlog= 8192는 SYN 대기열의 길이를 나타내며 기본값은 1024입니다. 대기열 길이를 8192로 늘리면 연결을 기다리는 더 많은 네트워크 연결을 수용할 수 있습니다.
  • net.ipv4.tcp_max_tw_buckets= 5000은 시스템이 동시에 최대 TIME_WAIT 수를 유지함을 의미합니다. 이 수를 초과하면 TIME_WAIT가 즉시 지워지고 경고 메시지가 인쇄됩니다. 기본값은 180000이며 5000으로 변경합니다. 이 매개변수는 TIME_WAIT의 최대 횟수를 초과하는 한 이를 제어할 수 있습니다. 커널의 기타 TCP 매개변수에 대한 설명
  • net.ipv4.tcp_max_syn_backlog= 65536 아직 클라이언트 확인 정보를 받지 못한 기록된 연결 요청의 최대값입니다. 메모리가 128M인 시스템의 경우 기본값은 1024이고, 메모리가 작은 시스템의 경우 기본값은 128입니다.
  • net.core.netdev_max_backlog= 32768 각 네트워크 인터페이스가 커널이 처리할 수 있는 것보다 더 빠르게 패킷을 수신할 때 대기열에 들어갈 수 있는 최대 패킷 수입니다.
  • net.core.somaxconn= 32768 예를 들어 웹 애플리케이션의 수신 기능 백로그는 커널 매개변수의 net.core.somaxconn을 기본적으로 128로 제한하고 nginx에서 정의한 NGX_LISTEN_BACKLOG의 기본값은 511입니다. 이므로 이 값을 조정해야 합니다.
  • net.core.wmem_default= 8388608
  • net.core.rmem_default= 8388608
  • net.core.rmem_max= 16777216 #최대 소켓 읽기 버퍼, 참조 최적화 값: 8732 00
  • 넷 .core.wmem_max= 16777216 #최대 소켓 쓰기 버퍼, 참조 최적화 값: 873200
  • net.ipv4.tcp_timestsmps= 0 타임스탬프는 시퀀스 번호 래핑을 방지할 수 있습니다. 1Gbps 링크는 확실히 이전에 사용되었던 시퀀스 번호를 만나게 됩니다. 타임스탬프를 사용하면 커널이 이러한 "비정상적인" 패킷을 허용할 수 있습니다. 여기서는 꺼야 합니다.
  • net.ipv4.tcp_synack_retries= 2 피어에 대한 연결을 열려면 커널은 이전 SYN에 대한 응답으로 ACK와 함께 SYN을 보내야 합니다. 이른바 삼자악수 중 두 번째 악수다. 이 설정은 연결을 포기하기 전에 커널이 보내는 SYN+ACK 패킷 수를 결정합니다.
  • net.ipv4.tcp_syn_retries= 2 커널이 연결 설정을 포기하기 전에 전송된 SYN 패킷 수입니다.
  • #net.ipv4.tcp_tw_len= 1
  • net.ipv4.tcp_tw_reuse= 1 재사용을 활성화합니다. 새로운 TCP 연결에 TIME-WAIT 소켓을 재사용할 수 있습니다.
  • net.ipv4.tcp_wmem= 8192 436600 873200 TCP 쓰기 버퍼, 참조 최적화 값: 8192 436600 873200
  • net.ipv4.tcp_rmem = 32768 436600 87320 0 TCP 읽기 버퍼, 참조 최적화 값: 32768 436600 873200
  • net.ipv4.tcp_mem= 94500000 91500000 92700000 또한 3개의 값이 있습니다. 의미:
  • net.ipv4.tcp_mem[0]: 이 값 미만에서는 TCP에 메모리 부족이 없습니다.
  • net.ipv4.tcp_mem[1]: 이 값에서 메모리 압박 단계로 들어갑니다.
  • net.ipv4.tcp_mem[2]: 이 값을 초과하면 TCP는 소켓 할당을 거부합니다. 위에서 언급한 메모리 단위는 바이트가 아닌 페이지입니다. 참조 최적화 값은 다음과 같습니다. 7864321048576 1572864
  • net.ipv4.tcp_max_orphans= 3276800 사용자 파일 핸들과 연결되지 않은 시스템의 최대 TCP 소켓 수입니다. 이 숫자를 초과하면 연결이 즉시 재설정되고 경고 메시지가 인쇄됩니다. 이 제한은 단순한 DoS 공격을 방지하기 위한 것입니다. 너무 많이 의존하거나 인위적으로 이 값을 줄여야 합니다(메모리를 늘리는 경우).
  • net.ipv4.tcp_fin_timeout= 30 로컬 끝에서 소켓을 닫도록 요청하는 경우 이 매개변수는 FIN-WAIT-2 상태를 유지하는 기간을 결정합니다. 피어는 오류를 범하고 연결을 닫지 않거나 예기치 않게 충돌할 수도 있습니다. 기본값은 60초입니다. 2.2 커널의 일반적인 값은 180초입니다. 그러나 귀하의 컴퓨터가 로드가 적은 웹 서버라도 많은 수의 데드 소켓으로 인해 메모리 오버플로가 발생할 위험이 있다는 점을 기억하십시오. 2는 최대 1.5K의 메모리만 먹을 수 있기 때문에 FIN-WAIT-1보다 덜 위험하지만 생존 기간은 더 깁니다.

또한 TCP 정체 알고리즘 문제와 관련되어 있습니다. 다음 명령을 사용하여 이 시스템에서 제공하는 정체 알고리즘 제어 모듈을 볼 수 있습니다.

  • sysctl net.ipv4.tcp_available_congestion_control

분석용 , 자세한 내용은 TCP 혼잡 제어 알고리즘의 장단점, 적용 환경, 성능 분석을 참조하세요. 예를 들어 높은 지연에는 hybla를, 중간 지연에는 htcp 알고리즘을 사용해 볼 수 있습니다.

TCP 혼잡 알고리즘을 hybla로 설정하려는 경우 net.ipv4.tcp_congestion_control=hybla

또한 3.7.1보다 높은 커널 버전의 경우 tcp_fastopen을 활성화할 수 있습니다: net.ipv4.tcp_fastopen= 3

IO 이벤트 배포 메커니즘

Linux에서 동시성 높은 TCP 연결을 활성화하려면 애플리케이션이 적절한 네트워크 I/O 기술과 I/O 이벤트 전달 메커니즘을 사용하는지 확인해야 합니다. 사용 가능한 I/O 기술은 동기 I/O, 비차단 동기 I/O 및 비동기 I/O입니다. TCP 동시성이 높은 경우 동기식 I/O를 사용하는 경우 TCP 연결당 I/O용 스레드를 생성하지 않으면 프로그램 작동이 심각하게 차단됩니다. 그러나 스레드가 너무 많으면 시스템의 스레드 스케줄링으로 인해 엄청난 오버헤드가 발생합니다. 따라서 TCP 동시성이 높은 상황에서는 동기 I/O를 사용하는 것이 바람직하지 않습니다. 이 경우 비차단 동기 I/O 또는 비동기 I/O 사용을 고려할 수 있습니다. 비차단 동기 I/O 기술에는 select(), poll(), epoll 및 기타 메커니즘의 사용이 포함됩니다. 비동기 I/O 기술은 AIO를 사용하는 것입니다.

I/O 이벤트 전달 메커니즘의 관점에서 select()는 제한된 수의 동시 연결(보통 1024개 이내)을 지원하므로 사용하는 것은 부적절합니다. 성능을 고려하면, poll()도 더 많은 수의 TCP 동시성을 지원할 수 있지만 "폴링" 메커니즘으로 인해 동시성 수가 높을 때 작동 효율성이 매우 낮고 오류가 발생할 수 있습니다. I/O 이벤트가 고르지 않게 분산되어 일부 TCP 연결에서 I/O "고갈"이 발생합니다. epoll이나 AIO를 사용한다면 위의 문제는 없습니다. (리눅스 커널에서 AIO 기술의 초기 구현은 각 I/O 요청에 대해 커널에 스레드를 생성하여 달성되었습니다. 이 구현 메커니즘은 높은 경우에 매우 효과적입니다. 실제로 동시 TCP 연결을 사용하면 심각한 성능 문제가 있지만 최신 Linux 커널에서는 AIO 구현이 향상되었습니다.

요약하자면, 높은 동시 TCP 연결을 지원하는 Linux 애플리케이션을 개발할 때 epoll 또는 AIO 기술을 사용하여 동시 TCP 연결에서 I/O 제어를 달성해야 합니다. 이렇게 하면 높은 동시 TCP 연결 지원을 처리하는 프로그램의 능력이 향상됩니다. 효율적인 I/O 보장을 제공합니다.

이러한 최적화 구성 후에는 서버의 TCP 동시 처리 기능이 크게 향상됩니다. 위 구성은 참고용일 뿐입니다. 프로덕션 환경에서 사용하는 경우 실제 상황에 따라 관찰하고 조정하십시오.

위 내용은 높은 동시성 조건에서 Linux 시스템 및 커널 매개변수 최적화의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 Linux中文社区에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제