InfraPlatform

[꿀팁] 고성능 Nginx를위한 튜닝 - (3) TCP 관련 처리량 늘리기-리눅스커널튜닝

IT오이시이 2020. 12. 28. 00:22
728x90

#Nginx설치 #Nginx-inatll #웹서버 설정 #Nginx웹서버설치 #웹서버튜닝 #high performancen nginx #system performance tunning #웹서버 튜닝 #성능개선 #시스템-튜닝 #파일시스템-튜닝

 

1. 디스크의 I/O 병목 줄이기
2. 프로세스 처리량 늘리기 (Process)
3. TCP 관련 처리량 늘리기
4. 메모리 및 CPU 튜닝하기 (Processor)
5. 마이크로캐싱
6. 로그 부하 줄이기
7. Dos, DDos 방어 설정

 

3번째 성능관련 연재로 TCP 관련 튜닝 입니다. 주로 리눅스 커널튜닝 사례로 많이 보았던 리눅스 커널 파라미터들에 대한 내용중에서 네트웍 관련된 부분들을 정리 하였습니다.

건물이 아무리 크고 좋아도 출입구가 적으면 사람들이 드나들기 어려운 것 처럼 리눅스의 TCP 튜닝은 내.외부간의 통신 요청량을 많이 받고 처리하는데 있습니다. 반면 너무 과하게 튜닝을 하면 또한 성능의 효과가 떨어지게 되므로 적정한 수준에서 튜닝을 해야 합니다. 이 부분은 시스템의 상태를 모니터링 하면서 상황마다 다르게 조정을 해야하는 영역이라 마땅한 정답은 없을 수 있습니다.

 

 

[꿀팁] 고성능 Nginx를위한 튜닝 - (3) TCP 관련 처리량 늘리기-리눅스커널튜닝

 

1. 수신 연결 수 최대화 하기 (리눅스커널 파라미터)

수신 대기열에 대한 부분은 다음과 같이 다양한 backlog 들이 있습니다. 이중에서 가장 많이 접하는 부분들을 정리해 보았습니다. backlog 는 대량으로 유입되는 동시 요청을 별도의 큐에 담아 버퍼링을 함으로 부하를 완충하는 역할을 합니다. 물론 처리량보다 더 많이 요청이 온다면 처리를 못하겠지만 동시 접속자가 갑자기 몰리는 웹사이트의 이벤트 처리에서 활용을 할 수 있습니다.

TCP 수신 대기열 netdev_max_backlog

net.core.netdev_max_backlog 설정으로 높은 트래픽을 처리하는 서버에서 처리 대기중인 패킷의 수를 최대화 하도록 증가하여야 합니다.

  • net.core.netdev_max_backlog = 20480

TCP 백 로그 대기열 tcp_max_syn_backlog

  • net.ipv4.tcp_max_syn_backlog =20480 [ default 8096 ]

TCP 요청으로 유입되는 대량의 SYN 패킷 요청을 수용하도록 백로그 큐를 늘려 줘야 합니다. Accept ACK가 수신 및 처리 될 때까지 수락 큐로 이동되지 않고 큐에서 대기하게 됩니다. 이는 synflood를 방지하도록 설정하는 것입니다.

  • net.ipv4.tcp_syncookies = 1 [ default 0 ]

TCP SYN 쿠키 tcp_syncookies, tcp_syn_retries

SYN 쿠키가 활성화 된 경우 백로그 큐가 가득 찼을 경우에도 정상적인 접속요구를 계속 받아들일수 있도록 해주므로, SYN_Flooding 공격에 대비한 가장 효과적인 방법 입니다. 그러나 SYN을 보내고 SYN + ACK를 수신되지 않는경우 ACK를 재시도하는 것이 발생 됩니다. 아래와 같이 재시도 횟수를 디폴트 5에서 1~2의 숫자로 줄여 줍니다.

  • net.ipv4.tcp_syncookies = 1 [ default 0 ]
  • net.ipv4.tcp_syn_retries = 2 [ default 5 ]
  • net.ipv4.tcp_retries1 = 2 [ default 3 ]

 

tcp_syn_retries 를 줄이는 이유는 서비스가 부하가 클경우 응답 처리가 되지 않고 retry들이 증가하여 신규 유입되는 것을 처리하지 못하게됩니다. 이때 retry 수를 줄여서 신규 유입을 증가 시키고, 응답이 없을시 불필요한 재시도를 줄이는 역할을 하게 됩니다.

 

