63
Realm () Android & iOS 위한 데이터베이스

[1B6]Realm a database for android & ios

Embed Size (px)

Citation preview

Realm (렘)Android & iOS 를 위한 데이터베이스

• Tim Anglade

• 개발자, Realm의 프로덕트 담당 임원

• 기존직장: Cloudant (CouchDB, acquired by IBM), MongoDB Inc, Apigee, NASDAQ Stock Exchange

• 개발 언어: Ruby, JavaScript, Java, Objective-C, Swift, Prolog, Pascal, C#

이분들이 DEVIEW를 성공으로 이끈 주역들 입니다.이분들께 커다란 박수를 드리고 싶습니다. 송창현, 옥상훈, 조한용, 박은정, 김동호 and everybody else!

다음에 이분들을 보시면 감사표시를 해주세요 ^^

개요

1. Realm(렘) 소개2. 배운 것들

2.1 내부 디자인2.2 API 디자인

3. Q&A

1. Realm(렘) 소개

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.

한국어 : 영역

• 새로운 데이터베이스, 모바일에서의 SQLite 역할을 대신할

• 모바일을 위한 디자인• 스마트폰, 태블릿 & 웨어러블에서 직접 동작함• 객체/모델-지향, 하지만 ORM은 아닙니다

• ACID 완벽지원• 간단한 쓰레드 모델 지원• C++ 코어 기반의 크로스 플랫폼

• 2014 7월에 발표, 2011년 부터 지적인 개발, 2012 부터 실제 제품에 사용됨

• 수만명의 개발자들이 앱개발에 사용중

• 수백만의 사용자들이 실제 사용중

• iOS 버전은 지금 당장 사용가능, Android 버전은 곧 사용가능

• > 8주만에 2만 명의 개발자가 사용• Parse.com 보다 빠른 성장

(8개월 동안 1만 명의 개발자가 사용)

• 9주동안 계속 Github 의 '탑 트렌드 프로젝트'

• “아름답고, 작은 메모리를 차지하며 다양한 플랫폼을 지원하는 모바일 앱을 위한 데이터베이스가 드디어 탄생 했습니다. 또한 디자인도 매우 아름답습니다.”—David Helgason, CEO, Unity

많은 앱에서 이미 사용중 입니다

• Breeze (TechCrunch Disrupt 파이널, 20억원 정도의 투자를 받음)

• Cloth (뉴욕타임즈에 많이 소개된)

• Zynga (매일 수백만명의 사용자가 사용하는 게임에서 사용중)

• + ~1,000 개의 앱이 이미 앱스토어에 올라오있거나 개발 완료단계

• 다음은 누구 일까요? 한국에 있는 우리의 제일 큰 팬은 누구?

수많은 사람들이 제게 Android 용 Realm

이 언제 출시되는지 물었습니다.곧 발표할 예정입니다!

얼마나 곧 이냐구요?

얼마나?오늘!

DEVIEW 를 위해 준비된!

Android용 Realm은 지금 사용가능 합니다

realm.io/krAndroid용 Realm에 대한 모임이 있습니다(한국어 진행).10월 6일 월요일 / 역삼동 알럿스퀘어 B2:

onoffmix.com/event/33885

모델(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}

쓰기

Realm realm = Realm.getInstance(this.getContext());

// Transactions give you easy thread-safetyrealm.beginTransaction();Dog dog = realm.createObject(Dog.class);dog.setName("Rex");dog.setAge(3);realm.commitTransaction();

쿼리

// Queries uses Builder pattern to// build up the query conditionsRealmResults<Dog> query = realm.where(Dog.class) .greaterThan("age", 8) .findAll();// Queries are chainableRealmResults<Dog> allRex = query.where() .contains("name", "rex") .findAll();

관계

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();

쓰레드 안전하게 관리하기

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();

암호화

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();

디자인 목표

1. 모던하고

2. 간단하며

• 배우기 쉽고 (< 1 hour)

• 관리하고/디버그하기 쉽고

• 여러 쓰레드에서 사용하기 쉽게

3. 속도가 빠르게

디자인 목표

1. 모던하고

2. 간단하며

• 배우기 쉽고 (< 1 hour)

• 관리하고/디버그하기 쉽고

• 여러 쓰레드에서 사용하기 쉽게

3. 속도가 빠르게

2. 배운 것들

2.1 데이터베이스 내부 디자인에 대해서 배운것

역사적 배경

• 대부분의 데이터 구조(배열, 해시, 등등)는 80년대에 만들어졌습니다

• 그당시에는, CPU와 메모리의 속도가 거의 비슷했습니다

• 이제는 상황이 달라졌습니다… 프로세서가 1000배 이상 빠릅니다

