본문 바로가기

서버운영 (TA, ADMIN)/분산처리

[분산처리] 서버 제작의 여러 방식

네트워크 방식에 대한 이슈

우선, 네트워크 관련 이슈 중 첫번째로 소켓 이벤트 핸들링(소켓 Event Handling)에 대해 알아보려고 합니다. 요즘 많은 핸들링 방식 중에 IOCP(IO Completion Port)가 가장 최적의 기술로 자리 매김하고 있는 추세인데, 초기에는 IOCP의 구현 자체에 중점을 두었다면, 요즘에는 IOCP를 사용해서 데이터를 처리하는 구조에 대한 이슈가 좀 더 많은 편입니다. 즉, 기본적인 Thread Pooling을 기초로 해서 서버의 환경과 목적에 따라 어떤 방식의 처리 프로세스(Process)를 가지는 것이 좋은가에 대한 이슈들이라고 볼 수 있습니다. 그래서 앞으로 IOCP와 관련된 이슈로 알아볼 내용은 IOCP가 어느 정도 좋은 가를 확인하기 위해서 Windows에서 제공되는 여러 소켓 이벤트 핸들링 방식들을 제작하고, 그것들과 성능 비교를 통해 IOCP의 진가를 알아보려고 합니다. 비교해 볼 방식들로는 Berkeley 소켓을 기반으로 한 Winsock 1.x 기반의 select 방식, Winsock 2.x 기반의 WSAEventselect 방식, Windows Message를 이용한 WSAAsyncSelect 방식, Overlapped Callback 방식들이 있으며 각각의 성능을 평가해 볼 예정입니다. 그 후 IOCP 방식으로 서버를 제작하여 앞의 방식들과 비교 벤치마크하려고 합니다. 벤치마크가 완료되면 IOCP를 어떻게 사용하는 것이 좋은지에 대한 내용을 알아볼 예정입니다. WorkerThread에서 직접 모든 데이터를 처리하는 편이 나은지, 아니면 Process 스레드를 따로 구성하는 것이 나은지를 알아보는 내용이 될 예정입니다. 물론, 이 부분은 우리가 주제로 하는 온라인 게임 서버를 기반으로 이야기될 예정입니다.



소켓 이벤트 핸들링 비교

 명칭

 Winsock 버전

 Berkely 호환

 IO 방식

 select

 Winsock 1.x

 호환

 Event 방식

 WSAEventSelect

 Winsock 2.x

 비호환

 Event 방식

 WSAAsyncSelect

 Winsock 2.x

 비호환

 Event 방식

 Overlapped Callback

 Winsock 2.x

 비호환

 Callback 방식

 locp

 Winsock 2.x

 비호환

 locp 방식



프로세스 데이터 핸들링 비교

 방식

 패킷

 대표적인 종류

 메모리

 예상 결과

 Non Queue

 아주 작음

 에코(Echo) 서버

 아주 작음

 매우 빠름

 CircularQueue

 보통

 웹, 게임 서버

 CircularQueue의 크기

 빠름

 locpQueue +
 MemoryPool

 보통

 웹, 게임 서버

 패킷 양의 처리 속도에 따라 다름

 빠름


네트워크 관련 이슈 중 두번째는 Accept 핸들링에 관련된 내용입니다. 사실 서버를 제작할때 가장 크게 Overhed가 걸리는 시점은 바로 Accept와 Disconnect입니다. 그만큼 구조와 제작 방식이 중요한 부분입니다. 현재 Accept 핸들링은 AcceptEx가 최선의 선택이라는 결론에 도달해 있는 상태입니다. 하지만 이 AcceptEx를 어떻게 사용하는지에 대해서는 아직 의견이 분분한 상태입니다. Accpet 핸들링에 대해서는 우선 AcceptEx와 그 외의 Barkely 소켓 기반의 accept, Winsock 2.x 기반의 WSAAccept를 비교해 보고, AcceptEx를 Pooling하는 방식과 Pooling을 하지 않는 방식으로 비교해 보겠습니다.


 명칭

 Winsock 버전

 Barkely 호환

 방식

 Read 가능

 accept

 1.x

 호환

 Event

 불가

 WSAAccept

 2.x

 비호환

 Event

 불가

 AcceptEx + Non-Pooling

 2.x

 비호환

 locp

 가능

 AcceptEx + Pooling

 2.x

 비호환

 locp

 가능


네트워크 이슈 중 세번째는 Nagle입니다. Nagle의 경우는 아직도 쓰는 것이 좋은 건지, 아니면 안 쓰는 것이 좋은 건지 결론이 나지 않은 부분이 많습니다. 여기에서는 온라인 게임 서버에서 Nagle을 사용하는 것이 좋은지에 대한 벤치마크를 주로 다루게 됩니다.


 방식

 설명

 Nagle

 일반적인 방식

 Non-Nagle

 속도를 요하는 패킷에서 주로 사용



메모리 관리에 대한 이슈


메모리 관리에 대한 이슈는 총 3가지 입니다. 사실 메모리 관리 기법은 이 3가지를 제외하면 없다고 보아도 좋습니다. 첫번째로는 일반적으로 C/C++을 처음 배우면서 가장 일반적으로 사용하게 되는 malloc/free, new/delete를 할 때 성능에 대해 알아보려고 합니다. 알려진 바로는 new를 할 때보다 delete를 호출할 때 더많은 시간이 소요된다는 이야기가 있는데, 이 부분을 다루면서 이러한 부분까지 확인할 예정입니다. 그 다음으로 알아볼 관리방식은 Static Allocation입니다. 이것은 사실 C에서 많이 사용되는 방식인데, C++로 넘어오면서 객체지향 언어에는 어울리지 않아 성능을 위해 구조를 버리는 형태가 되어버린 방식입니다. 하지만 아직도 속도면에서 많은 이득이 있어 여전히 많은 프로그래머들이 애용하고 있는 방식입니다. 세번째 Memory Pooling에 대해서 알아보도록 하겠습니다. 구조는 정적할당인데, 사용 방식은 동적할당(Dynamic Allocation)처럼 사용하고 제작될 예정입니다. new/delete가 행해질 때마다 미리 잡아두었던 정적 메모리 내에서 포인터 이용해서 빈 블록의 메모리 주소를 받아오는 방식입니다. 이 방식은 C++ 책에서도 여러 번 소개되고 있으니 참고바랍니다. 이렇게 3가지를 메모리 관리에 대한 이슈로 알아볼 예정입니다.


 방식

 속도

 메모리 사용량

 구조화

 동적 할당

 느림

 많음

 높음

 정적 할당

 빠름

 많음

 낮음

 메모리 풀

 빠름

 많음

 높음



데이터베이스에 대한 이슈


제목 자체는 데이터베이스에 대한 이슈이지만, 사실 데이터베이스 설계 및 쿼리(Query)에 대한 이슈보다는 데이터베이스 프로토콜(Database Protocol)의 이슈와 벤치마크에 대한 내용이 중심이 됩니다. 우선은 ODBC, ADO, OLEDB를 사용한 데이터베이스 접근 방식에 대한 각각의 구현 방식을 알아보고, 장단점, 그리고 성능을 평가해 볼 예정입니다. 아직도 ODBC 라이브러리 자체가 가벼워 성능이 더 좋다. ADORDB 환경에서는 더 유리하다 등의 이슈들이 많기에 우선은 라이브러리 자체의 성능을 검증하는 것 역시 필요합니다.


 명칭

 속도

 사용도

 개발 방식

 ODBC

 빠름

 어려움

 API

 ADO

 보통

 쉬움

 COM

 OLEDB

 보통

 쉬움

 COM