오늘 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배 늘렸습니다(이것은 Ubuntu Server이며 Linux 버전이 중요한지 확실하지 않습니다).
현재 값은 45984 61312 91968입니다. 새로운 값은 다음과 같습니다: 183936 245248 367872
그 후, 이상한 오류 메시지가 나타나기 시작했습니다.
Jan 26 08:18:49 haproxy1 kernel: [ 2291.579726] 경로 해시 체인이 너무 깁니다! Jan 26 08:18:49 haproxy1 kernel: [ 2291.579732] secret_interval을 조정하세요!
쉿..그것은 비밀!!
/proc/sys/net/ipv4/route/secret_interval
이는 분명히 기본값이 600이고 컨트롤이 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(커널 매개변수, 기본값을 알 수 없음?)
우리는 Linux 라우팅을 만들고 싶지 않습니다.더 나쁜, 그래서 우리는 이러한 설정 중 일부를 엉망으로 만드는 것을 두려워합니다.
트래픽이 많은 HAProxy 인스턴스에 대해 어떤 라우팅 매개변수를 조정하는 것이 가장 좋은지 조언해 줄 수 있는 사람이 있습니까?
답변1
나는이 문제를 겪은 적이 없습니다. 그러나 깊이를 줄이려면 해시 테이블 너비를 늘려야 할 수도 있습니다. "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의 경우 16kB 또는 32kB를 추가하면 1GB RAM에서는 3000개의 연결만 지원한다는 것을 알 수 있습니다.
tcp_rmem
및 (중간 매개변수) 의 기본 설정을 변경하면 tcp_wmem
메모리 사용량을 훨씬 줄일 수 있습니다. 쓰기 버퍼의 경우 4096만큼 낮은 값, tcp_rmem
5개 또는 11개의 TCP 세그먼트에서는 7300 또는 16060의 값으로 좋은 결과를 얻었습니다. 다시 시작하지 않고도 해당 설정을 변경할 수 있지만 해당 설정은 새 연결에만 적용됩니다.
만지고 싶지 않다면sysctls최신 HAProxy 1.4-dev8을 사용하면 전역 구성 및 측면(클라이언트 또는 서버)별로 해당 매개변수를 조정할 수 있습니다.
이것이 도움이 되기를 바랍니다!
답변2
오해 Out of socket memory error
의 소지가 있는 경우가 많습니다. 대부분의 경우 인터넷에 연결된 서버에서는 다음과 같습니다.~ 아니다메모리 부족과 관련된 문제를 나타냅니다. 내가 훨씬 더 자세히 설명했듯이블로그 게시물, 가장 일반적인 이유는 고아 소켓의 수입니다. 고아 소켓은 파일 설명자와 연결되지 않은 소켓입니다. 특정 상황에서는 Out of socket memory error
한계( )에서 2배 또는 4배 떨어져 있어도 커널이 를 발행합니다 /proc/sys/net/ipv4/tcp_max_orphans
. 이는 인터넷 연결 서비스에서 자주 발생하며 완전히 정상적인 현상입니다. 이 경우 올바른 조치는 tcp_max_orphans
트래픽이 최고조에 달할 때 일반적으로 나타나는 고아 수의 최소 4배가 되도록 조정하는 것입니다.
튜닝 을 권장하는 조언을 듣지 마십시오 tcp_mem
.tcp_rmem
tcp_wmem
정말당신이 무엇을하고 있는지 알아요. 이러한 조언을 제공하는 사람들은 일반적으로 그렇지 않습니다. 그들의 부두교는 종종 귀하의 환경에 틀리거나 부적절하며 귀하의 문제를 해결하지 못할 것입니다. 상황을 더욱 악화시킬 수도 있습니다.
답변3
우리는 이러한 매개변수 중 일부를 정기적으로 조정합니다. 높은 처리량, 낮은 대기 시간 거래 플랫폼에 대한 우리의 표준은 다음과 같습니다.
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