오픈 소스 Actor Framework 인 Akka.NET 을 통해 온라인 게임 서버를 어떻게 구현할 수 있는지를 설명합니다. Actor Model 에 대한 기본 이해부터 Scale-out 가능한 게임 서버 구축까지 전반적인 내용에 대해 알 수 있습니다. 설명을 위해 클라이언트는 Unity3D 를 사용할 예정입니다.
2015. 09. 05 도커 서울 밋업 4번째(Open Container Korea 주최).
elasticsearch에 은전한닢 한국어 형태소 분석기를 적용하고 운영한 사례 발표.
- 사용자 사전별로 이미지를 만들기
- nginx를 이용해 http basic auth 적용하기
오픈 소스 Actor Framework 인 Akka.NET 을 통해 온라인 게임 서버를 어떻게 구현할 수 있는지를 설명합니다. Actor Model 에 대한 기본 이해부터 Scale-out 가능한 게임 서버 구축까지 전반적인 내용에 대해 알 수 있습니다. 설명을 위해 클라이언트는 Unity3D 를 사용할 예정입니다.
2015. 09. 05 도커 서울 밋업 4번째(Open Container Korea 주최).
elasticsearch에 은전한닢 한국어 형태소 분석기를 적용하고 운영한 사례 발표.
- 사용자 사전별로 이미지를 만들기
- nginx를 이용해 http basic auth 적용하기
Confd, systemd, fleet을 이용한 어플리케이션 배포 in CoreOS충섭 김
Confd, systemd, fleet을 이용한 어플리케이션 배포 in CoreOS
Docker Seoul Meetup #2에서 발표한 자료입니다.
CoreOS에서 confd와 sidekick service를 이용한 서비스 배포에 대한 내용입니다.
http://www.youtube.com/watch?v=5ixJCM6pAcg
영상과 함께 보시면 더 좋습니다 :)
node.js를 처음 접하는 개발자를 위한 스터디 자료입니다.
실습 위주로, 간단한 웹 페이지를 만들어 보는 것을 목표로 하며,
express를 활용하기에 앞서, node.js 기본 API만으로 GET/POST 처리 방식을 알아봅니다.
내용의 깊이가 있지는 않으며, 단지 node.js의 입문을 위한 가벼운 수준으로 내용이 구성되었습니다.
이 발표는 [야생의 땅: 듀랑고]의 지형 배포 시스템과 생태계 시뮬레이션 자동화 시스템에 대한 이야기를 다룹니다. 듀랑고의 각 섬은 크기와 지형, 기후 조건이 다양하고 섬의 개수가 많아서 수동으로 관리하는 것은 사실상 불가능합니다. 몇번의 사내 테스트와 베타 테스트를 거치면서 이러한 문제를 해결해주는 자동화된 도구의 필요성이 절실해졌고, 작년에 NDC에서 발표했던 생태계 시뮬레이터와 Docker, 그리고 아마존 웹서비스(AWS)를 이용하여 수많은 섬들을 자동으로 생성하고 관리하는 자동화 시스템을 구축하게 되었습니다. 그 과정에서 했던 고민들, 기존의 애플리케이션을 "Dockerizing" 했던 경험, AWS의 각 서비스들을 적절히 활용했던 이야기, AWS의 각 지역별 요금이 상이하다는 점을 이용해서 비용을 절감한 사례, 그리고 자동화 시스템의 문제점과 앞으로의 방향에 대해서 이야기 할 계획입니다.
데브시스터즈의 Cookie Run: OvenBreak 에 적용된 Kubernetes 기반 다중 개발 서버 환경 구축 시스템에 대한 발표입니다.
Container orchestration 기반 개발 환경 구축 시스템의 필요성과, 왜 Kubernetes를 선택했는지, Kubernetes의 개념과 유용한 기능들을 다룹니다. 아울러 구축한 시스템에 대한 데모와, 작업했던 항목들에 대해 리뷰합니다.
*NDC17 발표에서는 데모 동영상을 사용했으나, 슬라이드 캡쳐로 대신합니다.
Confd, systemd, fleet을 이용한 어플리케이션 배포 in CoreOS충섭 김
Confd, systemd, fleet을 이용한 어플리케이션 배포 in CoreOS
Docker Seoul Meetup #2에서 발표한 자료입니다.
CoreOS에서 confd와 sidekick service를 이용한 서비스 배포에 대한 내용입니다.
http://www.youtube.com/watch?v=5ixJCM6pAcg
영상과 함께 보시면 더 좋습니다 :)
node.js를 처음 접하는 개발자를 위한 스터디 자료입니다.
실습 위주로, 간단한 웹 페이지를 만들어 보는 것을 목표로 하며,
express를 활용하기에 앞서, node.js 기본 API만으로 GET/POST 처리 방식을 알아봅니다.
내용의 깊이가 있지는 않으며, 단지 node.js의 입문을 위한 가벼운 수준으로 내용이 구성되었습니다.
이 발표는 [야생의 땅: 듀랑고]의 지형 배포 시스템과 생태계 시뮬레이션 자동화 시스템에 대한 이야기를 다룹니다. 듀랑고의 각 섬은 크기와 지형, 기후 조건이 다양하고 섬의 개수가 많아서 수동으로 관리하는 것은 사실상 불가능합니다. 몇번의 사내 테스트와 베타 테스트를 거치면서 이러한 문제를 해결해주는 자동화된 도구의 필요성이 절실해졌고, 작년에 NDC에서 발표했던 생태계 시뮬레이터와 Docker, 그리고 아마존 웹서비스(AWS)를 이용하여 수많은 섬들을 자동으로 생성하고 관리하는 자동화 시스템을 구축하게 되었습니다. 그 과정에서 했던 고민들, 기존의 애플리케이션을 "Dockerizing" 했던 경험, AWS의 각 서비스들을 적절히 활용했던 이야기, AWS의 각 지역별 요금이 상이하다는 점을 이용해서 비용을 절감한 사례, 그리고 자동화 시스템의 문제점과 앞으로의 방향에 대해서 이야기 할 계획입니다.
데브시스터즈의 Cookie Run: OvenBreak 에 적용된 Kubernetes 기반 다중 개발 서버 환경 구축 시스템에 대한 발표입니다.
Container orchestration 기반 개발 환경 구축 시스템의 필요성과, 왜 Kubernetes를 선택했는지, Kubernetes의 개념과 유용한 기능들을 다룹니다. 아울러 구축한 시스템에 대한 데모와, 작업했던 항목들에 대해 리뷰합니다.
*NDC17 발표에서는 데모 동영상을 사용했으나, 슬라이드 캡쳐로 대신합니다.
100% Serverless big data scale production Deep Learning Systemhoondong kim
- BigData Sale Deep Learning Training System (with GPU Docker PaaS on Azure Batch AI)
- Deep Learning Serving Layer (with Auto Scale Out Mode on Web App for Linux Docker)
- BigDL, Keras, Tensorlfow, Horovod, TensorflowOnAzure
어느 해커쏜에 참여한 백엔드 개발자들을 위한 교육자료
쉽게 만든다고 했는데도, 많이 어려웠나봅니다.
제 욕심이 과했던 것 같아요. 담번엔 좀 더 쉽게 !
- 독자 : 백엔드 개발자를 희망하는 사람 (취준생, 이직 희망자), 5년차 이하
- 주요 내용 : 백엔드 개발을 할 때 일어나는 일들(개발팀의 일)
- 비상업적 목적으로 인용은 가능합니다. (출처 명기 필수)
(GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례Jeongsang Baek
대부분의 중소 모바일 게임 업체는 앱을 잘 만들기에도 시간이 모자라 출시일을 잘 맞추기 급급한 상황이다. 그러다 보니 운영을 위한 툴은 소홀히 개발하는 경우가 대부분이고 운영 캠페인은 날림으로 개발하거나 그때 그때 개발자가 필요한 부분만 개발하기 일쑤다. 그러다보니 마케터는 결국 늘 개발자 눈치만 살피게 된다. 필자는 블루윈드에서 이러한 문제를 절감했고 '모바일 게임 개발사가 앱 개발에만 집중할 수 있게 해주고 싶다'는 IGAworks의 철학에 공감하여 라이브 오퍼레이션 프로젝트를 시작하게 되었다.
라이브 오퍼레이션의 개발 중점과제는 5가지였다. 첫번째, 다수의 개발사가 하나의 큰 클라우드 시스템을 사용하도록 multi-tenant 인프라를 구축해야 한다. 두번째, TCO(Total cost of ownership)를 최소화해야 한다. 세번째, 앱의 핵심유저를 실시간으로 그룹화하여 타게팅 캠페인을 할 수 있어야 한다. 네번째, 캠페인의 성과를 마케터에게 실시간으로 피드백해야 한다. 다섯째, 3개월 안에 정식 서비스가 되어야 한다는 점이었다. (왜 우리에게 주어지는 시간은 늘 3개월인가) 그리고 당연하지만 이 서비스를 혼자 개발해야 했다.
이 다섯가지 이슈를 해결하기 위하여 AWS 클라우드 상에 생산성과 성능이 검증된 node.js 와 mongodb를 이용하여 서비스 백엔드를 구성하였고, multi-tenant를 구성하기 위한 여러가지 고민과 그 해결책을 직접 구현하였다. 필자는 node.js와 mongodb를 사용해 본 경험이 충분하다 생각했지만 대규모 정식 서비스를 진행하며 많은 함정에 빠졌고 결국 해결했다.
이 발표를 통해 청강자는 node.js와 mongodb를 이용하여 multi-tenant 인프라를 구축해야 할 때 고려해야 할 설계 방식과 기술적인 고민, 그것에 대한 현실적인 해법을 얻을 수 있다.
Obfuscation 101
: 난독화, 프로가드, R8, 트랜스포머 API
김용욱
카카오뱅크
영화와 커피를 좋아하는 은행원. 반지 원정대는 극장에서만 15번을 보았다. 데이터베이스를 전공했지만 급변하는 모바일 환경에 반해 안드로이드에 승선했고 Realm을 통해 모바일과 데이터베이스를 융합했다. 그후 새로운 가능성을 찾아 금융으로 왔다.
8. Realm(렘) /rɛlm/
noun (plural: realms)
1. An abstract sphere of influence, real or
imagined.
2. The domain of a certain abstraction.
3. (formal or law) A territory or state, as ruled by
a specific power, and particularly those
territories ruled by a king.
한국어 : 영역
9. • 새로운 데이터베이스, 모바일에서의 SQLite 역할을 대
신할
• 모바일을 위한 디자인
• 스마트폰, 태블릿 & 웨어러블에서 직접 동작함
• 객체/모델-지향, 하지만 ORM은 아닙니다
• ACID 완벽지원
• 간단한 쓰레드 모델 지원
• C++ 코어 기반의 크로스 플랫폼
10. • 2014 7월에 발표, 2011년 부터 지적인 개발, 2012
부터 실제 제품에 사용됨
• 수만명의 개발자들이 앱개발에 사용중
• 수백만의 사용자들이 실제 사용중
• iOS 버전은 지금 당장 사용가능, Android 버전은 곧
사용가능
11. • > 8주만에 2만 명의 개발자가 사용
• Parse.com 보다 빠른 성장
(8개월 동안 1만 명의 개발자가 사용)
• 9주동안 계속 Github 의 '탑 트렌드 프로젝트'
• “아름답고, 작은 메모리를 차지하며 다양한 플랫폼을
지원하는 모바일 앱을 위한 데이터베이스가 드디어 탄
생 했습니다. 또한 디자인도 매우 아름답습니다.”
—David Helgason, CEO, Unity
12. 많은 앱에서 이미 사용중 입니다
• Breeze (TechCrunch Disrupt 파이널, 20억원 정도
의 투자를 받음)
• Cloth (뉴욕타임즈에 많이 소개된)
• Zynga (매일 수백만명의 사용자가 사용하는 게임에서
사용중)
• + ~1,000 개의 앱이 이미 앱스토어에 올라오있거나
개발 완료단계
• 다음은 누구 일까요? 한국에 있는 우리의 제일 큰 팬은
누구?
13.
14. 수많은 사람들이 제게
Android 용 Realm
이 언제 출시되는지 물었습니다.
곧 발표할 예정입니다!
17. DEVIEW 를 위해 준비된!
Android용 Realm
은 지금 사용가능 합니다
realm.io/kr
Android용 Realm에 대한 모임이 있습니다(한국어 진
행).10월 6일 월요일 / 역삼동 알럿스퀘어 B2:
onoffmix.com/event/33885
18. 모델(Models)
// Just extend your standard POJO from RealmObject:
public class Dog extends RealmObject {
private String name;
private int age;
@ignored private int dontPersistMe;
// + Standard setters and getters here
}
19. 쓰기
Realm realm = Realm.getInstance(this.getContext());
// Transactions give you easy thread-safety
realm.beginTransaction();
Dog dog = realm.createObject(Dog.class);
dog.setName("Rex");
dog.setAge(3);
realm.commitTransaction();
20. 쿼리
// Queries uses Builder pattern to
// build up the query conditions
RealmResults<Dog> query = realm.where(Dog.class)
.greaterThan("age", 8)
.findAll();
// Queries are chainable
RealmResults<Dog> allRex = query.where()
.contains("name", "rex")
.findAll();
21. 관계
public class Person extends RealmObject {
private String name;
private RealmList<Dog> dogs;
}
realm.beginWrite();
Dog mydog = realm.createObject(Dog.class);
Person person = realm.createObject(Person.class);
person.setName("Tim");
person.getDogs().add(mydog);
realm.commitWrite();
22. 쓰레드 안전하게 관리하기
new Thread(new Runnable() {
public void run() {
Realm realm = Realm.getInstance(this.getContext());
RealmResults<Dog> dogs = realm.where(Dog.class)
.contains("name", "rex")
.findAll();
// You can write to any Realm from any thread too
// with full ACID guarantees
}
}).start();
23. 암호화
Encryption
byte[] key = new byte[32];
new SecureRandom().nextBytes(key);
Realm realm = Realm.create(this, key);
// Normal usage!
RealmResults<Dog> query = realm.where(Dog.class)
.greaterThan("age", 8)
.findAll();
24. 디자인 목표
1. 모던하고
2. 간단하며
• 배우기 쉽고 (< 1 hour)
• 관리하고/디버그하기 쉽고
• 여러 쓰레드에서 사용하기 쉽게
3. 속도가 빠르게
25. 디자인 목표
1. 모던하고
2. 간단하며
• 배우기 쉽고 (< 1 hour)
• 관리하고/디버그하기 쉽고
• 여러 쓰레드에서 사용하기 쉽게
3. 속도가 빠르게
32. 역사적 배경
• 대부분의 데이터 구조(배열, 해시, 등등)는 80년대에 만
들어졌습니다
• 그당시에는, CPU와 메모리의 속도가 거의 비슷했습니
다
• 이제는 상황이 달라졌습니다… 프로세서가 1000배 이
상 빠릅니다
• 매일 사용하는 프로그램의 성능에 많은 영향을 끼쳤습
니다
• 데이터베이스에 끼친 영향은 더욱 큽니다
36. 행 기반의 데이터베이스
• 비슷한 레이아웃을 사용하는 경향이 있다
• 때로는 가변 인코딩을 사용하고, 이는 오버헤드를 발생
시킨다
• 행을 불러오는데 최적화 되어있지만, 그게 병목은 아니
다
• 행을 불러오는 것은 프로세서 캐시를 더럽힌다
(~64-128 바이트)
37. 컬럼 지향!
• 데이터를 컬럼 기준으로 자른다 - 한 컬럼당 하나의 배
열
• 패딩의 필요성이 없어진다
• 한 컬럼에서 이터레이션 할 때, 캐시를 건드리지 않는다
38. 추가적인 최적화
• 하나의 boolean 값은 보통 1 byte 전체를 차지한다
(8 bits) - 87%가 낭비됨!
• 그 대신에 Realm은 로 접근할 수 있도록 바이트
당 8개의 boolean을 저장하고 간단한 bit 쉬프트를
한다
• integer를 위해서는, 우리는 배열을 인서트 될 수 있는
가장 큰 숫자의 길이에 맞추는데 길이는 0, 1, 2, 4, 8,
16, 32 와 64 bit를 사용한다. 이로인해 64-bit 블럭
에 최소한의 오버헤드로 들어가도록 한다.
39. Realm의 가변 배열의 효과
1. 데이터가 훨씬 작다 (sqlite 사이즈의 50% 이하)
2. 검색이 훨씬 빠르다 (캐시 최적화 덕분에)
3. 컬럼 이터레이션이 훨씬 빠르다 (쿼리에 매우 유리한
조건이다)
4. 벡터 연산이 훨씬 빠르다
40. Realm 은 가변 배열의 그래프이다
• 가변배열은 b-tree에 연결되어있다
• 전체 구조는 매우 규칙적이다: 가변배열은 저~ 하부구
조에 있다
• 메모리에 매핑하기가 쉽다
41. Copy-on-Write
• Realm은 쓰기할 때 읽기를 block 하지 않기 위해서
COW(Copy-on-Write)를 사용한다
• 디스크에 시리얼화(serialize) 하기 위해서, 새로운 탑
노드에서부터 트리를 읽는다
42. Multiversion concurrency control (MVCC)
• 이 방식을 사용해서 여러 버전의 그래프를 유지할 수 있
습니다
• 쉬운 MVCC (git과 같은)
• 각 버전은 완전한 일관성을 가집니다 (ACID 개념)
43. 비압축 b-tree
• 압축이 필요 없습니다! 우리는
제일 오래된 버전을 표시하고 유
지하는 하는 방식으로 기존 버전
의 공간을 재사용 합니다
44. 복사없는 쿼리처리
• Realm 쿼리는 복사되는 것이아니, 매핑 됩니다
• SQL 쿼리에 비교하자면: 투영된 것을 보게되는 것이
아니라, 실제 데이터를 보게 됩니다
• 컨텍스트 (다른 컬럼의)는 언제나 사용 가능합니다
• 쿼리 결과의 값을 쉽게 수정할 수 있습니다
47. 지그재그 쿼리
size_t find(size_t start, size_t end) {
size_t i = start;
while (i < end) {
size_t orig_start = i;
while(i < end && !(first[i] < 10)) i++;
while(i < end && !(first[i] > 5)) i++;
while(i < end && !(second[i] == 200) i++;
while(i < end && !(third[i] != 0) i++;
if( i < end && i == orig_start)
return(i);
}
return -1;
}
48.
49. 지그재그 쿼리
• 우리는 각 조건문을 루프안에서도 테스트 하였습니다
• 컬럼-지향의 장점을 사용합니다, 캐싱!
• 최적의 패스를 찾을 수 있다는 것을 보장하지는 않지만,
대부분의 경우에 최적에 가까운 경로를 사용합니다
50. 링크
Dog mydog = realm.createObject(Dog.class);
Person person = realm.createObject(Person.class);
person.getDogs().add(mydog);
일반적으로:
1. 그래프 (탐색하기 좋지만, 일반적인 검색 등에서 좋지
않습니다)
2. 문서 (비정규화된 복사 — 유지하기 힘듭니다)
51. • Realm 은 세번째 방법을 사용합니다: 포인터!
• foreign 테이블 안의 오프셋을 가리킵니다
• pointer 가 0 이라면 “링크 없음”을 뜻 합니다
• 유일한 이슈는 객체가 지워졌을 때 레퍼런스를 유지하
는 일입니다
• 만약 객체가 foreign 테이블의 top 근처에서 삭제된
다면, 모든 포인터를 업데이트 해야 합니다! :(
52. 삭제 처리하기
• 링크가 삭제되었을 때, 마지막 레코드를 삭제된 레코드
자리로 이동합니다
• 이 방식을 사용하면, 하나의 링크만 업데이트가 필요합
니다
54. Google의 Joshua Bloch가 쓴 “How to Build a
Good API and Why it Matters” 를 꼭 읽어볼 것을 추
천합니다. j.mp/good-api-design
• “발표하기 전에 여러 앱들을 만들어보기”
• “모든 사람을 만족시킬 수는 없다”
• “API는 1가지 일을 해야 하고 그걸 잘해야 한다”
• “API는 가능하면 작아야 한다”
• “이름을 보고 어떤 역할을 하는지 알 수 있어야 한다”
• “통일성이 있어야한다”
이제부터는 우리가 배운 것들을 말씀드리겠습니다…
55. 최고의 API는 사람들이 이미 알고있는 것들이다
당신의 제품을 사용하기에 얼마나 걸리나요? 1주일? 3일?
0 시간은 어떤가요?
표준 문법과 언어나 프레임웍의 클래스를 따른다면, 모든
사람이 매우 바로 쓸 수 있는 API를 만드는 것이 가능합니
다.
예시: Realm 은 Realm 하나만 이해하면 됩니다. 다른 클
래스들은 직관적인 (RealmObject, RealmList)거나
필수가 아닌 것들 입니다.
56. 심플함 ≠ 심플한 API
심플한 API와 심플한 프로덕트 사이에는 커다란 차이가
있습니다!!
[…]
57. realm.beginTransaction()
dog.setName("Rex");
dog.setAge(3);
// dog.save()
realm.commitTransaction()
↑ vs ↓
// realm.beginTransaction()
dog.setName("Rex");
dog.setAge(3);
dog.save()
// realm.commitTransaction()
상단에 있는 답변 (명시적인 트랜젝션)이 ACID를 보장하
고, 충돌을 방지하기 위한 유일한 방법이고, 사용자가 멀티
쓰레드를 사용하는데에 큰 도움을 준다
58. 한번 벗어나면, 계속 그 길을 유지해야
한번 사용하는 언어의 스탠다드에서 벗어났으면(좋은 이
유로), 다음에도 그 것을 유지해서 API의 일관성을 유지하
는 것이 좋다.
Example:
- Realm
- RealmObject (can’t use just Object)
- RealmList (can’t use List or ArrayList)
- RealmResults (not Results or
RealmResultsList)
- RealmMigration (not Migration)
59. 사용자들은 이해하지 못하더라도 그것을 쓸 수 있어야 한
다
복잡한 개념을 단순화해서 사용자가 내부를 이해하지 않고
도 사용할 수 있도록 하는 것은 제품을 만드는 사람의 책임
이다.
예시: 마이그레이션 여러개의 데이터베이스의 상태를 데
이터의 차이점을 관리하면서 맵핑하고, 스키마와 디스크
저장방식을 관리 하는 것은 대부분의 사람들이 이해하기
힘든 것들이다. 우리는 보통 사용자들이 그런것들을 신경
쓸 필요 없도록 많은 노력을 기울였다. […]
60. […] 우리는 암묵적인 속성 추가를 허용합니다 (예를 들어
“name”이라는 속성을 모든 Dogs에 추가하기), 하지만
속성 삭제는 명시적으로 해야 합니다.
왜냐구요?
왜냐면 속성을 명시적으로 삭제하지 않으면, 그 컬럼이 추
가되고 삭제된 다음에 다시 추가되었는지, 아니면 처음으
로 추가된 것인지 알 수 없기 때문입니다. 이는 데이터의
일관성 이슈를 방지하기 위해서 필요합니다.
61. 1.0 는 새로운 0.1 입니다.
• 모바일 개발 사이클은 전통적인 서버사이드 개발/데스
크탑용 소프트웨어 개발보다 짧습니다.
• 요즘은 개발할 때 아무 많은 라이브러리를 사용합니다.
• 모바일 앱을 컨테이너화 하는 것은 의존성을 줄이는데
많은 도움을 줍니다.
• 덜 검증된 라이브러리를 쓰더라도 많은 장점을 가져올
수 있습니다.
• SDK 개발자가 API를 자주 수정하고/변화하고/개선하
는 것이 또한 많은 장점을 가져다 줍니다.
62. 지속적으로 관리하기
특별히 신경쓰지 않으면 복잡도가 점점 증가해서 API는
계속 쓰기 나빠질 것입니다!
새로운 기능을 추가하고, 버그를 고치, 하면서 계속 나빠질
것입니다.
API는 디자인이 아닙니다 — API는 구현하는 것이고, API
는 제품이고, API는 QA 입니다.
API는 생명체 입니다 :)
63. 감사합니다!
• http://realm.io/kr
• tim@realm.io 또는 kr@realm.io
• Vote for Realm BoF at 18:00 today :)
• Android용 Realm에 대한 한국어 모임이 있습니다.
10월 6일 월요일 / 역삼동 알럿스퀘어 B2:
onoffmix.com/event/33885
질문 있으세요?