couchdb on rails

53
CouchDB on Rails An Introduction Jonathan Weiss 03.07.2010

Upload: jonathan-weiss

Post on 15-Jan-2015

6.281 views

Category:

Technology


0 download

DESCRIPTION

Introduction into CouchDB and how to use it from Ruby/Rails. Presented by Jonathan Weiss presented at RailsCamp 4 in Cologne (03.07.2010)

TRANSCRIPT

Page 1: CouchDB on Rails

CouchDB on Rails An Introduction

Jonathan Weiss 03.07.2010

Page 2: CouchDB on Rails

Who am I?

Working for Peritor in Berlin, Germany

Written, maintain, or involved in

  Webistrano

  Capistrano

  SimplyStored

  Happening

  The great fire of London

http://github.com/jweiss

@jweiss

2

Page 3: CouchDB on Rails

Scalarium

EC2 Cluster Management

  Auto-config

  Self-Healing

  Auto-Scaling

  One-click-deployment

www.scalarium.com

3

Page 4: CouchDB on Rails

Database Requirements

High Availability

Easy Replication

Clustering

Robustness

Short Recovery Time

4

Page 5: CouchDB on Rails

5

Page 6: CouchDB on Rails

CouchDB

Build for the Web

Scales

Replication built-in

Embracing offline

Flexible schema – document DB

6

Page 7: CouchDB on Rails

7

”CouchDB is built of the Web“ Jacob Kaplan-Moss

Page 8: CouchDB on Rails

Web Technologies

HTTP the access protocol

JavaScript the query language

JSON the storage format

8

Page 9: CouchDB on Rails

JSON Document

{ "_id": "BCCD12CBB", "_rev": "1-AB764C", "type": "person", "name": "Darth Vader", "age": 63, "headware": ["Helmet", "Sombrero"], "dark_side": true, "weapons": { "right_arm": "light_saber", "left_arm": null } }

9

Page 10: CouchDB on Rails

JSON Document

{ "_id": "BCCD12CBB", "_rev": "1-AB764C", "type": "person", "name": "Darth Vader", "age": 63, "headware": ["Helmet", "Sombrero"], "dark_side": true, "weapons": { "right_arm": "light_saber", "left_arm": null } }

10

Page 11: CouchDB on Rails

JSON Document

{ "_id": "BCCD12CBB", "_rev": "1-AB764C", "type": "person", "name": "Darth Vader", "age": 63, "headware": ["Helmet", "Sombrero"], "dark_side": true, "weapons": { "right_arm": "light_saber", "left_arm": null } }

11

Page 12: CouchDB on Rails

No Tables or Namespaces

12

Page 13: CouchDB on Rails

No Tables or Namespaces

13

Page 14: CouchDB on Rails

Manual Namespacing

{ "_id": "BCCD12CBB", "_rev": "1-AB764C", "type": "person", "name": "Darth Vader", "age": 63, "headware": ["Helmet", "Sombrero"], "dark_side": true, "weapons": { "right_arm": "light_saber", "left_arm": null } }

14

Page 15: CouchDB on Rails

Interacting with CouchDB

15

PUT /dbname/ID

JSON

HTTP Client

Page 16: CouchDB on Rails

Interacting with CouchDB

16

JSON

GET /dbname/ID

HTTP Client

Page 17: CouchDB on Rails

Interacting with CouchDB

17

DELETE /dbname/ID HTTP Client

Page 18: CouchDB on Rails

18

Views

Page 19: CouchDB on Rails

