레이블이 buffer인 게시물을 표시합니다. 모든 게시물 표시
레이블이 buffer인 게시물을 표시합니다. 모든 게시물 표시

2011년 3월 18일 금요일

permit overflow in receiving buffer of socket stream

보통 socket connection당 공평하게 동등한
recv buffer size(socet에서 memory로 읽어들이는 버퍼)를 유지한다.
socket buffer size도 마찬가지이다.

socket buffer는 full이 나거나 ready가 안될때 would block이 발생하는데,
would block이 발생하는 경우는 send측에서 알아서 처리하게 된다.
(기다렸다가 재시도 한다.)
그러므로, socket buffer에 대해서는 size와 option(nagle 과 같은) 대해서만 신경쓰면 될 것 같다.

recv의 경우는 socket buffer에 읽을꺼리가 있는데, 프로그래머가 정한 recv buffer가 full이 될 경우에 어떻게 처리할까?
buffer를 늘려서 읽어 놓거나, 읽는 것을 나중에 하는 일이다.
선택에 달린 문제일 것이다.

1) buffer를 늘리고 읽는 정책으로 한다면,
특정 connection에만 읽게 해주게 되서, 사소한 특혜같은 것이 생긴다.
logic에서 제때 처리를 못해주면, 다시 또 buffer overflow가 생길 수 있다.
메모리를 재할당해야하는 부담감도 생길 수 있다.
잦은 재할당은 메모리 fragmentation으로 이어져 성능에 결국 악영향을 줄 것이다.
재할당을 해야 하면 사용하던 pointer도 invalidate되어서, zero copy가 힘들어진다.
또한, 멀티쓰레드 환경에서는 lock을 해야 할 것들이 한두개라도 더 많아진다.
다만, IO에서는 delay가 생기지 않는다.

2) buffer size를 절대적으로 고정한다면,
recv event에도 무시하고, recv buffer가 비워지고 읽을 수 있을때까지 기다려야 한다.

메모리 재할당은 없다.  따라서, zero copy가 가능해진다.
읽지 않더라도 socket buffer 에 쌓이게 되므로, 잃어버릴 염려는 없다.
다만, recv buffer가 비워질때까지의 시간만큼 io에서 delay가 생기는 것이다.
최소한 recv event round(event round time)까지 기다려야 하고, 그때도 비워지지 않는다면, 다시 기다려야 할 것이다.
그러나, 리얼타임서버의 임무는 요청을 일정시간 내에 응답해야하고, 더우기 모든 유저들에게 동등하게 처리해줄 의무가 있는 서버라면, logic round time도 존재한다.
logic round time이란, 요청된 request를 모두 소화하는 시간으로 정의할 수 있을 것이다.

클라이언트 입장에서 허용되는 maximum latency(client permit latency?)를 50ms라고 한다면,
network latency(C->S + S->C) + logic round time + event round time < 50ms 이어야 할 것이다.

* 나는 buffer size 를 고정하기로 했다. ( file transfer용 서버가 아니라면 말이다. )

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

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

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