트랜잭션 엔진 일람

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

튜링 머신

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

메모리(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)

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

레플리케이션 활성화된 Redis

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

단점:

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

블록체인?!

크게 퍼블릭 체인과 프라이빗 체인으로 나뉨. 퍼블릭의 경우 크게 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 이론이 소프트웨어 개발, 그중에서도 트랜잭션 엔진에 무엇을 의미하는지 지금까지도 업계가 오해해왔던 만큼, 업계가 이 영역에 대해 모르는 것도 많을 것이다. 많은 토론이 필요한 이유다.

Redux 공부 필기

  1. Redux의 혁신은 상태를 한곳에 몰아넣은 것, 상태와 ‘상태 변경자’들을 분리한 것이다. 맞다, WAS들이 이미 하고 있는 그것 맞다. (AWS Lambda가 왜 ‘람다’인지 생각해보라.)
  2. 상기 혁신을 통해 핫 리로딩(hot-reloading)을 지원한 것이 키 피처중 하나였다. 역시 WAS들이 이미 하고 있는 그것 맞다.
  3. 모듈화는 상태를 찢어놓음으로 달성한게 아니라 함수를 찢어놓음으로 달성한다. 찢어진 함수들은 ‘함수 합성’을 통해 다시 합쳐질 수 있다.
  4. 키 피처중 다른 하나는 시간 여행 디버깅(Time Travel Debugging)이다. (Redux라는 네이밍의 중의적 의미중 하나. 후술.) Visual Studio나 WinDbg에서 지원하는 그거 맞다. 다만 Redux가 먼저 나왔고 따라해도 VS와 WinDbg가 따라했을 것 같다.
  5. 시간여행의 비결이 뭐냐? 애플리케이션 상태를 1개의 불변(immutable) 객체에 저장하는 것이다. 상태가 바뀔 때 어떠카냐고? 불변형 객체를 하나 새로 만들면 된다.
  6. 그렇게 하게되면 메모리 사용량이 무식하게 늘어나지 않냐? 아니다. 최적화되어 필요한 부분만 증분으로 늘어난다. 즉 상태변경을 하는 일반 애플리케이션과 큰 차이가 없다. (특히 웹앱의 생명주기상 더욱 문제 안된다.)
  7. 메모리 사용량이 폭증하지 않는 마법의 비결이 뭐냐? 답은 의외로 간단했다. 얕은 복사(Shallow Copy)다. 진짜 천재다.
  8. 물론 이상 모두 Redux의 핵심을 짚었다고 할 수 없다. Flux – Redux 진화 라인의 핵심은 액션의 단방향 흐름이다. 즉 이벤트 소싱이다.
  9. 이벤트 소싱과 상태의 예측성 모두 게임 쪽에서 훨씬 일찍부터 태동하고있던 사상이었고, DB쪽에서는 옛날부터 이미 구현된 현실이었다.
  10. 물론 수렴 진화(Convergent evolution)에서 그 어떤 가지도 모두 동등하게 중요하고 대체불가하다.
  11. 함수형 프로그래밍 신도들은 immutable 의 승리가 보일 것이고, 데이터베이스 힙 가이들은 “THE LOG IS THE DATABASE”가 보일 것이고, 이벤트 소싱파들은 이벤트 소싱이 보일 것이고, CRDT연구자들은 CRDT가 보일 것이고, Redis 애호가들은 Redis가 보일 것이고, 블록체인 신도들은 블록체인이 보일 것이다.
  12. “Redux”는 “Reduce”(“맵리듀스”의 그 “리듀스” 맞다)와 같은 라틴어 어원을 갖는다. 위에서 언급한 것처럼 “(과거의 것을) 되찾음”이란 뜻이 있다. 그리고 reduce는 함수형 프로그래밍에서 잘 알려진 패턴인데 억지번역을 해보자면 ‘귀납 합병’ 같은거다. 필자도 지금 알게 된건데 “fold”가 더 표준적인 용어더라.
  13. 정말 블록체인으로 Redux를 구현한 사람이 있다.
  14. Redux는 놀랍도록 짧다. 핵심 코드 99줄 구현을 갖고있는 것으로 유명하다. 그도 그럴것이 React Europe이란 컨퍼런스에 ‘핫 리로딩’ 관련 기술공유를 하기 위해 PoC 목적으로 급조해 만들어졌다고 한다. (거봐 그냥 WAS를 본딴거라니까)
  15. Redux 발명자는 이미 페이스북에서 채갔다.

Kotlin언어 성공사례: Corda 블록체인(by R3)

Kotlin언어? 뭔 듣보잡? 성공사례가 있니?

찾아보니 있다.

corda_kotlin.png

CTO는 전 구글 시니어 엔지니어였다고 한다. CTO분이 얘기하신 Kotlin 선택 원인:

  1. 정적 타이핑 (그러고 보니 밀레니얼 세대 언어는 다 그런 것 같다)
  2. Java가 비즈니스 월드에서 중요해서. (하긴)
  3. 섹시해서 (구닥다리 Java랑 비교하니 그렇지)
  4. 배우기 쉬워서 그래서 구인이 쉬워서 (보통 Java구인을 하고 1~3일 트레이닝 시키면 코틀린 언어 코딩을 할 수 있다고 한다)
  5. IDE지원 잘되서
  6. 컴파일 속도가 빨라서 (Scala 저격하며)
  7. 문서화가 잘돼있어서
  8. 내가 할줄 알아서. 내가 좀 해봤는데 재밌어서

