Backlog ?
아래의 그림은 TCP3-Way Handshake 연결 과정을 보여 줍니다.
클라이언트 와 서버 통신과정의
2.SNY+ACK 보낼때 Backlog 큐에 저장 되었다가
3.ACK 올때 Backlog 큐에서 제거 됩니다.
간단하게 설명하자면 서버가 클라이언트에게 응답을 보내고 Backlog 큐에 저장했다가
클라이언트에서 응답을 받게 되면 Backlog 큐에서 제거 하게 됩니다.
초당 들어오는 연결수 가 매우 많을경우 Backlog 큐 저장 하게 되는데
Backlog 큐가 작을 경우 연결 할 때 이슈 발생할 수 있습니다.
그렇때 Backlog 큐 사이즈를 적절하게 증가 해줘야 합니다.
그렇다고 넘 큰값을 사용하게 되면 메모리 낭비하게 됩니다.
레디스의 백로그 값은 레디스 conf(/etc/redis/6379.conf) 파일 안에
tcp-backlog 값을 보시면 됩니다.
tcp-backlog = 511 되어있습니다.
tcp-backlog 511을 1024으로 변경 해보겠습니다.
Linux (ubuntu) 의 syn_backlog, somaxconn 값을 조정
syn_backlog, somaxconn 확인
sysctl -a | grep -i syn_backlog
128
syn_backlog, somaxconn 값 변경
sysctl -w net.core.somaxconn=1024
sysctl -w net.ipv4.tcp_max_syn_backlog=1024
그러다면 somaxconn 뭘까요 ?
soket max connection 약어 이며
syn_backlog 는 위에서 도 설명 했듯이 서버에서 클라이언트에게 SYN +ACK 보내고
Syn Backlog 버퍼에기록합니다.
클라이언트에서 ACK 응답이오면 비워지고 오지않으면 보관한다.
레디스의 backlog 크기는 syn_backlog , somaxconn 설정값을 넘을수 없음
syn_backlog 또는 somaxconn = 128 이면 128 +1 = 129 -> 129 *2 = 258 -> 258 의 근사값 = 256
즉 레디스에서 약 256개 이상 backuplog를 가져갈수 없습니다.
레디스에서는 tcp-backlog 511 이지만 syn_backlog ,somaxconn = 128 이면 256개
밖엔 처리 못합니다 그래서 syn_backlog , somaxconn의 값을 변경해야 합니다.
tcp-backlog 511 처리하기 위해 syn_backlog ,somaxconn 값을
128 에서 256 으로 변경해야 합니다.
syn_backlog ,somaxconn 256 +1 = 257 --> 257 *2 = 514 근사값 512 설정
소캣당 약 80byte 소모 512일때 메모리사용량은 80byte * 512 = 40mb
somaxconn 늘리고 어플리케이션 의 backlog
를 늘려가며 운영하는것이 유리 해 보여서 syn_backlog,somaxconn을 1024 변경 시
레디스에서 2048 까지 backlog를 사용할수 있습니다.
이때 메모리사용량은 약 160Mb 정도입니다.
Backlog TEST
Redis backlog 확인
cat /etc/redis/6379.conf
tcp-backlog 511
Redis 재시작
sudo service redis_6379 restart
부하주기
sudo apt-get install hping3
sudo hping3 -c 100 --flood -d 120 -S -w 64 -p 6379 --rand-source localhost
syn_recv 수 확인
sudo netstat -napo | grep -ic syn_recv
512
시스템에서 backlog , maxconn 확인
sudo sysctl -a |grep tcp_max_syn_backlog
net.ipv4.tcp_max_syn_backlog = 1024
sudo sysctl -a |grep somaxconn
net.core.somaxconn = 1024
결과 syn_recv : 512 이며 시스템에서 backlog , maxconn = 2048 (1024+1 *2의 근사값)
서로 맞지 않음 (Redis config값에 영향을 받음)
Redis tcp-backlog 511을 512변경
cat /etc/redis/6379.conf
tcp-backlog 512
Redis 재시작 부하주기 syn_recv 수 확인
결과 syn_recv : 1024 이며 시스템에서 backlog , maxconn = 2048 (1024+1 *2의 근사값)
서로 맞지 않음 (Redis config값에 영향을 받음)
Redis tcp-backlog 511 을 1024 변경
cat /etc/redis/6379.conf
tcp-backlog 1024
확인과정 (Redis 재시작 -> 부하주기 -> syn_recv 수 확인)
syn_recv : 2048 이며 시스템에서 backlog , maxconn = 2048 (1024+1 *2의 근사값)
서로 맞음
Redis tcp-backlog 511 을 4096 변경
cat /etc/redis/6379.conf
tcp-backlog 4096
확인과정 (Redis 재시작 -> 부하주기 -> syn_recv 수 확인)
syn_recv : 2048 이며 시스템에서 backlog , maxconn = 4096 (2048+1 *2의 근사값)
서로 맞음 (backlog , maxconn 시스템 설정 값 넘지 못함)