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용 서버가 아니라면 말이다. )

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