Linux IP 라우팅 매개 변수 조정-secret_interval 및 tcp_mem


30

오늘날 HAProxy VM 중 하나에서 약간의 장애 조치 문제가있었습니다. 우리가 그것을 파헤 치자 우리는 이것을 발견했습니다.

1 월 26 일 07:41:45 haproxy2 커널 : [226818.070059] __ratelimit : 콜백 10 개 억제
1 월 26 일 07:41:45 haproxy2 커널 : [226818.070064] 소켓 메모리 부족
1 월 26 일 07:41:47 haproxy2 커널 : [226819.560048] 소켓 메모리 부족
1 월 26 일 07:41:49 haproxy2 커널 : [226822.030044] 소켓 메모리 부족

이 링크 당에 대한 기본 설정이 낮게 설정되어 있어야 net.ipv4.tcp_mem합니다. 그래서 우리는 기본값에서 4 배 증가했습니다 (Linux 풍미가 중요한지 확실하지 않은 우분투 서버입니다).

현재 값은 다음과 같습니다. 45984 61312 91968
새로운 값은 다음과 같습니다. 183936 245248 367872

그 후, 우리는 기괴한 오류 메시지를보기 시작했습니다.

1 월 26 일 08:18:49 haproxy1 커널 : [2291.579726] 해시 체인이 너무 길다!
1 월 26 일 08:18:49 haproxy1 커널 : [2291.579732] secret_interval을 조정하십시오!

... 비밀이야 !!

이것은 분명히 /proc/sys/net/ipv4/route/secret_interval기본값 600과 관련 이 있으며 경로 캐시의 주기적 플러시를 제어 합니다.

secret_interval명령은 커널이 새 / 오래된 수에 관계없이 모든 경로 해시 항목을 얼마나 자주 날려 버리는지를 지시합니다. 우리의 환경에서 이것은 일반적으로 나쁘다. 캐시가 지워질 때마다 CPU는 초당 수천 개의 항목을 다시 작성하는 중입니다. 그러나 메모리 누수를 막기 위해 하루에 한 번 실행되도록 설정했습니다 (아직 없었습니다).

우리는 이것을 줄이면서도 행복하지만 , 단순히 경로 캐시에서 이전 값을 더 빨리 밀어내는 대신 전체 간격 캐시를 정기적으로 삭제하는 것이 좋습니다 .

조사 결과, /proc/sys/net/ipv4/route/gc_elasticity라우팅 테이블 크기를 확인하는 데 더 좋은 옵션 인 것으로 나타났습니다 .

gc_elasticity커널이 라우트 해시 항목 만료를 시작하기 전에 허용 할 평균 버킷 깊이로 가장 잘 설명 할 수 있습니다. 이는 활성 경로의 상한을 유지하는 데 도움이됩니다.

라우트 캐시 정리가보다 적극적으로 실행되기를 희망하여 탄력성을 8에서 4로 조정했습니다. secret_interval우리에게 올바른 느낌 이 들지 않습니다. 그러나 많은 설정이 있으며 실제로 여기에 올바른 방법인지 확실하지 않습니다.

  • / proc / sys / net / ipv4 / route / gc_elasticity (8)
  • / proc / sys / net / ipv4 / route / gc_interval (60)
  • / proc / sys / net / ipv4 / route / gc_min_interval (0)
  • / proc / sys / net / ipv4 / route / gc_timeout (300)
  • / proc / sys / net / ipv4 / route / secret_interval (600)
  • / proc / sys / net / ipv4 / route / gc_thresh (?)
  • rhash_entries (커널 매개 변수, 기본 불명)?

우리는 리눅스 라우팅을 악화시키고 싶지 않기 때문에 이러한 설정 중 일부를 망쳐 놓는 것을 두려워합니다.

트래픽이 많은 HAProxy 인스턴스에 대해 어떤 라우팅 매개 변수를 조정하는 것이 가장 좋은지 조언 할 수 있습니까?

답변:


28

이 문제가 발생하지 않았습니다. 그러나 깊이를 줄이려면 해시 테이블 너비를 늘려야합니다. "dmesg"를 사용하면 현재 몇 개의 항목이 있는지 볼 수 있습니다.

$ dmesg | grep '^IP route'
IP route cache hash table entries: 32768 (order: 5, 131072 bytes)

커널 부팅 명령 줄 매개 변수를 사용하여이 값을 변경할 수 있습니다 rhash_entries. 먼저 손으로 시도한 후 lilo.conf또는에 추가하십시오 grub.conf.

예를 들면 다음과 같습니다. kernel vmlinux rhash_entries=131072

HAProxy VM에 적은 메모리를 할당했기 때문에 해시 테이블이 매우 제한적일 수 있습니다 (라우트 해시 크기는 총 RAM에 따라 조정 됨).

에 대해 tcp_mem조심하십시오. 초기 설정으로 인해 1GB의 RAM으로 실행 중이고 1/3은 TCP 소켓에 할당 될 수 있다고 생각합니다. 이제 367872 * 4096 바이트 = 1.5GB의 RAM을 TCP 소켓에 할당했습니다. 메모리가 부족하지 않도록 매우주의해야합니다. 일반적으로 1/3의 메모리를 HAProxy에 할당하고 다른 1/3을 TCP 스택에 할당하고 마지막 1/3을 나머지 시스템에 할당합니다.