TCP 수락 대기열 somaxconn

  • net.core.somaxconn = 8192 [ default 1024 ]

somaxconn는 애플리케이션이 TCP listen()으로 열리는 수락 큐 크기입니다. 리스너의 수락 큐에 있을 수 있는 최대 연결 제한을 충분히 늘려 줍니다. (애플리케이션 listen()이 somaxconn 보다 많이 호출되면 진입을 제한 합니다.)

네트웍 메모리 설정 net.core.Xmem_max, net.ipv4.tcp_Xme

- 주로 오라클 관련 네트웍 튜닝 자료에 많이 나오는 내용으로 네트웍 드라이버의 버퍼 메모리 확보를 위해 설정하며
최근의 OS에서는 기본 설정도 충분하므로 별도 튜닝이 필요 없을수 있습니다.

네트워크 수신 과 송신 버퍼값 지정
- net.core.rmem_default net.core.rmem_max
- net.core.wmem_default net.core.wmem_max

TCP와 UDP 소켓 수신 과 송신에 사용되는 버퍼 크기
- net.ipv4.tcp_rmem , net.ipv4.tcp_wmem
  • net.ipv4.tcp_window_scaling=1
  • net.core.rmem_max = 212992
  • net.core.wmem_max = 212992
  • net.ipv4.tcp_rmem = 4096 87380 6291456
  • net.ipv4.tcp_wmem = 4096 87380 629145

 

기타 TCP 튜닝 파라미터

필요시 추가하는 옵션으로 응답 처리가 완료된 커넥션을 빨리 종료하거나 불필요한 활동을 제한 하는 내용입니다.

TIME_WAIT 으로 인한 SOCKET 고갈 방지

