Advanced CouchDB phpday.it

169
CouchDB relax

description

A talk I did at phpday.it in Verona, Italy. Using some more advanced CouchDB functionality, like filters, changes feed, shows, geolocation (GeoCouch), and other interesting stuff. It also covers some real use cases.

Transcript of Advanced CouchDB phpday.it

Page 1: Advanced CouchDB phpday.it

CouchDBrelax

Page 2: Advanced CouchDB phpday.it

CouchDBrelax

Sander van de Graaf@svdgraaf

Page 4: Advanced CouchDB phpday.it

RELAX

Page 5: Advanced CouchDB phpday.it

CONTENTS

• Introduction

• PHP Usage

• Replication/Scalability

• Backend usage

• Couchapps

•Other stuff (GeoCouch!)

Page 6: Advanced CouchDB phpday.it

CouchDBrelax

Page 7: Advanced CouchDB phpday.it
Page 8: Advanced CouchDB phpday.it

NOSQL

Page 9: Advanced CouchDB phpday.it

IT’S A MOVEMENT

Page 10: Advanced CouchDB phpday.it

1998

Page 11: Advanced CouchDB phpday.it
Page 12: Advanced CouchDB phpday.it
Page 13: Advanced CouchDB phpday.it
Page 14: Advanced CouchDB phpday.it
Page 15: Advanced CouchDB phpday.it
Page 16: Advanced CouchDB phpday.it
Page 17: Advanced CouchDB phpday.it
Page 18: Advanced CouchDB phpday.it
Page 19: Advanced CouchDB phpday.it

Carlo Strozzi

Page 20: Advanced CouchDB phpday.it

NOSQL == Not Only SQL

Page 21: Advanced CouchDB phpday.it

“[The NoSQL movement] departs from the relational model altogether, it should therefore have been called more appropriately ‘NoREL’, or something to that effect.”

- Carlo Strozzi

Page 22: Advanced CouchDB phpday.it

CouchDBrelax

Page 23: Advanced CouchDB phpday.it
Page 24: Advanced CouchDB phpday.it
Page 25: Advanced CouchDB phpday.it
Page 26: Advanced CouchDB phpday.it
Page 27: Advanced CouchDB phpday.it
Page 28: Advanced CouchDB phpday.it
Page 29: Advanced CouchDB phpday.it
Page 30: Advanced CouchDB phpday.it
Page 31: Advanced CouchDB phpday.it

NUTSHELL

Page 32: Advanced CouchDB phpday.it

SPEED

Page 33: Advanced CouchDB phpday.it

APPEND ONLY

Page 34: Advanced CouchDB phpday.it

NO REPAIR NEEDED

Page 35: Advanced CouchDB phpday.it

COMPACTING

Page 36: Advanced CouchDB phpday.it

HTTP SERVER

Page 37: Advanced CouchDB phpday.it

CAP

Page 38: Advanced CouchDB phpday.it

CAP

CouchDB

Page 39: Advanced CouchDB phpday.it

EVENTUALLY CONSISTENT

CouchDB

Page 40: Advanced CouchDB phpday.it

FULL REST API

Page 41: Advanced CouchDB phpday.it

HTTP METHODS

• GET

• PUT

• POST

•DELETE

• COPY

• SELECT

• UPDATE

• INSERT

•DELETE

• ...

Page 42: Advanced CouchDB phpday.it
Page 43: Advanced CouchDB phpday.it

{ "total_rows": 2, "offset": 0, "rows": [ { "id": "abc089b91fadfcf67a438e73f426f71d", "key": [ "2011-05-07 13:52:15", "abc089b91fadfcf67a438e73f426f71d" ], "value": { "_id": "abc089b91fadfcf67a438e73f426f71d", "_rev": "2-a38e08996586cd774b0b5c3006659de0", "message": "A2 HUISARTSENPOST BARNEVELD NIJKERKERWEG 119 3771LA 119" } }, { "id": "abc089b91fadfcf67a438e73f4286fd5", "key": [ "2011-05-07 14:00:16", "abc089b91fadfcf67a438e73f4286fd5" ], "value": { "_id": "abc089b91fadfcf67a438e73f4286fd5", "_rev": "2-691929b5f3d6cde58f27d62681c7b599", "message": "A1 LEEUWERIKSWEIDE 183 WAGENINGEN 6708LH 183" } } ] }