Design Document { "id": "_design/hats”, "_rev": "431212AB4”, "language": "javascript”, "views": { "all": { "map": "function(doc){ .... }”, "reduce": "function(doc){ .... }” }, "by_manufacturer": { "map": "function(doc){ .... }”, "reduce": "function(doc){ .... }” } } }

19

Page 20: CouchDB on Rails

Design Document { "id": "_design/hats”, "_rev": "431212AB4”, "language": "javascript”, "views": { "all": { "map": "function(doc){ .... }”, "reduce": "function(doc){ .... }” }, "by_manufacturer": { "map": "function(doc){ .... }”, "reduce": "function(doc){ .... }” } } }

20

Document ID –

prefixed by “_design/”

Page 21: CouchDB on Rails

Design Document { "id": "_design/hats”, "_rev": "431212AB4”, "language": "javascript”, "views": { "all": { "map": "function(doc){ .... }”, "reduce": "function(doc){ .... }” }, "by_manufacturer": { "map": "function(doc){ .... }”, "reduce": "function(doc){ .... }” } } }

21

Hash of Views

Page 22: CouchDB on Rails

Design Document { "id": "_design/hats”, "_rev": "431212AB4”, "language": "javascript”, "views": { "all": { "map": "function(doc){ .... }”, "reduce": "function(doc){ .... }” }, "by_manufacturer": { "map": "function(doc){ .... }”, "reduce": "function(doc){ .... }” } } }

22

Hash of Views Every view has map &

reduce function

Page 23: CouchDB on Rails

Map

function(doc) { if (doc.headware) { for (var hat in doc.headware) { emit(hat, 1); } } }

23

Page 24: CouchDB on Rails

Map

function(doc) { if (doc.headware) { for (var hat in doc.headware) { emit(hat, 1); } } }

24

Passed every document in the DB

Page 25: CouchDB on Rails

Map

function(doc) { if (doc.headware) { for (var hat in doc.headware) { emit(hat, 1); } } }

25

Inspects & Decides

Page 26: CouchDB on Rails

Map

function(doc) { if (doc.headware) { for (var hat in doc.headware) { emit(hat, 1); } } }

26

Emits result for index

Page 27: CouchDB on Rails

Reduce

function(keys, values, rereduce) { return sum(values); }

27

Page 28: CouchDB on Rails

Reduce

function(keys, values, rereduce) { return sum(values); }

28

Passed map result (or partial reduce result)

Page 29: CouchDB on Rails

Reduce

function(keys, values, rereduce) { return sum(values); }

29

Aggregates (count, sum, average, …)

Page 30: CouchDB on Rails

Example Map Result

Map functions are similar to SQL indices

30

ID KEY VALUE

51ABFA211 Cap 1

ABC123456 Cappy 1

BCCD12CBB Helmet 1

BCCD12CBB Sombrero 1

Sorted by the key

Key can also be an array

Value can be complex JSON

Page 31: CouchDB on Rails

Query a view

31

GET /dbname/_design/hats/_view/all

HTTP Client

{"total_rows":348,"offset":0,"rows”:[ {"id":"A","key":"A","value":1}, {"id":"B","key":"B","value":1}, ]}

Page 32: CouchDB on Rails

Query a view

32

GET /dbname/_design/hats/_view/all?include_docs=true

HTTP Client

Page 33: CouchDB on Rails

View Query

Filter by

  key=ABC123

  startkey=123 & endkey=9

  limit=100

  descending=true

  group=true

  reduce=true

  Include_docs=true

33

Page 34: CouchDB on Rails

SQL vs. JavaScript

34

Vs.

Page 35: CouchDB on Rails

SQL vs. JavaScript

35

Vs.

ActiveRecord

SimplyStored

Page 36: CouchDB on Rails

SimplyStored

Convenience Layer for CouchDB

  Models & Associations

  Validations

  Callbacks

  Dynamic finder

  S3 attachments

  Paranoid delete

  ActiveModel compliant

36

BSD-licensed on http://github.com/peritor/simply_stored

On top of CouchPotato, CouchRest & RestClient

Page 37: CouchDB on Rails

Setup

37

Install

Load in environment.rb

Configure

Page 38: CouchDB on Rails

Setup

38

Page 39: CouchDB on Rails

39

Page 40: CouchDB on Rails

40

Page 41: CouchDB on Rails

RockingChair

In-memory CouchDB

  Just a big Hash

  Understands all SimplyStored generated views

  Speeds up tests

  Tests can run in parallel

  Nice for debugging

41

BSD-licensed on http://github.com/jweiss/rocking_chair

Page 42: CouchDB on Rails

Database Requirements

High Availability

Easy Replication

Clustering

Robustness

Short Recovery Time

42

Page 43: CouchDB on Rails

Replication

XXXXX

43

B-Tree

Photo by Mathias Meyer

Page 44: CouchDB on Rails

B-Tree

Append only

Concurrency (MVCC)

Crash resistant

Hot backups

Compaction

44

Page 45: CouchDB on Rails

Replication

45

Page 46: CouchDB on Rails

CouchDB Replication

46

POST /_replicate

POST /_replicate

Eventually consistent & conflict resolution

Page 47: CouchDB on Rails

Load Balancing

47

HTTP Client HTTP Load Balancer

Replication

Page 48: CouchDB on Rails

Caching

48

HTTP Client HTTP Cache Varnish Apache …

Page 49: CouchDB on Rails

Multi-Master

49

Page 50: CouchDB on Rails

Sharding/Partitioning with CouchDB Lounge

50

HTTP Client CouchDB Lounge

Page 51: CouchDB on Rails

Sharding with CouchDB Lounge

51

HTTP Client CouchDB Lounge

Page 52: CouchDB on Rails

Various

CouchApps

Validations

Filtered replication

Changes feed

Futon

Geo

Fulltext-Search with embedded Lucene

Experimental Ruby-View-Server

52

Page 53: CouchDB on Rails

© Peritor GmbH - Alle Rechte vorbehalten

Peritor GmbH Blücherstr. 22, Hof III Aufgang 6 10961 Berlin

Tel.: +49 (0)30 69 20 09 84 0 Fax: +49 (0)30 69 20 09 84 9

Internet: www.peritor.com E-Mail: [email protected]

Q&A