Skynet 설계 설명

작자: cloudwu

번역: coolspeed

한달이란 시간에 걸쳐 드디어 skynet (https://github.com/cloudwu/skynet) 의 C 버전을 완성했다. 중간에 여러 모듈을 반복하여 리팩토링 한 결과 최종 남은 코드는 얼마 되지 않았다: 겨우 C 코드 6천여줄, 그리고 Lua 코드 천여줄이었다. 비록 일부 코드는 좀 급하게 짰지만 나 자신의 퀄리티 요구에 부합된다. 버그는 피면하기 어렵겠지만 이정도 작은 규모의 코드베이스는 충분히 명료하여 수정하기가 어렵지 않을 것이다.

Github 에 올린 이 프로젝트를 개발하는데 사용된 시간은 사실 한달도 훨씬 안된다. 나의 대부분 시간은 지난 반년 넘게 짜놓은 Erlang 버전 프레임워크와의 하위호환성과 호환 안되는 Erlang 모듈들을 포팅하는데 허비했다. 이 부분 코드들은 저희의 실 게임프로젝트와 관련 있는 것이어서 오픈하지 않았다. 또한 양이 이보다 몇배나 되는 관련코드들을 왕창 올려봤자 이 오픈소스프로젝트의 의미에 도움이 되지 않을 것이다. 프로젝트에 관심을 가지는 친구들은 그런 별로 중요하지도 않고, 많은 인터페이스들이 레거시 부담으로 추하게 설계된 구조 때문에 오히려 미궁에 빠질 것이다.

저희의 구 프로젝트와 연동시켜 보고 포팅도 다 잘 됐음이 확인된 후에 나는 또 skynet 의 일부 밑층 설계를 수정했다. 안전한 포팅을 보장하는 전제하에서 최대한 개선을 함으로써 히스토리컬 레거시를 최소한으로 걺어지도록 힘썼다. 이런 수정들은 쉽지 않았지만 의미가 있다고 생각한다. 최근 내가 자세하게 생각을 굴린 성과들이다. 오늘의 이 블로그글에서 나는 이번 픽스된 버전을 토대로 설계 설명을 좀 기록하려고 한다. 추후 찾아보기에도 좋게.


Skynet 코어는 어떤 문제를 해결하는가

나는 우리의 게임 서버가 ( 하지만 skynet 이 게임서버에만 사용될 수 있는게 아니다) 충분히 멀티코어의 파워를 이용할 수 있기를 바라며 서로 다른 비즈니스 로직들을 서로 독립적인 실행환경속에서 협동적으로 작동시키기를 원한다. 최초에 나는 이런 실행 환경이 OS 의 프로세스이기를 바랬다. 하지만 후에 발견한건데 만약 우리가 임베디드 언어를 필연적으로 사용하게 된다면, 예를 들어서 Lua, 독립적인 OS 프로세스의 의미가 크지 않을 것이다. Lua State 는 이미 충분히 양호한 샌드박스 환경을 마련해주어 서로 다른 실행환경을 격리해줄 수 있었다. 뿐만아니라 멀티스레딩 방식은 상태 공유를 통해 데이터 교환을 더욱 효율적으로 할 수 있게 해준다. 그러면서 멀티스레딩이 흔히 비평받는 단점들, 이를테면 복잡한 스레드 락, 스레드 스케쥴링 등은 밑단의 규모를 가능껏 제한하고 설계를 최대한 간소화함으로써 최소한의 범위안으로 가두어둘 수 있다. 이런 입장에서 skynet 은 최종적으로 3000 줄 안되는 C 코드로 코어층을 구현했는데 이것은 코딩 좀만 할줄 아는 C 프로그래머라면 빠른 기간내에 이해하고 유지보수 할 수 있는 규모이다.

핵심기능차원에서 skynet 은 오직 한가지 문제만 해결한다:

하나의 규약에 부합되는 C 모듈을 다이나믹 라이브러리 ( so 파일) 로부터 가동시켜 영원히 겹치지 않는 (모듈이 꺼지더라도) 하나의 숫자 id 에 바인딩하여 handle 로 사용하는 것이다. 모듈은 서비스 (Service) 라 불리고 서비스들은 서로 자유롭게 메세지를 보낼 수 있다. 모듈은 skynet 프레임워크에 하나의 callback함수를 등록하여 그것으로 자기에게 보내온 메세지를 받는다. 모듈들은 모두 하나하나의 메세지에 의해 드리븐 되고 메세지가 오지 않을 때에는 펜딩되여있으며 CPU 자원 소모가 0이도록 보장된다. 자발 실행적인 로직이 필요하다면 skynet 시스템에서 제공하는 timeout 메세지를 이용하여 일정 시간마다 트리그 시킬 수 있다.

Continue reading

[퍼옴] Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이 왜 이리 힘드나요? (Lock-free에서 Transactional Memory까지)

웬만해서는 블로그에 퍼온 내용은 올리지 않을려고 했는데…

이건 올려야 해 ( __ __)\

NDC 2014 세션 키노트:

SlideShare 사이트 링크:

Continue reading

The C10M Problem

C10K 도 어제같은데 C10M 이라니 ㄷㄷ..

여기서도 우리의 미운 오리 Java 는 등장합니다.

WhatsApp 의 Erlang 으로 (FreeBSD상에서) 만든 200만 커넥션을 무색하게 만드는,

무려 천2백만 커넥션. Java 로 구현. (Linux 상에서). [1]

Haskell 언어의 2천만 QPS (epoll / kqueue)도 인상적입니다. [2]

Several prominent programming languages provide lightweight threads or processes. Erlang provides lightweight processes that communicate only using message passing. The Go programming language provides sophisticated coroutines, called goroutines. The Go scheduler also uses N (one per cpu) poll serve. In upcoming releases, Go’s IO event notification will be integrated with the scheduler, whereas with Mio, the event notification is implemented entirely in Haskell.

Event libraries such as libevent, libev, and libuv also provide abstraction over platform-specific event notification APIs. These APIs require programmer to express programs as event handle, while Mio is designed and optimized to support a lightweight thread programming model.

Mio has been fully implemented, has been incorporated into the GHC code base, and will be released as part of GHC 7.8.1. Mio includes 874 new lines of code and 359 old lines of code deleted.

쩌.. 쩐다..

 

References:

[1] Scaling to 12 Million Concurrent Connections: How MigratoryData Did It

[2] Mio: A High-Performance Multicore IO Manager for GHC

 

LMAX 거래소가 게임서버 아키텍쳐에 주는 계시 #2

부제: <거래엔진의 참조가치가 어느 정도인가?>

1편에서는 LMAX 아키텍쳐를 소개하고 (소개했다기에는 부끄러울 정도로 간략하게 소개하고) 그것을 성공 사례의 거울로 한번쯤 비추어보자고 말했습니다.

그럼 제기할 수 있는 한가지 자연스러운 질문은: 거래엔진이 뭐 게임 서버도 아닌데, 뭐 어뜨케 참조하잔 말야? 참조할 가치가 있냐? 가 되겠습니다.

제2편에서는 이 문제들을 대답하기 위해 노력을 해보겠습니다.

간단한 대답은 이렇게 되겠습니다: 그렇습니다, 다릅니다. 거래 엔진은 거래 엔진이고 게임 서버는 게임 서버겠죠?

하지만 게임 서버도 게임 서버와 다릅니다. 실시성에 대한 요구가 높은 게임 서버도 있고 실시성에 별로 요구가 없는 게임 서버도 있습니다. 오케이, 알겠습니다. 보다 의미있는 비교를 위하여 이 글에서는 “게임 서버” == “실시간 게임 서버” 로 한정하겠습니다. 그렇다고 하더라도 실시간 게임 서버가 다 같은 건 아니겠죠? 거래 엔진도 거래 엔진이라고 해서 다 같은게 아닙니다.

무엇보다 유사성을 논할 때 우리는 특성들의 집합을 두고 논해야 하는거지 그것이 뭐라고 “불리는가”에만 의뢰하여 유사성을 판단할 수는 없습니다.

그러면 문제는 아래와 같은 형태로 전환됩니다:

거래 엔진과 실시간 게임 서버는 어떤 면에서 유사하고 어떤 면에서 다를까요?

사실상 거래 엔진과 실시간 게임 서버는 많은 특성들을 공유하고 있습니다:

  • 1. 높은 스루풋을 희망한다. (그 단위는 업계에서 공인 되는 건 여러가지가 있지만 여기서는 “TPS”로 하겠습니다.)
  • 2. 레이턴시를 최소화 하고 싶어한다.

— 1 과 2 의 원인으로 양자는 모두 아래와 같은 특점들을 지니게 됩니다.

  • 3. socket 서버이다.
  • 4. 유상태(stateful) 아키텍쳐를 취한다. (모두 “DATABASE IS DEAD”란 화제에 휩쓸리기 좋은 예제이다. 취소선.)
  • 5. 서버가 request / response 모델로도 구현이 가능하지만 성능과 실시성을 높이기 위해서는 보통 서버에서 클라에 푸시하는 방식도 있기를 원한다.
  • 6. IO boundary. (게임 서버의 경우 CPU boundary 일 수 있는데 이는 뒤에서 논하겠다)

— 그리고 semantic 각도에서

  • 7. 리퀫에는 “술어”(predicate) 가 포함되는 경우가 허다하다.

이는 아래의 공통된 특성을 초래합니다:

  • 8. C / S 통신의 내용에는 RPC 가 많다.

— 그리고  Continue reading

LMAX 거래소가 게임서버 아키텍쳐에 주는 계시 #1

LMAX Exchange 란 무엇인가?

2010 년에 영국 런던에서 창립되였는데 첫 온라인 외환거래소라고 합니다. 영국에서 성장이 가장 빠른 핀테크 업체이기도 하답니다. [1] [2]

LMAX 거래소가 최근 기술영역에서 주목받게 된 이유는 LMAX 가 업계 최고 성능을 자랑하는 마켓 엔진 아키텍쳐를 발표했기 때문인데요, 도대체 얼마만큼의 성능이 되냐구요?

비교대상으로 우리가 익숙한 고성능 시스템을 살펴봅시다.

  1. VISA 는 평균 2,000 TPS 성능으로 돌고있다고 합니다. [3]
  2. NASDAQ 의 자료에 의하면 NASDAQ 의 전대 엔진의 성능은 10,000 TPS 였고 그때는 그걸로 자랑을 했었습니다. [4]
    지금의 NASDAQ 는 35,000 TPS 부하로 돌고있다는 것을 들은 적 있는데 출처는 찾지 못하겠습니다. 이건 그냥 그럴 수도 있겠거니 정도로 들어주시면 됩니다.
    현재 최신의 NASDAQ 마켓 엔진도 고성능 솔루션을 연구하여 백만 TPS 의 성능을 낼 수 있다고 합니다. [5]
  3. redis 의 set 성능은 100,000 TPS 입니다. pipeline 모드를 켜면 400,000 TPS 입니다. [9]

그건 그렇고 오늘 말하려고 하는 LMAX 의 스루풋 절대수치는 얼마인가요?
무려 600 만 TPS 에 이른다고 합니다. [8]

LMAX 를 알게 된 것은 Bitshares 를 통한 것인데요. [6] [7]  Continue reading

보이지 않는 전우

author: 李鱼 번역: coolspeed

cover

스티브 마퀴스는 TV도 없고 휴대폰 신호도 들어오지 않는 워싱턴 외곽의 한 오두막안에서 은거한다. 15 년동안 그는 전 세계 다른 십여명의 프로그래머와 인류의 프라이버시를 지키는 위대한 프로젝트를 수행해왔다. 그들은 서로 만난 적이 한번도 없다. 그들은 서로에게 이메일 뒤에 있는 유령과 같은 존재였다, 갑자기 어느 중국회사가 “거액”의 돈을 기증해오기 전까지는.

[워싱턴]

스 티브 마퀴스(Steve Marquess)는 TV도 없고 휴대폰 신호도 들어오지 않는 워싱턴 외곽의 한 오두막 안에서 은거한다. 통신사는 해마다 신호탑이 그의 집앞에 세워질것이라고 가슴치며 말했지만 지금까지도 실행하지 않았다. 이런 불편한 점 말고는 오두막 주변은 울울창창 나무들이 자라고 새들이 지저귀며 꽃향기가 풍겨 슈퍼히어로가 세계를 구할 필요 없는 주말에 찾기에 딱 좋은 곳이였다.

“난 인젠 노인이야. 천공판(punched card)이나 진공관 컴퓨터들을 기억하고 있을 만큼 구물이지. 그 시절엔 소프트웨어 특허따윈 없었고 IBM같은 컴퓨터 제조사들은 소프트웨어를 컴퓨터를 팔 때 무료로 줬어. 그때부터 난 오픈소스에 정신이 팔려있었어.”

스티브 마퀴스는 어느 지방잡대를 졸업하고 미국 국방부의 컬설턴트로 근무했었고 무기거래상의 면허도 땄었다. 그렇게 세월은 흐르고 그는 마침내 주택구입대출을 다 갚았으며 어느덧 딸도 대학교 졸업의 나이가 되었다.

그는 수다가 많았지만 청각이 좀 안좋았다. 평소에 술과 사냥을 좋아했다. 그외 시간은 거의 가장 광범위하게 쓰이고있는 오픈소스 암호학 라이브러리인 OpenSSL프로젝트에 기여하였다. OpenSSL의 코드에 취약점이 생기면 지구상의 3분의2에 달하는 웹사이트 서버가 영향을 받게 된다. 해커는 심지어 직접 개인컴퓨터를 공격할 수도 있게 되며 인터넷에 연결되어있는 전세계 수십억 네티즌들의 개인정보, 비밀블로그글이며 은행계좌비밀번호까지, 다 위험속에 노출되게 된다.

창립때부터 OpenSSL프로젝트는 소스코드를 오픈하였고 모든 질의와 개선건의들을 귀담아 들어왔다. 위키백과(Wikipedia)와 유사하게 이 오픈소스프로젝트도 그 어떤 상업적회사에 소속되여있지 않으며 한줄한줄의 코드가 다 전 세계 각지에 있는 프로그래머들이 주말이나 여가시간에 자원적으로 기여한 것이다. 서버를 유지보수하기 위해, 새로운 장비를 구입하기 위해, 검증테스트를 외주로 돌리기 위해, OpenSSL은 대중으로부터 기부금을 받기도 하고, 프로젝트에 보태기 위해 프로젝트와 전혀 관련 없는 외주 프로그래밍 일감도 받군 했다.

15년동안 OpenSSL이 매년 얻은 기부금은 시종 2천여달러 좌우에서 배회했다. 믿기 어렵겠지만, 국제인터넷의 태반을 보호하고있는 암호학 라이브러리 프로젝트는 사실상 2명의 풀타임 프로그래머밖에 고용할 수 없었다. 그 두분의 이름은 모두 스티브, 캡틴 아메리카와 동명이였다.

Continue reading