Page 44: Advanced CouchDB phpday.it

REPLICATION

Page 45: Advanced CouchDB phpday.it
Page 46: Advanced CouchDB phpday.it
Page 47: Advanced CouchDB phpday.it

CONTENTS

• Introduction

• PHP Usage

• Replication/Scalability

• Backend usage

• Couchapps

•Other stuff

Page 48: Advanced CouchDB phpday.it

RELAX

Page 49: Advanced CouchDB phpday.it

PHP USAGE

Page 50: Advanced CouchDB phpday.it

PHP LIBRARIES

• PHPillow (LGPL)

• PHP Object Freezer (BSD)

• PHP On Couch (GPL 2 / 3)

• PHP CouchDB Extension (PHP license)

• SAG for CouchDB (apache)

•Doctrine 2 CouchDB ODM

Page 51: Advanced CouchDB phpday.it

<?PHP// setup connection for couchdb$client = new Couchdb_Client('http://ponies.couchone.com:5984','rainbows');

// fetch a document$doc = $client->getDoc('awesome_pony');

// updating document$doc->type = "awesome";

try { $client->storeDoc($doc);}catch (Exception $e) { echo "Document storage failed : " . $e->getMessage();}

PHP ON COUCH

Page 52: Advanced CouchDB phpday.it

CONTENTS

• Introduction

• PHP Usage

• Replication/Scalability

• Backend usage

• Couchapps

•Other stuff

Page 53: Advanced CouchDB phpday.it

REPLICATION

Page 54: Advanced CouchDB phpday.it

DEFINITION

“Replication is the process of sharing information so as to ensure consistency between redundant resources, such as software or hardware components, to improve reliability, fault-tolerance, or accessibility.”

Source: wikipedia

Page 55: Advanced CouchDB phpday.it
Page 56: Advanced CouchDB phpday.it

CouchDBrelax

Page 57: Advanced CouchDB phpday.it

CouchDBrelax

CouchDBrelax

Page 58: Advanced CouchDB phpday.it

CouchDBrelax

CouchDBrelax

CouchDBrelax

CouchDBrelax

Page 59: Advanced CouchDB phpday.it

CouchDBrelax

CouchDBrelax

Page 60: Advanced CouchDB phpday.it

CouchDBrelax

CouchDBrelax

CouchDBrelax

Page 61: Advanced CouchDB phpday.it

CouchDBrelax

CouchDBrelax

CouchDBrelax

US NL

BE

Page 62: Advanced CouchDB phpday.it

USE CASEIDG Publishers

Page 63: Advanced CouchDB phpday.it
Page 64: Advanced CouchDB phpday.it
Page 65: Advanced CouchDB phpday.it
Page 66: Advanced CouchDB phpday.it

IDG NL IDG DE

IDG US IDG AUSTRALIA

CouchDBrelax

CouchDBrelax

CouchDBrelax

CouchDBrelax

CouchDBrelax

CouchDBrelax

CouchDBrelax

Page 67: Advanced CouchDB phpday.it

IDG NL IDG US

IDG DE IDG Italy

IDG Brazil

IDG Romania

IDG Poland

IDG SpaniaIDG UK

IDG Ghana

IDG Hungary

IDG Sweden

IDG Portugal

IDG Japan IDG Thailand IDG Vietnam

Page 68: Advanced CouchDB phpday.it

IMPLICATIONEvery single bit of IDG content published

worldwide, is available anywhere, anytime in msec.

Page 69: Advanced CouchDB phpday.it

P2P WEB

Page 70: Advanced CouchDB phpday.it

“World Domination”

Page 71: Advanced CouchDB phpday.it

HOW DO I DO THAT?

Page 72: Advanced CouchDB phpday.it

CLUSTERING“The fun stuff ”

Page 73: Advanced CouchDB phpday.it
Page 74: Advanced CouchDB phpday.it

CouchDBrelax

CouchDBrelax

loadbalancer

...n

Page 75: Advanced CouchDB phpday.it

CHALLENGES

• Large amounts of data

• Large views (with big/long map/reduce queries)

• LOTS of traffic

• Location based partitions

• For fun and profit

Page 76: Advanced CouchDB phpday.it

MAP/REDUCE

Page 77: Advanced CouchDB phpday.it

INPUT

IP Bytes

212.122.174.13 18271

212.122.174.13 191726

212.122.174.13 198

74.119.8.111 91272

