SYN Backlog Queue

NightMiya827·2023년 12월 17일
0

(블로그 이사하면서 옮겨진 글입니다)

네트워크 연결하는 코드를 테스트하다가 과하게 많은 요청이 빠르게 오면 연결을 거부하는 듯한 동작을 하는 것을 발견하였다. 이유를 찾다보니 backlog라는 개념을 접하고, 한번에 수백, 수천개의 connection 연결이 요청을 하는 경우에 실패하는 이유를 설명하는 블로그 글을 찾았다. 많은 네트워크 요청을 관리하는 경우 자주 접하는 문제인지 클라우드플레어, 알리바바, 네이버 등 대규모 웹서비스를 운영하는 사람들의 글을 몇개 찾을 수 있었다.
글에는 많은 내용이 있었지만, 결국 알고싶은 내용은 '한번에 많은 요청이 왔을 때 처리할 수 있는 방법' 단 한가지이다. 그리고 그걸 위해서 알아야하는 핵심이 '백로그 크기를 어떻게 설정해야하는지'이다. 하지만 슬프게도 백로그 크기가 작으면 많은 요청을 받을 수 없고, 크기가 무작정 크다고 좋은 것도 아니다. 그래서 많은 사이트들이 TCP연결과정부터 시작해서 엄청나게 많은 이야기를 거친 다음에야 무엇을 어떻게 설정해야하는지에 대해 설명한다.
이 글에서는 최대한 많은 설명을 참고자료로 넘기고 'backlog가 뭐고, 이걸 어떻게 설정해야하는가'에 대해서만 간략하게 설명하려고 한다.

SYN Backlog Queue

TCP연결은 3way handshake과정을 통해서 이루어진다. 그리고 서버는 클라이언트와 연결을 맺기 위해서 연결 요청을 받았다는 사실을 handshake과정이 끝나기 전까지 어딘가에 저장하고 관리할 필요가 있다. 이 때 저장에 사용되는 것이 SYN를 받았다는 사실을 기록하는 SYN backlog Queue이다.(글에 따라서 SYN Queuebacklog Queue등으로 부르기도 한다.) 그리고 서버 코드에서는 연결이 맺어지고나면 accept와 같은 함수를 이용해서 관리하게 되는데, 이를 위해서 연결이 맺어졌지만 accept되지 않은 연결을 관리하는 accept Queue가 추가로 필요하다. 여기에 대한 상세한 설명은 이 블로그가 상세히 설명하고 있다. 그리고 운좋게도 한글로 설명한 블로그도 존재하며 설명이 상당히 잘 되어있다.

SYN Backlog Queue는 작으면 안된다

당연하게도 큐 사이즈는 정상 요청도 충분히 처리할 수 없을만큼 작으면 안된다. 그리고 큐 사이즈가 너무 작으면 안되는 이유가 한가지 더 있는데, 백로그 큐 사이즈가 작으면 SYN Flood Attack이라는 DDOS 공격에 취약해진다. SYN Flood Attack은 간략히 말하면 클라이언트가 SYN만 무수히 많이 보내고 ACK를 보내지 않아서 SYN Backlog Queue를 가득차게 만들어서 다른 사람이 연결을 맺지 못하게 만드는 공격이다. 이것도 당연하게도 큐의 사이즈가 크면 그만큼 발생시키기 힘들어진다. 이 공격에 대한 자세한 내용과 대응 방법은 cloudflare에서 잘 설명해주고 있다.

SYN Backlog Queue는 크면 안된다?

을 보면 사이즈를 너무 크게 잡는 것도 권장하지 않는데, 그 이유는 메모리를 쓸모없이 많이 사용할 수 있기 때문이다.
그리고 일정 이상 사이즈가 커지면 다른 문제들도 있을 수 있다. 실제로 SYN Backlog Queue를 크게 변경하는 과정을 보면 Accept Queue의 사이즈도 커져야하고, 파일 관련 설정, 쓰레드 설정 등 많은 것을 수정해야한다. SYN 큐 사이즈가 커지는 것에 위험성이 별로 없다는 것이 Thread 관련 설정을 바꾸는 것에 위험성이 별로 없다는 것을 의미하지는 않기 때문에, 이런 과정을 통해서 어느 수준 이상으로 사이즈를 크게 만드려는 경우에는 주의할 필요가 있다.

SYN Backlog Queue의 적절한 수치 찾기

SYN Backlog Queue를 크게 변경하는 과정에 대한 글의 마지막을 보면 SYN Backlog Queue의 사이즈를 Accept Queue이상, 최대 연결 수 이하의 사이즈로 설정하라고 되어있다. 또한 Accept Queue의 사이즈는 쓰레드 수의 20~25%로 설정하는 것을 권장하고있다. 무작정 크다고 좋은게 아니라는 걸 고려해서 이 구간안에서 적절히 큰 값으로 설정하면 될 듯 하다. 참고로 기본 백로그 크기는 VMWare에서 1280, linux에서 4096, winsock2에서 수백~수천이라고 되어있다. 하지만 winsock2에서 초기값은 200 고정값으로 사용되고 있는 것으로 보인다.

부록: Windows backlog

다른 사례들을 살펴보면 많이들 backlog queue사이즈를 1000이상으로 설정해두고 있는데 윈도우에서는 200이 기본값으로 나온다. 왜 200일까? 확실한 사실은 찾지 못했지만, 여기를 보면 "Max I/O completion threads was always 1000"으로 쓰레드 개수가 1000개이고, 위에서 쓰레드 수의 20~25% 이상이 적절하다는 권장사항을 확인하였다. 1000개의 20%가 200개이니, 200개가 나름대로 의미있는 숫자로 보인다. 하지만 이 문서의 내용을 보면 200이라는 숫자는 윈도우 8 시절 이전에 정해진 숫자인 듯 하고 그 사이에 많은 기술적 변화가 있었으니 이제는 더 큰 사이즈를 기본 값으로 제공해줘도 될 것 같다는 생각이 든다.
linux도 5.4버전에서 4096으로 늘려준 것이고 이전에는 128이었다. 5.4가 19년에 나왔고, 우분투 기준 20.04에서 적용되었으니 백로그 사이즈가 획기적으로 늘어난 것도 아직 3~4년밖에 되지않았다. 그러니 윈도우도 12가 나올 때에는 좀 방법을 찾아서 늘려주지 않을까...

0개의 댓글

관련 채용 정보