[토론] 서버 성능에 대한 네트워크 서버 실무자와의 대담 -_-;

mastercho의 이미지

약 2만명의 클라이언트에 대한 I/O처리에 관한 내용이었습니다

쓰레드를 어느정도 많이 두고 처리하는거와 극도로 적게 1-2개만 두고 처리하거와에 대한 의견이 많이 갈렸는데

일단 쓰레드당 poll를 두고 처리한다는 가정에서 밑에 경우가 나왔습니다 [ recv하는것만 따짐 ]

case 1
recv가 분명 블럭킹 모드의 소켓을 호출한것이므로 커널 모드로 떨어지게 되고 커널에서 프로세스로 복사가 이루어진다

또한 블럭킹이 된다 , [블럭킹 소켓이니 블럭킹 recv가 된다는 말입니다..] 따라서

약 2만명의 사용자가 있고 2만명의 사용자의 recv를 받아야 하는 쓰레드가 있는데 하나의 쓰레드가 처리할

수도 있지만 , 많은 양의 recv가 생길 경우

더 쓰레드를 두어 [쓰레드당 사용자를 나누어서 poll recv 처리] 처리하면 더 많은 양의 처리가 가능하다

case 2
recv (read i/o)[poller에서 리턴되어진 상태]가 가능한 경우 데이터를 읽는 시스템 콜을 호출했을경우에 블라킹 되지 않고

recv가 블라킹 되지 않고 리턴한다. io시에 recv을 할경우 이 쓰레드가 cpu을 충분히 사용하고 있다면 더이상의 쓰레드 필요없

이 충분히 최고의 성능을 낼수 있다.

둘다 같은 환경에서입니다 ( 대략 1 CPU[1기가] 1기가 램정도로 보고요)

이런 의견이 나왔거든요

저 같은 경우 1번을 주장했지만 오래동안 실무에서 서버 어플리케션을 만지신분이 2번 즉 recv를 해도[블럭킹 소켓]
poller에서 recv가능한 상태로 리턴하였기때문에 블럭킹이 되지 않고 바로 카피후 리턴된다는거였습니다

따라서 1 case처럼 2만명이 있다면 약 50개정도로 유저를 쓰레드당 400 유저를 분산해 poller을 두고 recv 하는거와

case2처럼 단일 혹은 2개 쓰레드의 극소수의 쓰레드에서 recv만하는게 , 50개의 쓰레드를 두는것보다 훨씬 유리하다는거와

어느쪽 의견이 맞는지 궁금해 몸이 간질거려 숨 넘어거 갈거 같네요

많은분들의 답변좀 부탁드리겠습니다

windpipe의 이미지

적정 쓰레드 갯수는 2* cpu갯수 혹은 2* cpu갯수 + 2 로 알려져 있습니다.

어떤 Poller를 쓰느냐에 따라 조금은 달라지겠지만,

iocp, kqueue, select, poll, epoll, /dev/poll 등에서는 위 공식을 따라주는 것이 좋습니다.

1,2 번을 고르라면, 2번이 가깝겠습니다.

lightwind의 이미지

여러가지가 있지 않을까요.. 환경에 따라...
그러나 시스템이 멀티쓰레딩을 지원한다면 ( 아시다시피 현재의 대부분의 시스템은 멀티쓰레딩에 적합하도록 설계되어 있지 안습니까? ) 이경우 적정량의 쓰레드는 전체적인 시스템의 효율을 높여 줍니다.

게다가 하이퍼쓰레딩과 같은 보다 효율적인 기법이 나오긴 했지만 시스템 IO는 아직도 대부분의 시스템에서 최상위의 작업이며 이때는 CPU도 잠시 멈출( Idle )해 질정도로 강력한 쓰레드 우선순위를 배정받습니다.
따라서 IO 작업을 하는 동안 다른 일을 효율적으로 수행하도록 구현하는 것은 상당히 어렵습니다. 따라서 IO를 제어하는 쓰레드 일수록 그 수가 적을 경우에는 고도로 설계한다하여도 병목현상이 오기 쉽습니다.

