트랜잭션 엔진 일람

사람들이 말하는 프로그래밍은 대부분 원주율 계산이 아니라 소프트웨어 시스템 구축이다. 소프트웨어 시스템 구축에 있어서 애플리케이션 상태 관리가 핵심이다. 따라서 백엔드 프로그래밍에서 트랜잭션 엔진이야말로 핵심 요소다. 그 중요성이 너무 덜 강조된 것과 대조되게 말이다.

튜링 머신

당연히 모든 트랜잭션 처리 수단은 이 범주에서 벗어나지 못한다. 문제 연산을 위해 발명되었지만, 소프트웨어 시스템 구축에 더 많이 쓰이는 것 같다.

메모리(Random Access Memory)

메모리에서 당연히 트랜잭션을 처리할 수 있다. 문제는 트랜잭션 중간 상태에서 정전이나 고장이 발생할 경우, 트랜잭션의 원자적 적용에만 실패하는 것이 아니라, 원 상태마저 누락하는 재난이 발생해버린다.

우리가 사용하는 메모리 장치가 용량이 무한대이고 절대 정전이나 고장이 발생하지 않는 추상적인 “완벽한” 메모리라면 데이터베이스를 발명할 필요도 없었을 것이다.

관계형 데이터베이스(RDBMS)

흔히 백엔드 프로그래밍에 node.js를 써야 하나 python을 써야 하나 하는 토론이 발생하지만, 정작 중요한 부분은 왕왕 DBMS 쪽이라는 것이 간과되곤 한다. RDBMS는 오랜 역사 기간동안 트랜잭션 엔진 영역의 왕좌를 지켜왔다. 그러다 최근에 왕좌에서 끌려 내려왔는데, 스케일 문제 때문이었다. RDBMS는 수평확장성이 좋지 않았다.

여러 문서간 트랜잭션을 지원하지 않는 NoSQL

애플리케이션이 트랜잭션 처리 기능을 포함해야 한다. 이것을 잘하기 아주 어려움. 잘 해도 더러워짐. 확장성의 대가.

액터 모델(Actor Model)

애플리케이션이 트랜잭션 처리 기능을 포함해야 한다. 쉬운 확장성의 대가. 액터 모델은 상태 변경 명령을 전달하는 방식으로 작동한다. 다중 객체 상태의 동시 settlement에 약하다.

LMAX 아키텍처 (싱글 스레드, 이벤트 소싱을 통한 레플리케이션)

이 방식은 LMAX 외환 거래소, 한국거래소, 됴쿄증권거래소, 상하이증권거래소 같은 곳에 모두 적용되어 있다. 한마디로 높은 빈도의 트랜잭션 처리 영역을 장악하고 있다.

싱글스레드 모델. 수평확장 불가. 아이러니하게 TPS가 가장 높음 (6백만 TPS) . 저장공간 수평확장 불가한 것이 최대 단점.

참고: https://martinfowler.com/articles/lmax.html

고신뢰성 분산 키값 저장소 (a.k.a 분산 코디네이터)

Apache Zookeeper, etcd, Google Chubby 등 구현이 있다.

분산 저장소지만 기본적으로 중앙화된 저장소라고 봐야 한다. 다만 클라이언트에 데이터 누락의 위험 없이 최신 상태를 지속적으로 (최종 일관성) 동기화 해준다는 보장을 한다. (클라이언트로의) 분산 동기화에 특화되어 있는 저장 백엔드라고 봐야 한다.

장점:

  • 거의 완벽한 안전성.

단점:

  • 여러 문서간 트랜잭션 기능 미제공
  • TPS
  • 수평확장 불가

트랜잭션 기능 있는 클라우드 스케일 NoSQL DBMS

단점이 거의 없음. ACID + 확장성. 레이턴시를 대가로 CAP 모두 만족할 수 있음. 범용적임.

가상 액터 + 트랜잭션 패치(즉 Microsoft Orleans)

레플리케이션 불가. 하지만 상태 랜딩 (영구화) 백엔드가 레플리케이션 기능 있는 DB일 경우 레플리케이션 기능 생긴다. 단 레플리케이트 되려면 컨시스턴트한 쓰기를 해야 함. 이는 레이턴시를 대가로 함. 객체 데이터베이스(Object Database)라 할 정도의 높은 표현력이 킬링 포인트. 다른 장점: 투명한 분산 / 쉬운 수평확장. Stateless 서비스에 준하는 배포 민첩성.

레플리케이션 활성화된 Redis

장점: 높은 TPS (백만 TPS), 안전성.

단점:

  • 레플리카 랙 기간동안의 아주 미약한 데이터 불안전성 (크로스 리전 20ms 대. 베어 메탈 로컬 네트워크 1ms 대)
  • Redis의 자료형 표현력의 한계 (메모리 주소 쓸 수 없음)
  • 그로 인한 프로그래밍 표현력 부족. 애플리케이션 상태 의존적인 트랜젹션은 제한된 lua로 짜야 함.
  • 수평확장 불가 (수평확장 시 트랜잭션 불가)
  • 수직 확장의 공간 한계가 낮음(메모리 한계). 콜드 데이터를 디스크로 랜딩 시키는 기제(와 온디맨드 로딩 기제)가 필요할 경우 애플리케이션 단에서 제공해야 함.

블록체인?!

크게 퍼블릭 체인과 프라이빗 체인으로 나뉨. 퍼블릭의 경우 크게 POW와 POS로 나뉨. 각각 아주 많은 종류가 있다. 종류에 따라 TPS, 데이터 redundancy 수준, 분산 공격 가능성 모두 다름. 단점도 각각 다름. 장점이 뭐냐 라고 한다면, 퍼블릭 프라이빗을 막론하고 한가지로 요약할 수 있음. 가트너의 평가를빌자면:

멀티 파티 신뢰 문제를 해결함.

(It allows untrusted parties to exchange commercial transactions.)

Gartner Top 10 Strategic Technology Trends for 2018

즉 트랜잭션 엔진의 멀티 파티 소유가 가능해짐. 그중 “파티”의 뜻은? RFC 7519(JSON Web Token)의 서언에서 말하는 “two parties”의 “파티”와 같은 뜻. 한발 나아가 그 어떤 파티에도 소유되지 않은 트랜젹션 엔진이 탄생했음을 의미. 역사상 처음으로 애플리케이션의 상태에 대한 글로벌 컨센서스를 독점 외의 수단으로 달성할 수 있게 됨.

단점: 블록체인 트릴레마(불가능 삼각형)각자 단점이 모두 다르지만, 공통된 단점: 레이턴시. 아직까지 효과적인 수평확장이나 계층화된 확장 솔루션이 구현 및 실천에서 성공한 기록이 없음(이론과 소규모실천에는 많음). 애플리케이션 상태의 비밀성 부재. 결정론성 요구 때문에 상단 애플리케이션에서 외부 상태 참조 불가.

결론

CAP 이론이 소프트웨어 개발, 그중에서도 트랜잭션 엔진에 무엇을 의미하는지 지금까지도 업계가 오해해왔던 만큼, 업계가 이 영역에 대해 모르는 것도 많을 것이다. 많은 토론이 필요한 이유다.

매니지드 언어로 MMORPG 만들기

사건의 유래는 게임코디에 어느분이 이런 질문을 올린겁니다.

MORPG까지는 만들어봤는데, 심리스한 MMORPG를 Java나 C#으로 ( 메이저 한 언어로 갑시다…! ) 만든다고 하면 막연히 가장 걱정되는게 Full GC 상황에서의 world stop입니다. 아무리 concurrent gc나 vm 옵션을 건드려서 최적화 한다고 해도 언젠가는 Full GC를 마주칠텐데 1초만 world가 멈춘다고 해도 썩 유쾌한 경험은 아닐거 같거든요.

두번째로는 최대가용 메모리 입니다. Full GC랑 연관이 있는데 결국 Full GC상황에서의 GC 수행시간은 vm에 할당한 최대 heap size에 어느정도 비례합니다. 이 주제를 놓고 지인들과 몇번 토론을 했는데 주로 나온 얘기들은…

‘마영전은?’
‘누가 시도해 본 사람?’
‘요즘 하드웨어 좋은데 괜찮지 않을까?’
‘C++ 놓은지 너무 오래되서…(?)’
‘최소화 할 수는 있겠다, 죄다 pooling 한다던가, 그런데 적당히 해야지 이럴거면 왜 java나 c#을 써야할까?’

와 같은 얘기 -_- 어떻게 생각하시나요?

Continue reading

차세대 실시간 게임서버 엔진 Century 설계 설명

피터 틸의 <ZERO to ONE> 은 이런 물음으로 시작된다:

사람을 채용하려고 면접을 볼 때 내가 자주 하는 질문이 하나 있다.

“정말 중요한 진실인데 남들이 당신한테 동의해주지 않는 것은 무엇입니까?”

그리고 책 중간에도 이런 문장들이 있다:

“대부분의 사람들은 더 이상 찾아낼 숨겨진 비밀이 없는 것처럼 행동한다.” (P126)

“사람들이 숨겨진 비밀을 무서워하는 것은 틀릴까 봐 무서워하기 때문이다. 숨겨진 비밀이라면 당연히 주류 세력의 점검을 받은 적이 없다. 인생에서 실수하지 않는 것이 목표인 사람은 숨겨진 비밀을 찾아다니면 안 된다. 혼자서만 옳은 것도 쉬운 일이 아닌데, 혼자이면서 ‘틀리는 것’ 은 견딜 수 없을 테니 말이다.” (P130)

“세번째 추세는 ‘무사 안일주의’ 다. 사회의 엘리트들은 새로운 사고를 탐구할 수 있는 자유와 능력을 가장 많이 지녔다. 하지만 그들이야말로 숨겨진 비밀을 가장 믿지 않는 사람들인 것 같다. 이미 다 해놓은 것들을 토대로 편안하게 지대(地代)나 받고 있으면 되는데, 무엇하러 새로운 숨겨진 비밀을 찾아 해매겠는가?” (P130)

“숨겨진 비밀을 찾겠다는 포부를 가진 사람들은 먼저 이렇게 자문하게 될 것이다. ‘뭔가 새로운 것을 발견하는 게 가능하다면 똑똑하고 창의적인 글로벌 인재들 중 누군가가 벌써 발견하지 않았을까?’ ” (P131)

“숨겨진 비밀은 찾아다니지 않으면 발견할 수가 없다. 이 점을 잘 보여준 사람이 페르마의 마지막 정리를 증명한 앤드루 와일스였다.” (P135)

“진짜 진실은 아직 찾아내지 못한 숨겨진 비밀들이 많이 있다는 점이다. 하지만 그 비밀들은 오직 그칠 줄 모르고 찾아 헤매는 사람들에게만 그 모습을 드러낼 것이다.” (P136)

“숨겨진 비밀을 믿고 그것을 찾아다니는 것만으로도 우리는 보편화된 관습을 넘어 뻔히 보이는 곳에 숨어 있는 기회들을 볼 수 있다.” (P137)

“숨겨진 비밀을 발견한 사람은 선택의 기로에 놓인다. 누군가에게 얘기를 할 것인가? 아니면 혼자서 간직할 것인가? 이는 숨겨진 비밀의 종류에 달려 있다. 파우스트가 바그너에게 들려준 것처럼 위험한 진실들도 있으니까 말이다.” (P141)


Continue reading

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