• 매일 사용하는 프로그램의 성능에 많은 영향을 끼쳤습니다

• 데이터베이스에 끼친 영향은 더욱 큽니다

가변 배열

일반적인 레이아웃

struct mytype { bool value1; int64_t value2; int value3;};mytype myarray[2];

패딩!

행 기반의 데이터베이스

• 비슷한 레이아웃을 사용하는 경향이 있다• 때로는 가변 인코딩을 사용하고, 이는 오버헤드를 발생시킨다

• 행을 불러오는데 최적화 되어있지만, 그게 병목은 아니다

• 행을 불러오는 것은 프로세서 캐시를 더럽힌다 (~64-128 바이트)

컬럼 지향!

• 데이터를 컬럼 기준으로 자른다 - 한 컬럼당 하나의 배열

• 패딩의 필요성이 없어진다• 한 컬럼에서 이터레이션 할 때, 캐시를 건드리지 않는다

추가적인 최적화

• 하나의 boolean 값은 보통 1 byte 전체를 차지한다 (8 bits) - 87%가 낭비됨!

• 그 대신에 Realm은 로 접근할 수 있도록 바이트당 8개의 boolean을 저장하고 간단한 bit 쉬프트를 한다

• integer를 위해서는, 우리는 배열을 인서트 될 수 있는 가장 큰 숫자의 길이에 맞추는데 길이는 0, 1, 2, 4, 8, 16, 32 와 64 bit를 사용한다. 이로인해 64-bit 블럭에 최소한의 오버헤드로 들어가도록 한다.

Realm의 가변 배열의 효과

1. 데이터가 훨씬 작다 (sqlite 사이즈의 50% 이하)2. 검색이 훨씬 빠르다 (캐시 최적화 덕분에)3. 컬럼 이터레이션이 훨씬 빠르다 (쿼리에 매우 유리한 조건이다)

4. 벡터 연산이 훨씬 빠르다

Realm 은 가변 배열의 그래프이다

• 가변배열은 b-tree에 연결되어있다• 전체 구조는 매우 규칙적이다: 가변배열은 저~ 하부구조에 있다

• 메모리에 매핑하기가 쉽다

Copy-on-Write

• Realm은 쓰기할 때 읽기를 block 하지 않기 위해서 COW(Copy-on-Write)를 사용한다

• 디스크에 시리얼화(serialize) 하기 위해서, 새로운 탑 노드에서부터 트리를 읽는다

Multiversion concurrency control (MVCC)

• 이 방식을 사용해서 여러 버전의 그래프를 유지할 수 있습니다

• 쉬운 MVCC (git과 같은)• 각 버전은 완전한 일관성을 가집니다 (ACID 개념)

비압축 b-tree

• 압축이 필요 없습니다! 우리는 제일 오래된 버전을 표시하고 유지하는 하는 방식으로 기존 버전의 공간을 재사용 합니다

복사없는 쿼리처리

• Realm 쿼리는 복사되는 것이아니, 매핑 됩니다• SQL 쿼리에 비교하자면: 투영된 것을 보게되는 것이 아니라, 실제 데이터를 보게 됩니다

• 컨텍스트 (다른 컬럼의)는 언제나 사용 가능합니다• 쿼리 결과의 값을 쉽게 수정할 수 있습니다

지그재그 쿼리

일반적인 검색 알고리즘

size_t find(size_t start, size_t end) {size_t i = start;while(i < end && first[i] > 5 && first[i] < 10 && second[i] == 200 && third[i] != 0)i++; if(i < end) return i; else return -1;}

지그재그 쿼리

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;}

지그재그 쿼리

• 우리는 각 조건문을 루프안에서도 테스트 하였습니다• 컬럼-지향의 장점을 사용합니다, 캐싱!• 최적의 패스를 찾을 수 있다는 것을 보장하지는 않지만, 대부분의 경우에 최적에 가까운 경로를 사용합니다

링크

Dog mydog = realm.createObject(Dog.class);Person person = realm.createObject(Person.class);person.getDogs().add(mydog);

일반적으로:1. 그래프 (탐색하기 좋지만, 일반적인 검색 등에서 좋지 않습니다)2. 문서 (비정규화된 복사 — 유지하기 힘듭니다)

• Realm 은 세번째 방법을 사용합니다: 포인터!

• foreign 테이블 안의 오프셋을 가리킵니다

• pointer 가 0 이라면 “링크 없음”을 뜻 합니다

• 유일한 이슈는 객체가 지워졌을 때 레퍼런스를 유지하는 일입니다