그러면서 하는 말이 Kotlin이 없었다면 Scala 썼을 것이라 한다.

마지막에 내린 결론이: 잘한 것 같다.


 

개인적으로 Kotlin이 정말 반갑다. JVM팬으로서 항상 언어가 아쉬웠는데, Java는 구닥다리고, Scala는 너무 복잡하고* Groovy는 언어가 아쉽고, (Scala 와 Groovy공통점이 모두 창립자가 포기했다는 점..) Clojure는 대중성을 전혀 염두에 두지 않은 것 같고. 그런 점에서 Kotlin은 JVM에게 복음과도 같았다.

특히 실행 가능한 환경이  JVM / Javascript VM / Native 로 다양해서 플랫폼에 발목 잡히는 일이 없도록 했다는 점도 칭찬하고 싶다. (마이크로소프트가 최근에야 터득한 점)

JVM, V8엔진, 네이티브 세가지 모두 점점 중요해지는 플랫폼인 것 같다. 아 WASM(Web Assembly)까지 지원하면 더욱 좋겠지만. 이게 미래가 될 수도 있으니. 걱정할 필요가 없는게 컴파일러 플랫폼이 LLVM이어서 WASM이 GC만 지원하면 WASM으로 컴파일 하는 것도 식은 죽 먹기일 거라는 점.

최근 홍민희님의 PyConKr 2017 발표 <파이썬과 다이아스포라>를 보고, 최근에 읽은 <사피엔스>와 결부해서 느낀 점이: 성공한 언어들은 모두 대중성을 키 피처로 치밀하게 기획된 것 같다는 점이다. 민족의 용광로처럼 말이다. (적어도 대량 전파됨을 성공의 척도로 본다면 그렇다)

심지어 Rust도 너무 결백증스러운 면이 있어서 대중성이 의심스럽다.

다행히 Kotlin은 대중성을 키 피처로 설계된 듯하다. 그것의 일환으로 Java월드 레거시에 대한 포용성도 잘 설계된 것 같다.

미래가 지켜볼만하지 않은가!

* 참고로 R3 Corda의 경쟁상대인 IBM hyperledger fabric 은 Go언어로 만들었다.

부록

* TIOBE 프로그래밍 언어 유행도 인덱스에 따르면 Scala는 D언어나 COBOL언어보다 인기가 적다: https://www.tiobe.com/tiobe-index/

 

DB 정규화를 하지 않는 이유

DB 정규화를 하지 않는 이유는 한마디로 성능이다.

그렇다면 DB 정규화는 왜 성능을 해치는가?

1. DB 정규화는 테이블을 많이 나누게 하고, 테이블이 맣아지면 Join 이 많아진다. 그리고 Join 은 성능에 큰 악영향을 미친다.

1.1 Join 은 테이블 락 (Lock) 을 일으키고, 테이블 락은 병렬성의 큰 적이다.

아마 이 이유가 No-SQL 이 부상하게 된 가장 주된 원인이 아닐까 생각한다.

Python 의 GIL 이랑 같은 원리.

1.2 Join 은 여러 테이블을 가로지르는 다중 Disk-seeking 을 일으킨다. 한마디로 데이터 국지화의 적이다.

컴퓨터 하드웨어와 소프트웨어에서 많은 최적화장치들의 작동근거가 데이터 국지화이다. 이 가정이 깨질 경우 데이터 액세스가 굉장히 비싸진다.

DB 정규화는 공간을 가장 절약하는 방식이다 (i). 하지만 저장공간은 저렴하다 [1].

공간을 절약하는건 당연히 죄가 아니다. 심지어 공간을 절약해야 시간도 절약되는 경우가 많다. 그리고 이것 역시 “정규화가 성능에 좋다” 라고 주장하는 사람들의 한가지 근거이다.

하지만 알고리즘이란게 어느 선에 도달한 뒤에는 불가피하게 시간과 공간 사이의 트레이드오프에 직면하게 된다.

정규화는 공간 절약의 극한에 서있다.

이는 이론적으로도 당연하게 시간을 트레이딩 할 여지가 있음을 의미하지만, 많은 실천결과들이 역시 이 결론을 뒷받침해주고 있다.

또한 위의 1.2 와 결합시켜서 살펴보면 알게 되는데, 데이터 양을 줄인다고 무조건 시간이 절약되는게 아니라, 다수의 경우 데이터 국지화가 성능에 훨씬 큰 영향을 미친다. 이것은 실천적으로도 많이들 이중화 (Redundency) 로 정규화를 타파해 성능향상을 이룩하고 있는 산업현황과도 매칭된다.