"소켓 메모리 부족"메시지가 tcp_rmem및의 기본 설정에서 비롯된 것 같습니다 tcp_wmem. 기본적으로 각 소켓의 출력에는 64kB가 할당되고 입력에는 87kB가 할당됩니다. 이는 소켓 버퍼에 대해서만 프록시 연결의 경우 총 300kB를 의미합니다. HAProxy의 경우 16 또는 32kB에 추가하면 1GB의 RAM으로 3000 개의 연결 만 지원한다는 것을 알 수 있습니다.

tcp_rmemand tcp_wmem(middle param) 의 기본 설정을 변경하면 메모리를 훨씬 더 줄일 수 있습니다. 쓰기 버퍼의 경우 4096만큼 낮고 tcp_rmem(5 또는 11 개의 TCP 세그먼트) 에서 7300 또는 16060으로 좋은 결과를 얻습니다 . 다시 시작하지 않고 해당 설정을 변경할 수 있지만 새 연결에만 적용됩니다.

당신이 당신의 터치하지 않으려면 sysctls을 너무 많이, 최신 HAProxy, 1.4 dev8, 당신은 글로벌 구성에서 이러한 매개 변수를 조정할 수 있으며, 측면 당 (클라이언트 또는 서버).

도움이되기를 바랍니다.


8

Out of socket memory error종종 오해의 소지가있다. 대부분 인터넷 연결 서버에서는 메모리 부족과 관련된 문제를 나타내지 않습니다 . 블로그 게시물 에서 훨씬 자세하게 설명했듯이 , 가장 일반적인 이유는 고아 소켓의 수입니다. 고아 소켓은 파일 디스크립터와 관련이없는 소켓입니다. 어떤 상황에서는 커널이 Out of socket memory error한계 ( /proc/sys/net/ipv4/tcp_max_orphans) 에서 2 배 또는 4 배 떨어져 있어도 문제가 발생합니다 . 이는 인터넷 연결 서비스에서 자주 발생하며 완벽하게 정상입니다. 이 경우 올바른 조치는 tcp_max_orphans일반적으로 피크 트래픽에서 일반적으로 보는 고아 수의 4 배가되도록 조정하는 것입니다.

튜닝 권장 어떤 조언을 듣지 마십시오 tcp_mem또는 tcp_rmem또는 tcp_wmem당신이하지 않으면 정말 당신이 무슨 일을하는지 알고있다. 이러한 조언을하는 사람들은 일반적으로 그렇지 않습니다. 그들의 부두는 종종 귀하의 환경에 맞지 않거나 부적절하며 문제를 해결하지 못할 것입니다. 심지어 악화시킬 수도 있습니다.


1
이 경우 dmesg에서 메시지가 다르면 "고아 소켓이 너무 많습니다"라는 메시지가 나타납니다. 그러나 고아는 엄청난 양의 메모리를 소비 할 수 있다는 데 동의합니다.
Willy Tarreau

당신이 수를 초과하면 /proc/sys/net/ipv4/tcp_max_orphans다른 오류가 발생합니다. 예를 들어 전체 스택 교환 스택 /proc/sys/net/ipv4/tcp_max_orphans은 65536이며 /proc/net/sockstatTCP를 사용합니다. inuse 2996 orphan 171 tw 15972 alloc 2998 mem 1621-무시할 수없는 차이.
Geoff Dalgas

-4

이러한 매개 변수 중 일부를 정기적으로 조정합니다. 높은 처리량, 낮은 대기 시간 거래 플랫폼에 대한 표준은 다음과 같습니다.

net.ipv4.tcp_rmem = 4096 16777216 33554432
net.ipv4.tcp_wmem = 4096 16777216 33554432
net.ipv4.tcp_mem = 4096 16777216 33554432
net.core.rmem_default = 16777216
net.core.wmem_default = 16777216
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.netdev_max_backlog = 30000
net.core.netdev_max_backlog = 30000

1
Willy의 수학에 따르면 표준 메모리 압력 # (중간 숫자)은 68GB입니까?! 세 번 (rmem, wmem, mem) ??
Jeff Atwood

10
이 튜너 블은 잘못되었으며 벤치 환경에서 자주 찾아서 맹목적으로 복사하여 붙여 넣습니다. 몇 개의 동시 세션에는 아무런 문제가 없지만 100 개의 TCP 소켓에서도 3.2GB의 RAM을 할당합니다. 대기 시간이 짧으면 의심되는 것이 없습니다. 전송 중에 원격 시스템의 플러그를 뽑아서 출력 버퍼가 채워지거나 로컬 작업이 중지되고 입력 버퍼가 채워지는지 확인하면됩니다. 이것은 미쳤다 ...
Willy Tarreau

6
제프, 이건 3 번이 아니에요 tcp_mem은 페이지에 있으며 전체 크기를 정의합니다. tcp_rmem 및 tcp_wmem은 바이트 단위이며 소켓 별 크기를 정의합니다.
Willy Tarreau

작은 데이터를 가진 동시 서버의 경우 너무 많은 소켓 버퍼를 예약하고 싶지 않으며 tcp_mem은 r / wmem과 완전히 다르며 동일한 숫자를 사용하면 실제로 의미가 없습니다 (하나는 Connections 당 바이트입니다. 시스템 당 페이지 수)
eckes
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.