주위에서 볼 수 있는 가장 훌륭한 쓰레드 시스템 중에 하나가 상용 DBMS인데요. 잘아시겠지만 DBMS는 잘 고안된 쓰레딩 기법을 사용해서 설계되었을 뿐더러 자체에 부하분산 시스템과 IO채널을 가지고 있습니다. 그럼에도 ( 하나의 DBMS내에서 ) 데이터베이스 제어 프로세스를 한둘 또는 몇개만 열어놓고 쓰는 경우는 없다는 것을 예로 들겠습니다.

따라서 제생각에는 보편적인 멀티스레딩 운영체제 상에서 다수의 IO처리를 위해서 극소수의 스레드로 운영한다는 것은 많은 문제점을 양산할 거라고 생각합니다. 물론 보편적인 운영체제하에서 그렇다는 전제입니다. 특수한 시스템에서는 극소수의 스레드가 전체적인 효율면에서 우수할 수도 있겠지요. 미사일처럼.

익명 사용자의 이미지

저는 구현상 편의를 전혀 고려하지 않고 성능을 최고우선으로
많은 튜닝을 할수 있는 여유가 있다면 2번을 택하겠습니다.
우선 그 전에 해당 서버외에 다른 서비스를 하지 않는다면 이라는 조건판단이
좀 고려되어야 할거구요.

하지만 보통의 경우 그만한 여유가 없다는 생각이 들고
그리하여 결국 1번을 택하지 않을까 생각됩니다.

이유는 직접 해보면 설명이 필요없을듯 합니다. (아닐려나?)

그냥 제 생각일뿐이니 딴지 걸기 없기.

ihavnoid의 이미지

극단적으로 thread가 적거나 많거나 하지 않다면 쌤쌤이가 아닐까 하는 생각이 듭니다.... task가 어떤 것인지 정확히는 모르겠지만, 병목지점이 어차피 CPU가 아니라 I/O 버스일 것이라는 생각입니다....

좀 더 자세한 것은 일의 성격(1개의 query를 처리하는 데에 드는 시간의 part별 비율 같은 것들)을 알아야 할 수 있을 것 같습니다...

저같으면 그냥 구현하기 편한 걸루 하겠습니다...-0-
그냥 비전문가의 찍기였습니다-0-

Consider the ravens: for they neither sow nor reap; which neither have storehouse nor barn; and God feedeth them: how much more are ye better than the fowls?
Luke 12:24

purewell의 이미지

ㅡ_-) 퍼포먼스를 위해 복잡한 코드 보다는
쉬운 코드가 향후 유지보수를 위해 속편하고 좋을 것입니다.

아무리 소프트웨어를 빡시게 옵티마이징 해도,
하드웨어가 +.+) 눈부시게 발전해버리므로
시간이 지나면 거기서 거기가 될 것입니다.

2만명의 클라이언트를 여러대의 PC Server로
처리하거나 한 대의 Super Server로 관리하거나
결국 매한가지. ㅡ0-) Thread를 쓰던 Process를
쓰던 큰 관계가 없을 듯 합니다.

_____________________________
언제나 맑고픈 샘이가...
http://purewell.biz

익명 사용자의 이미지

purewell wrote:
ㅡ_-) 퍼포먼스를 위해 복잡한 코드 보다는
쉬운 코드가 향후 유지보수를 위해 속편하고 좋을 것입니다.

아무리 소프트웨어를 빡시게 옵티마이징 해도,
하드웨어가 +.+) 눈부시게 발전해버리므로
시간이 지나면 거기서 거기가 될 것입니다.

2만명의 클라이언트를 여러대의 PC Server로
처리하거나 한 대의 Super Server로 관리하거나
결국 매한가지. ㅡ0-) Thread를 쓰던 Process를
쓰던 큰 관계가 없을 듯 합니다.

이건 제 의견인데요.
적어도 개발자는 개발자 자신을 위한 프로그램을 만드는 것은 아니라고 생각합니다.
사용자의 생각을 고려해서 만들어야 한다는 것이 제 생각이구요.
사용자는 당연히 작은 사양의 시스템으로 많은 client를 받아들이는 그런것을
원하겠지요.