또한 이 점은 저장 매개체의 랜덤 액세스와 순서적 액세스 사이의 수량급을 초월하는 성능 gap 의 배경속에서 더욱 확대된다. 이것은 물리적인 HDD 에서 유독 두드러지지만 SSD 에서도 상황은 비슷하다.

정규화는 쓰기에 최적화되어 있다. 하지만 읽기가 훨씬 중요하다.

Continue reading

슈퍼마리오 멀티플레이어 개발 후기

coolspeed

팀 합류 과제로 게임제작 미션을 받았다.

나는 과제로 “슈퍼마리오 멀티플레이어 게임”을 만들었다:

EnemyCD.gif

과제 결과물을 왓 스튜디오의 허락을 받고 소스코드를 Github 에 공개하였다:

https://github.com/coolspeed/MarioMultiplayer

관심 있으신 분들은 별표 하나씩 찍어 즐찾해주시길 부탁립니다.

게임 룰: 위의 GIF 움짤  그대로. 먼저 상대방을 밟는 쪽이 이긴다.

과제가 1차, 2차로 나뉘는데 1차에서는 싱글 플레이어 슈퍼마리오를 만들었고 2차에서는 그것을 멀티플레이어 게임으로 발전시켰다.

최종 클라이언트 Java (Processing) 1500 줄, 서버 C# 22줄로 짜여졌다.

클라이언트

Processing 으로 만들었다. 왜?

    1. Processing 이 좋아서. (유쾌한 시각적 프로그래밍)
    1. Unity 쓸줄 몰라서.
    1. 다른 엔진도 쓸줄 몰라서.
    1. 엔진부분이 더 재밌어서.
  1. 웹에다 배포하고 싶어서. (P5.js 를 통하여. 하지만 망했다. 그냥 일반 Processing 애플리케이션처럼 exe 파일로 빌드했다.)

서버

단순한 릴레이 서버.

big_mirror.png

넷코드

ZeroMQ 를 네트워크 라이브러리로 사용했다.

Continue reading

블록체인 관련 TED 강연 3선

블록체인이 무엇일까요? 아직 알지 못한다면 아는 것이 좋을 것이고, 안다고 해도 실제 운영 방식에 대한 자세한 설명이 도움이 될 것입니다. 돈 탭스콧이 인터넷의 두 번째 세대를 표방하며 돈과 경제, 정부와 사회를 변화시킬 잠재력을 가진 신뢰 구축 기술의 비밀을 밝힙니다.


모든 걸 바꾸게 될 분산적인 경제 제도인 블록 체인과 인사하세요. 이 복잡하고 혼란스러운 과학 기술을을 명료하게 설명하는 베티나 워버그는 인간의 역사만큼 오래된 상업과 재정 활동을 보다 흥미로운 것으로 변하게 할 블록체인(교환 가치를 위한 분산적이고 투명성이 보장되고 자동화된 제도)이 거래를 용이하게 하는 은행과 정부 같은 중앙집권적 기관에 대한 우리의 필요를 어떻게 사라지게 하는 지에 관해 설명합니다.


우리가 물건을 매매하는 방식이 바뀌고, 은행과 환전소가 없어도 되는 세상이 온다면 어떨까요? 비트코인이나 이더리움과 같은 암호화 전자 화폐가 보편화되면 미래에 이런 급격한 변화가 일어날 수 있습니다. 아직 그런 세상이 도래하진 않았지만, 이 재기 넘치는 강연을 통해 디지털 화폐 연구자 네하 나룰라는 화폐의 집단 허구에 관해 설명하면서, 지금과는 사뭇 다른 미래를 제시합니다.

왜 그동안의 함수형 언어 홍보는 잘못됐는가?

그렇다. 함수형 프로그래밍과 그것을 포함하는 “선언식 프로그래밍” [1] 은 그동안 이른바 산업 프로그래밍과 산업 프로그래밍 언어의 혁신요소들의 주요 원천 중 하나였다[2]. 하지만 그동안의 함수형 언어 홍보에서는 중요한 오류들을 범했다.

예를 들어 함수형 에반젤리스트들은 아래와 같은 광고어들을 내세웠었다.

“함수형 언어에서 변수는 값이 바뀔 수 없어요. 그리고 이게 좋아요. 버그를 막아주니까.”

이걸 듣는 사람들의 반응은 아마도 당장 발이 묶인 느낌일 것이다. 그래서 “그러면 코딩을 어떻게 해요?” 라고 묻는다면, 이런 대답이 올 것이다. “변수 변경이 정말 필요할 때는 변경할 수도 있어요. 그리고 함수형 프로그래밍에서는 꼬리 재귀를 사용하지요.” 그러면서 아마도 계승(factorial)이나 피보나치 예제를 주머니에서 꺼낼 것이다.

이렇게 되면 프로그래머는 아마도 고개를 갸우뚱 하며 (말은 하지 않고) 생각할 것이다.

“그렇게 되면 어차피 명령식에서랑 똑같이 변하는 변수를 사용하지 않을까? 과연 참고 변수를 변하지 않게 사용할 수 있을까?”

“그리고 나는 일할 때 매일 계승을 짜진 않는단 말야..흠..”

Continue reading