웹서버의 경우 대량의 처리를 하다보면 TIME_WAIT 이 발생합니다. 이때 소켓의 고갈을 방지하기 위해서 다음 파라미터들을 이용합니다.
net.ipv4.tw_reuse는 클라이언트 입장에서 외부로 요청할때 로컬 포트의 TIME_WAIT 상태의 소켓을 재사용할 수 있게 합니다. tcp_tw_reuse 를 사용하려면 net.ipv4.tcp_timestamp를 이용하여 새로운 패킷을 인식 하도록 해야 합니다.
net.ipv4.tw_recycle은 서버 입장에서 TIME_WAIT 상태의 소켓을 빠르게 회수하고 재활용할 수 있게 하지만 권장하지 않습니다.(# net.ipv4.tcp_tw_recycle =0 # CentOs8 deprecated 이며, 사용시 주의를 요하는 변수 입니다. )
시스템이 동시에 유지하는 time-wait 소켓 최대 수 net.ipv4.tcp_max_tw_buckets 도 함께 설정합니다.

  • net.ipv4.tcp_tw_reuse = 1
  • net.ipv4.tcp_timestamps = 1
  • net.ipv4.tcp_max_tw_buckets = 360000 [default 16384]
  • net.netfilter.nf_conntrack_buckets = 16384 [default 16384]
net.ipv4.tcp_timestamps = 0으로 하면 TCP의 부하를 줄일수 있어서 예전에는 disable 상태로 처리 했습니다.

 

FIN_WAIT2이 대량 발생 하는 경우

HTTP 서비스에서 서버는 Keepalive 시간 초과와 같은 경우 연결을 닫습니다. 서버는 연결을 닫고 FIN_WAIT2 상태가 됩니다. FIN_WAIT2상태에 있는 TCP 연결을 쉽게 닫을 수 있도록 매개 변수 "tcp_fin_timeout" 값을 줄이는 것이 좋습니다. net.ipv4.tcp_fin_timeout 의 경우 웹서버의 경우는 5~10초 이내로 줄여 줍니다.

  • net.ipv4.tcp_fin_timeout = 5

 

tcp_keepalive_time은 전송된 마지막 패킷과 첫번째 Keepalive 간격으로 Keepalive 를 유지하는 시간설정 입니다.
keepalive를 사용하는 주된 이유는 종단 시스템 중의 하나가 다운될 때 발생할 수 있는 한쪽만 열린 연결 상태를 정리하는 것입니다.
(기본값 7200은 2시간이며 1200초 20분정도로 네트웍 종단간의 유지 시간을 고려해서 설정하였습니다.)

  • net.ipv4.tcp_keepalive_time = 1200 [default 7200] # 첫 번째 연결 후 유지 프로브를 보내기까지 대기시간
  • net.ipv4.tcp_keepalive_intvl = 75 # default 75초 마다 응답 SYN에 대한 상태 확인을 하는 probe 주기
  • net.ipv4.tcp_keepalive_probes = 9 # default 연속 9 회 동안 ACK 응답이 수신되지 않으면 연결이 끊어진 것으로 판단
http keepalive 와 달리 TCP keepalive는 네트웍 종단간의 연결 상태를 관리하는 주기 입니다. 주로 사용하지 않고 "ESTABLISHED" 된 접속조차도 불필요 한것으로 보고 해제하고 리소스를 반환하기 위한 것들입니다.
기본 값은 아래와 같습니다. (주로 수정하지 않고 쓰는 변수 입니다.)
net.ipv4.tcp_keepalive_intvl = 7200
net.ipv4.tcp_keepalive_intvl = 75
net.ipv4.tcp_keepalive_probes = 9

*) 종종 tcp_keepalive_time = 60~600 등의 튜닝 사례들도 있기는 한데 견해의 차이가 있습니다. 불안정한 네트웍으로 중단된 통신이나, 유휴상태가 된 연결을 빨리 해지하고 반환 할것인지, 또 한번 맺어진 커넥션이 다시 맺어질 것을 고려해서 기다릴 것인지 또는 상대방의 연결이 끊어진것을 빨리 알기 위해 짧게 할 것인지, 또 이런 상태 확인도 시스템의 부하가 될 수 있어서 길게 잡을 것인지 등 다양한 상황에 따른 이해 차이가 있습니다. ( 이값은 네트웍 장애 또는 패킷의 불안정으로 인한 상황를 관리하는 측면에서 사용하는 용도에서 활용에 대한 의견을 내어야 하는 부분이 있습니다. (따라서 사람마다 견해는 차이가 있습니다.)

* 짧게 설정하면 빈번한 상태 확인도 부하라고 보여지고, 종종 DB를 리부팅하거나 웹서버, WAS를 리부팅하는 동안 종단의 네트웍이 유지될 필요가 있다고 봅니다. 또한 client와 모바일, 채팅, 웹에서 재접속이 예상되기 때문에 1200을 예상하였다는 것입니다. 또 NAS 및 DB등의 종료 재접속 리부팅 등 다양한 상황을 고려해서 너무 짧은 것보다 적절한 시간을 설정하여야 합니다. (설정을 하지 않아도 큰차이는 없습니다.)

 

 

2. 파일 연결수 늘리기 (리눅스 환경변수 )

오픈 가능한 파일수 설정

  • fs.file-max = 65536
  • kernel.threads-max = 3261780 [ 시스템이 자동으로 설정되므로 수정 하지 않습니다. ]

 

사용자 제한 해제

현재 사용자의 오픈 가능한 파일수(기본 1024) 에 대한 예상 목표에 따라 늘려 줍니다.

* 기본 사용자 파일 오픈 가능한 수를 확인합니다.
# ulimit -n -u
open files (-n) 1024
max user processes (-u) 22474

 

고성능 서버의 경우 어플리케이션이 스레드가 동시에 처리 할 수 있을 만큼 충분히 높게 설정 합니다.
- /etc/security/limits.conf 나 /etc/security/limits.d/nginx.conf 같은 파일을 만들어서 추가 하면 됩니다.

# cat /etc/security/limits.d/nginx.conf
nginx soft nofile 204800
nginx hard nofile 204800
nginx soft nproc 64000
nginx hard nproc 64000

* soft 는 실제 적용되는 값 , hard 는 soft 가 부족 할 때 hard 값 까지 늘릴 수 있는 max 값

 

systemd (LimitNPROC) 를 이용한 프로세스별 제한 해제 하기

/usr/lib/systemd/system/<servicename>.service 파일을 수정하여 해당 서비스를 재기동 합니다.

[Unit]
Description=Some Daemon
After=syslog.target network.target

[Service]
Type=notify
LimitNOFILE=65536
ExecStart=/usr/sbin/somedaemon

[Install]
WantedBy=multi-user.target

데몬을 재기동 후 설정 상태를 확인 합니다.
- 해당 데몬의 구동되는 PID로 limits 설정을 확인하면 적용된 상태를 확인 할 수 있습니다.

cat /proc/service_pid/limits | grep open
* PID가
2614 인 데몬에 대한 설정을 아래와 같이 확인 가능합니다.

 

* 프로세스에 적용한 한계값 확인 

[root@vm1 sysctl.d]# cat /proc/2614/limits
Limit Soft Limit Hard Limit Units
Max processes 22474 22474 processes
Max open files 65536 65536 files

위와 같이 해당 프로세스에 설정한 값이 적용 되었는지 확인 가능 합니다.

 

3. 리눅스 커널 튜닝 적용 하기

리눅스 커널 파라미터는 /etc/sysctl.conf 나 /etc/sysctl.d/sys_tune.conf 파일로 관리됩니다. 주로 이 두개 파일을 아래와 같이 수정하여 시스템 재기동시 자동으로 로딩되도록 관리합니다.

리눅스 커널 파라미터는 재부팅을 하지 않고 runtime 적용이 가능합니다. 다만 작동 중인 application 은 커널 파라미터를 적용후에 재기동을 해야 새로 설정된 커널 파라미터가 적용 됩니다.

튜닝되는 내용을 sysctl.conf는 "/etc/sysctl.d/sys_tune.conf" 파일을 include 하도록 되어 있어서 별도 파일로 작성 하여 적용 하도록 하겠습니다.

# cat /etc/sysctl.d/sys_tune.conf

# FS Tuneups
fs.file-max = 65536

# Socket Tuneups
net.core.netdev_max_backlog = 20480
net.core.somaxconn = 20480

# NET Tuneups
net.ipv4.tcp_window_scaling=1
net.core.rmem_max = 16000000
net.core.wmem_max = 16000000
net.ipv4.tcp_rmem = 4096 250000 16000000
net.ipv4.tcp_wmem = 4096 250000 16000000

# TCP Tuneups
net.ipv4.tcp_max_syn_backlog = 204800
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_retries1 = 2

# TIME_WAIT
net.ipv4.tcp_tw_reuse = 1
# net.ipv4.tcp_tw_recycle =0 # CentOs8 deprecated
net.ipv4.tcp_max_tw_buckets = 360000 # [default 16384]
net.netfilter.nf_conntrack_buckets = 16384 # [default 16384]

# FIN_WAIT2
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_keepalive_time = 1200


위와 같이 파일을 수정하고 "sysctl -p" 라는 명령을 통해서 sysctl.conf 관련 환경 파일을 런타임에서 리눅스 커널에 적용할 수 있습니다.
(다만 적용 후 해당 프로세스는 재기동을 해야 합니다)

sysctl 명령으로 설정을 적용하는 방법은 아래와 같습니다. 그리고 "sysctl -a " 로 모든 파라미터를 출력하고 적용된 값을 확인 할수 있습니다.



[커널파라미터 적용]

sysctl -p /etc/sysctl.d/sys_tune.conf

[커널 파라미터값을 조회]

# backlog 관련 적용 상태를 확인 합니다.
sysctl -a | grep netdev_max_backlog
sysctl -a -r "backlog"

 

sysctl -p, --load[=<file>]     # read values from file
- 파일을 명시하지 않으면 default 로 "/etc/sysctl.conf"가 로딩 됩니다.

sysctl -a, --all      # display all variables

sysctl -r, --pattern <expression>   # select setting that match expression

 

 

[관련 문헌]

1. couplewith.tistory.com/entry/꿀팁-고성능-Nginx를위한-튜닝-1-디스크의-IO-병목-줄이기

 2. couplewith.tistory.com/entry/꿀팁-고성능-Nginx를위한-튜닝-2-프로세스-처리량-늘리기

 3. (tuning Nginx for Performance ) www.nginx.com/blog/tuning-nginx/

 4. (Nginx core Sendfile) nginx.org/en/docs/http/ngx_http_core_module.html#sendfile

  5. (levelup High performance network) .gitconnected.com/linux-kernel-tuning-for-high-performance-networking

  6. www.alibabacloud.com/help/faq-detail/41334.htm

  7. ( Optimize Network parameters) www.dba-oracle.com/t_linux_networking_kernel_parameters.htm

  8. (리눅스 성능의  TCP 성능을 결정짖는 커널파라미터) meetup.toast.com/posts/55

 

[웹서버 튜닝 목차]

1. 디스크의 I/O 병목 줄이기
2. 프로세스 처리량 늘리기 (Process)
3. TCP 관련 처리량 늘리기
4. 메모리 및 CPU 튜닝하기 (Processor)
5. 마이크로캐싱
6. 로그 부하 줄이기
7. Dos, DDos 방어 설정

 

728x90
반응형