• 만약 객체가 foreign 테이블의 top 근처에서 삭제된다면, 모든 포인터를 업데이트 해야 합니다! :(

삭제 처리하기

• 링크가 삭제되었을 때, 마지막 레코드를 삭제된 레코드 자리로 이동합니다

• 이 방식을 사용하면, 하나의 링크만 업데이트가 필요합니다

2.2 API 디자인에 대해서 배운것

Google의 Joshua Bloch가 쓴 “How to Build a Good API and Why it Matters” 를 꼭 읽어볼 것을 추천합니다. j.mp/good-api-design

• “발표하기 전에 여러 앱들을 만들어보기”• “모든 사람을 만족시킬 수는 없다”• “API는 1가지 일을 해야 하고 그걸 잘해야 한다”• “API는 가능하면 작아야 한다”• “이름을 보고 어떤 역할을 하는지 알 수 있어야 한다”• “통일성이 있어야한다”이제부터는 우리가 배운 것들을 말씀드리겠습니다…

최고의 API는 사람들이 이미 알고있는 것들이다

당신의 제품을 사용하기에 얼마나 걸리나요? 1주일? 3일?0 시간은 어떤가요?표준 문법과 언어나 프레임웍의 클래스를 따른다면, 모든 사람이 매우 바로 쓸 수 있는 API를 만드는 것이 가능합니다.예시: Realm 은 Realm 하나만 이해하면 됩니다. 다른 클래스들은 직관적인 (RealmObject, RealmList)거나 필수가 아닌 것들 입니다.

심플함 ≠ 심플한 API

심플한 API와 심플한 프로덕트 사이에는 커다란 차이가 있습니다!![…]

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를 보장하고, 충돌을 방지하기 위한 유일한 방법이고, 사용자가 멀티 쓰레드를 사용하는데에 큰 도움을 준다

한번 벗어나면, 계속 그 길을 유지해야

한번 사용하는 언어의 스탠다드에서 벗어났으면(좋은 이유로), 다음에도 그 것을 유지해서 API의 일관성을 유지하는 것이 좋다.Example:- Realm- RealmObject (can’t use just Object)- RealmList (can’t use List or ArrayList)- RealmResults (not Results or RealmResultsList)- RealmMigration (not Migration)

사용자들은 이해하지 못하더라도 그것을 쓸 수 있어야 한다

복잡한 개념을 단순화해서 사용자가 내부를 이해하지 않고도 사용할 수 있도록 하는 것은 제품을 만드는 사람의 책임이다.예시: 마이그레이션 여러개의 데이터베이스의 상태를 데이터의 차이점을 관리하면서 맵핑하고, 스키마와 디스크 저장방식을 관리 하는 것은 대부분의 사람들이 이해하기 힘든 것들이다. 우리는 보통 사용자들이 그런것들을 신경쓸 필요 없도록 많은 노력을 기울였다. […]

[…] 우리는 암묵적인 속성 추가를 허용합니다 (예를 들어 “name”이라는 속성을 모든 Dogs에 추가하기), 하지만 속성 삭제는 명시적으로 해야 합니다.

왜냐구요?왜냐면 속성을 명시적으로 삭제하지 않으면, 그 컬럼이 추가되고 삭제된 다음에 다시 추가되었는지, 아니면 처음으로 추가된 것인지 알 수 없기 때문입니다. 이는 데이터의 일관성 이슈를 방지하기 위해서 필요합니다.

1.0 는 새로운 0.1 입니다.

• 모바일 개발 사이클은 전통적인 서버사이드 개발/데스크탑용 소프트웨어 개발보다 짧습니다.

• 요즘은 개발할 때 아무 많은 라이브러리를 사용합니다.• 모바일 앱을 컨테이너화 하는 것은 의존성을 줄이는데 많은 도움을 줍니다.

• 덜 검증된 라이브러리를 쓰더라도 많은 장점을 가져올 수 있습니다.

• SDK 개발자가 API를 자주 수정하고/변화하고/개선하는 것이 또한 많은 장점을 가져다 줍니다.

지속적으로 관리하기

특별히 신경쓰지 않으면 복잡도가 점점 증가해서 API는 계속 쓰기 나빠질 것입니다!새로운 기능을 추가하고, 버그를 고치, 하면서 계속 나빠질 것입니다.API는 디자인이 아닙니다 — API는 구현하는 것이고, API는 제품이고, API는 QA 입니다.API는 생명체 입니다 :)

감사합니다!• http://realm.io/kr

[email protected] 또는 [email protected]

• Vote for Realm BoF at 18:00 today :)

• Android용 Realm에 대한 한국어 모임이 있습니다. 10월 6일 월요일 / 역삼동 알럿스퀘어 B2: onoffmix.com/event/33885

질문 있으세요?