74.119.8.111 8371

212.122.174.13 43

Page 78: Advanced CouchDB phpday.it

MAPPER => REDUCER

IP Bytes

212.122.174.13

18271

212.122.174.13191726

212.122.174.13198

212.122.174.13

43

74.119.8.11191272

74.119.8.1118371

Page 79: Advanced CouchDB phpday.it

AFTER REDUCE

IP Bytes

212.122.174.13 210238

74.119.8.111 99643

Page 80: Advanced CouchDB phpday.it

PARTITION INPUT

Partition IP Bytes

0 212.122.174.13 18271

0 212.122.174.13 191726

0 212.122.174.13 198

1 74.119.8.111 91272

1 74.119.8.111 8371

0 212.122.174.13 43

Page 81: Advanced CouchDB phpday.it

MAPPER => REDUCER

Partition IP Bytes

0 212.122.174.13

18271

0 212.122.174.13191726

0 212.122.174.13198

0 212.122.174.13

43

1 74.119.8.11191272

1 74.119.8.1118371

Page 82: Advanced CouchDB phpday.it

AFTER REDUCE

IP Bytes

212.122.174.13 210238

74.119.8.111 99643

Page 83: Advanced CouchDB phpday.it

• CouchDB Lounge

• Pillow

• BigCouch

CLUSTERING OPTIONS

Page 84: Advanced CouchDB phpday.it

LOUNGE

•partitioning/clustering

•Nginx module

•meebo.com

• ‘easy’

•http://tilgovi.github.com/couchdb-lounge/

Page 85: Advanced CouchDB phpday.it

LOUNGE

• dumb_proxy => proxy for simple PUT/GET’s

• smart_proxy => proxy for map/reduce over shards

• replicator => updates all copies, redundantly

Page 86: Advanced CouchDB phpday.it

CouchDBrelax

CouchDBrelax

nginx

...n

dumb_proxy

Page 87: Advanced CouchDB phpday.it

CouchDBrelax

CouchDBrelax

nginx

...n

smart_proxy

Page 88: Advanced CouchDB phpday.it

Bonus:

other nginx modules work too

Page 89: Advanced CouchDB phpday.it

PILLOW

•Erlang based

• router/rereducer (map/reduce over multiple systems)

• In development (but promising!)

•https://github.com/khellan/Pillow

Page 90: Advanced CouchDB phpday.it

BIGCOUCH

•Fork

•100% api compatible

•Open Source/Commercial

•https://cloudant.com/#!/solutions/bigcouch

Page 91: Advanced CouchDB phpday.it

CONTENTS

• Introduction

• PHP Usage

• Replication/Scalability

• Backend usage

• Couchapps

•Other stuff

Page 92: Advanced CouchDB phpday.it

BACKEND USAGE

Page 93: Advanced CouchDB phpday.it

PROXIED

CouchDBrelax

Page 94: Advanced CouchDB phpday.it

DIRECT

CouchDBrelax

Page 95: Advanced CouchDB phpday.it

NOSQL && SQL HYBRID

• onSave, onCommit hooks available in every major framework

