2011년 3월 13일 일요일

circular queue buffer

나는 client socket으로부터 recv를 한 후에, packet parsing을 위해 저장을 해 둘 buffer로 circular queue 형식의 buffer를 사용한다.
그것은 고정 사이즈이다.
그 이유는 다음과 같다.

예를 들어, user(connection)당 100KB의 buffer를 정해 놓았다면, 최대 6만명(60k)이 동시에 접속한다면, 6000MB=6GB의 메모리를 사용하게 된다.
그런데, user당 할당되는 100KB의 사이즈는 서비스의 성격에 따라 달라져야 한다.
왜냐하면, 100KB의 의미는, pending packet들의 크기의 합의 최대치이다.
파일 전송과 같은 전송을 위해서는, 100KB는 모자랄 것이다. 요즘 인터넷 속도는 평균적으로 10~100Mbps(bits per sec)정도로 봐야 하기 때문이다.
속도가 1~10MBPS(bytes per sec)에서 100KB의 버퍼로 원활히 서비스 하려면,
100KB의 버퍼의 처리 속도로는 초당 100~1000번 버퍼를 비울 수 있어야 한다.

즉, 버퍼를 비우는 속도가 인터넷으로 들어오는 upload 속도보다 느리다면, buffer는 full이 날 것이다. 이런 경우는 서비스를 유지할 수 없다.

매우 빠른 액션 게임과 같은 경우에는 버퍼를 빠르게 비울 수 있어야 할 것이다.
그보다 느린 MMORPG의 경우는 그 보단 버퍼의 크기가 크지만, 버퍼를 비우는 속도는 그 보단 느려도 될 것이다.
이러한 인터넷속도,버퍼크기,버퍼 비우는 속도(througput)를 고려하여 버퍼의 크기를 정하여야 하고, 적당한 circular buffer size를 정하여야 할 것이다.
또한, socket내의 buffer size option과 nagle option등도 정하여야 할 것이다.

만약 계산적으로 적절한 socket buffer size,option, 그리고 buffer size까지 정하였다면, 비정상적인 최대치도 계산이 될 것이다. 그에 맞게 circular queue buffer size를 정하고, 비정상인 경우는, abrnomal state로 생각하여, 오류 처리를 해주면 된다. 즉, buffer size를 동적으로 늘리면 안된다는 뜻이다. 만약, DDoS공격이라도 온다면, 비정상 커넥션은 빨리 끊어주는 것이 필요한 것이다.

반면에, 웹서버는 close될때까지 한번의 리퀘스트만 하는 것이므로, 버퍼는 필요없고, 모두 저장해 놓으면 된다. 그리고 핸들러에게 넘겨주면 되는 간단한 작업이다.

도움이 되셨다면, 광고 클릭을 ㅎㅎ ^^