옛 선조들의 장인정신을 생각해보면서 ....

purewell의 이미지

Quote:
이건 제 의견인데요.
적어도 개발자는 개발자 자신을 위한 프로그램을 만드는 것은 아니라고 생각합니다.
사용자의 생각을 고려해서 만들어야 한다는 것이 제 생각이구요.
사용자는 당연히 작은 사양의 시스템으로 많은 client를 받아들이는 그런것을
원하겠지요.

옛 선조들의 장인정신을 생각해보면서 ....

어디에 관점을 두느냐에 따라 다르겠죠.
(물론 두마리 토끼 모두를 잡을 수 있다면 가장 좋겠지만)

저는 Time과 유지 보수에 주안점을 둡니다.
(의견입니다)

시간이 무한정 주어지는 오픈프로젝트가 아닌 이상,
상업적인, 특히 IT 계열의 프로젝트는 시간이 돈이라는
생각을 져버릴 수 없기에 옵티마이징이 조금 덜 되더라도,
그 시간을 하드웨어 구매비용으로 살 수 있다면 사서라도
좀더 빨리 내놓는 쪽을 택할 것입니다.

_____________________________
언제나 맑고픈 샘이가...
http://purewell.biz

익명 사용자의 이미지

상업 프로그래머라면 (종종 코더라고 불리기도 하는) 성능보다는 유지보수의 용이성을 최선으로 두고 작업하는게 좋다고 생각합니다.
안그러면 평생 발목잡힙니다. ㅡㅡ;;
에러나서 손볼게 생겼는데 마침 휴가중이라면 어찌하겠습니까..
저도 별 생각없이 코드 복잡하게 짜고 (사실 복잡한건 아니지만..) 문서화를 대충했다가 피본적이 있었습니다. (휴가를 2번이나 반납헀습니다. 작년 12월 31일도 휴가 마지막 날이었는데 술마시다가 회사로 불려가서 종소리를 회사에서 라디오로 들었습니다. ㅡㅡ;; )

그뒤로 코드 성능은 좀 떨어지더라도 누구나 알아볼 수 있도록 풀어쓰고 (때때로 알고리즘을 명확히 하기 위해 지역변수를 추가로 더 쓰기도 하고), 주요 코드마다 어떠어떠한 프로세싱을 하는지에 대한 주석을 꼭 달아둡니다.
최적화되었지만 복잡한 알고리즘과 느리지만 단순해서 한눈에 알아보는 알고리즘을 선택하게 될 경우 고민할 것 없이 후자를 선택합니다.

단순하고 쉬울수록 개발기간은 단축되고 다른사람이 업무를 이어받아서 진행하기도 좋거든요.
어떤 바보가 보더라도 유지보수가 가능해야 한다 - 최근의 제 철학(??)입니다.
대부분 유지보수는 맡기 싫어하기 때문에 코드는 더욱 쉬워야 합니다. 안그러면 인수인계 하기도 피곤하거든요.
장인정신도 좋지만 그렇다고 어셈블리어로 짤 수는 없는 거잖아요. :)
(물론 저도 나름대로의 장인정신은 가지고 있지만 상업 프로젝트에 써먹었다가 피본 경험이 있어서.. ㅡㅡ;; )

xfmulder의 이미지

이건 이 주제와 다른다고 생각합니다만,

저도 장인정신에 적극 동감합니다. 그런데 요즘은 쉽게 짜둬야 다른사람이 편해진다는 것에 더 많은 신경을 씁니다.
(요새 하는일이 남이 짠 코드를 유지보수하는일입니다. 변경요청 오면 수정해주는데 쉽게 짠 코드에 대해서는 너무나 선임자에게 감사하게 됩니다. 어렵고 난해하면 정말 환장하지요)
"도자기 굽듯이 하지말고 빵 찍듯이 하라는...."

물론 이건 application 에 대한 거고, 핵심 라이브러리라면 조금 어렵더라도 최적화해둬야 하겠지요.

내 자식들도 나처럼 !!