• onSave -> make a JSON representation of your object, and PUT it to couchdb (#protip: only ‘public’ data)

• sql db is leading, you don’t care about versioning in couchdb

• you can use your data directly from couchdb within your frontend javascript

Page 96: Advanced CouchDB phpday.it

<?php

class Pony extends Application_models{ public function toArray() { $data = $this->_getData();

// we don't want any private data pushed unset($data['created_on']); unset($data['created_by']); unset($data['access_level']); unset($data['private_data']);

$data['tags'] = $this->getTags(); $data['categories'] = $this->getCategories(); $data['rainbows'] = 'double'; return $data; }}

MODEL

Page 97: Advanced CouchDB phpday.it

AFTER_SAVE<?php

class article_module extends admin_module{ public function after_save() { parent::after_save(); $data = $this->toJson();

// store the document in couchdb $res = CouchDB::put($data); // set the local id and revision, so we can // use it the next time $this->_id = $res->_id; $this->_rev = $res->_rev; }}

Page 98: Advanced CouchDB phpday.it

RewriteEngine OnRewriteRule /data/(.*) http://127.0.0.1:5984/db/$1 [P,L]

PROXY

Page 99: Advanced CouchDB phpday.it

?callback=foobar

JSONP

foobar(...)

Page 100: Advanced CouchDB phpday.it

JAVASCRIPT

<script type="text/javascript">$.getJSON("/db/ponies/_design/ponies/_view/best-ponies?include_docs=true",function(res){ for(i in res.rows) { doc = res.rows[i].doc; // do stuff }});</script>

Page 101: Advanced CouchDB phpday.it

CONTENTS

• Introduction

• PHP Usage

• Replication/Scalability

• Backend usage

• Couchapps

•Other stuff

Page 102: Advanced CouchDB phpday.it

COUCHAPP

Page 103: Advanced CouchDB phpday.it

“Distributed, scalable, web applications you say?

omgwtfbbq!?!1!!!one1!1!eleven”

Page 104: Advanced CouchDB phpday.it

_attachments

Page 105: Advanced CouchDB phpday.it

CouchDBrelax

CouchDBrelax

CouchDBrelax

Page 106: Advanced CouchDB phpday.it

INSTALLATION

Couchapp 0.7.5

Page 107: Advanced CouchDB phpday.it

$ couchapp init

Page 108: Advanced CouchDB phpday.it

LAYOUT

Page 109: Advanced CouchDB phpday.it

$ couchapp push http://ponies.couchone.com:5984/rainbows

Page 112: Advanced CouchDB phpday.it

CONTENTS

• Introduction

• PHP Usage

• Replication/Scalability

• Backend usage

• Couchapps

•Other stuff

Page 113: Advanced CouchDB phpday.it

OTHER STUFF

Page 114: Advanced CouchDB phpday.it

REWRITES

Page 115: Advanced CouchDB phpday.it

_REWRITE

Page 117: Advanced CouchDB phpday.it
Page 118: Advanced CouchDB phpday.it

{ .... "rewrites": [{ "from": "/best-5-ponies", "to": "ponies/_view/best-ponies", "method": "GET", "query": { "descending": true, "limit": 5, "key": "foobar" } }]}

STEP 1

Page 121: Advanced CouchDB phpday.it

[vhosts]awesomeponies.com = /rainbows/_design/ponies/_rewrite

STEP 2

Page 124: Advanced CouchDB phpday.it
Page 125: Advanced CouchDB phpday.it

_CHANGES

Page 126: Advanced CouchDB phpday.it

RELAX

Page 127: Advanced CouchDB phpday.it

$ curl -X GET "http://ponies.couchone.com/rainbows/_changes"

Page 128: Advanced CouchDB phpday.it

{"results":[

], "last_seq":0}

Page 129: Advanced CouchDB phpday.it

curl -X PUT http://ponies.couchone.come/rainbows/foobar -d '{"type":"awesome"}'

Page 130: Advanced CouchDB phpday.it

{"results":[ { "seq":1, "id":"foobar", "changes":[{"rev":"1-aaa8e2a031bca334f50b48b6682fb486"}] }], "last_seq":1}

Page 131: Advanced CouchDB phpday.it

{"results":[ { "seq":1, "id":"foobar", "changes":[{"rev":"1-aaa8e2a031bca334f50b48b6682fb486"}] }, { "seq":2, "id":"foobar2", "changes":[{"rev":"1-e18422e6a82d0f2157d74b5dcf457997"}] }], "last_seq":2}

Page 132: Advanced CouchDB phpday.it

_CHANGES OPTIONS

• ?since

• Longpolling

• Continuous

Page 133: Advanced CouchDB phpday.it

$ curl -X GET "http://ponies.couchone.com/rainbows/_changes?since=20"

SINCE

Page 134: Advanced CouchDB phpday.it

curl -X GET "http://ponies.couchone.com/rainbows/_changes?feed=longpoll&since=2"

LONGPOLLING

Page 135: Advanced CouchDB phpday.it

curl -X GET "http://ponies.couchone.com/rainbows/_changes?feed=continuous&since=2"

CONTINOUS

Page 136: Advanced CouchDB phpday.it
Page 137: Advanced CouchDB phpday.it

FILTERS

Page 138: Advanced CouchDB phpday.it

function(doc, req) { if(doc.priority == 'high') { return true; } return false;}

FILTERS/IMPORTANT.JS

Page 140: Advanced CouchDB phpday.it

function(doc, req) { if(doc.city.name == req.query.name) { return true; } return false;}

FILTERS/CITY.JS

Page 141: Advanced CouchDB phpday.it

curl -X GET"http://ponies.couchone.com/rainbows/_changes?feed=continuous&filter=app/name&name=verona

Page 142: Advanced CouchDB phpday.it

SHOWS

Page 143: Advanced CouchDB phpday.it

function(doc, req) { return { body: "Hello World" }}

Page 145: Advanced CouchDB phpday.it

function(doc) { return { "code": 302, "body": "See other", "headers": { "Location": doc.target } };}

Page 146: Advanced CouchDB phpday.it

USE CASECDN

Page 147: Advanced CouchDB phpday.it

From public hash to private file

/m/m1gz4l4a1clb.jpg

a2d85de382c8672925174e731a1d2a89

Page 148: Advanced CouchDB phpday.it

Varnish middleware

storage(http based)

proprietarywebserver

mysql

1 2 3

4

5

Page 149: Advanced CouchDB phpday.it

middleware

storage(http based)

nginx + mod_cacheVarnish

1 2 3

4

Page 150: Advanced CouchDB phpday.it

function(doc) { return { "code": 302, "body": "See other", "headers": { "Location": doc.target } };}

Page 151: Advanced CouchDB phpday.it

{ "_id": "m1gz4l4a1clb", "_rev": "2-d7855bba9445f446c0b71f044e796c28", "content-type": "image/jpeg", "target": "http://10.16.10.1/a2d85de382c8672925174e731a1d2a89",}

Page 152: Advanced CouchDB phpday.it

LUCENE

Page 153: Advanced CouchDB phpday.it

[external]fti=/path/to/python /path/to/couchdb-lucene/tools/couchdb-external-hook.py

[httpd_db_handlers]_fti = {couch_httpd_external, handle_external_req, <<"fti">>}

Page 154: Advanced CouchDB phpday.it

function(doc) { var ret=new Document(); ret.add(doc.message); ret.add(new Date(doc.datetime)); return ret;}

FULLTEXT/BY_MESSAGE/BY_QUERY.JS

Page 156: Advanced CouchDB phpday.it

GEOCOUCHhttps://github.com/vmx/couchdb

Page 157: Advanced CouchDB phpday.it
Page 158: Advanced CouchDB phpday.it

GEOCOUCH

• Supports bbox, polygon, lines, etc.

• fork (for now)

• outputs via lists, georss possible

• directly useable by google maps

• can read GIS data

• combined with _changes makes interesting use cases possible

Page 159: Advanced CouchDB phpday.it

SPATIAL INDEXin spatial/points.js

function(doc) { if (doc.geo && doc.geo.latitude != '' && doc.geo.longitude != '') { emit( { type: "Point", coordinates: [ parseFloat(doc.geo.latitude), parseFloat(doc.geo.longitude) ] }, [ doc._id, doc ] ); } }

Page 160: Advanced CouchDB phpday.it

SPATIAL INDEXin spatial/points.js

function(doc) { if (doc.geo && doc.geo.latitude != '' && doc.geo.longitude != '') { emit( { type: "Point", coordinates: [ parseFloat(doc.geo.latitude), parseFloat(doc.geo.longitude) ] }, [ doc._id, doc ] ); } }

Page 161: Advanced CouchDB phpday.it

SPATIAL INDEXin spatial/points.js

function(doc) { if (doc.geo && doc.geo.latitude != '' && doc.geo.longitude != '') { emit( { type: "Point", coordinates: [ parseFloat(doc.geo.latitude), parseFloat(doc.geo.longitude) ] }, [ doc._id, doc ] ); } }

Page 162: Advanced CouchDB phpday.it

http://db.example.com/couchappdemo/_design/phpday/_spatial/points?bbox=0,0,180,90

Worldwide search

{"update_seq":3,"rows":[ { "id":"Verona", "bbox":[10.991748,45.438367,10.991748,45.438367], "value":[ "Verona", [10.991748,45.438367] ] }]}

Page 163: Advanced CouchDB phpday.it

bbox=west,south,east,north

Page 164: Advanced CouchDB phpday.it
Page 165: Advanced CouchDB phpday.it

https://github.com/couchbaselabs/iOS-Couchbase

COUCHDB FOR IOS

Page 166: Advanced CouchDB phpday.it

http://www.iriscouch.com/

Page 168: Advanced CouchDB phpday.it

Q?

Page 169: Advanced CouchDB phpday.it

http://joind.in/talk/view/3009