31
1 1 Getting Started with Couchbase App Development Michael Nitschinger Developer Advocate @daschl

CCB12 Getting Started with Couchbase App Development

Embed Size (px)

Citation preview

Page 1: CCB12 Getting Started with Couchbase App Development

11

Getting Started withCouchbase App Development

Michael NitschingerDeveloper Advocate@daschl

Page 2: CCB12 Getting Started with Couchbase App Development

2

What we’ll talk about

• Setup Development Environment• Intro to Document Databases• Intro to Couchbase Operations• Basic Document Modeling• Modeling Examples

Page 3: CCB12 Getting Started with Couchbase App Development

3 3

Basics & Getting started

Page 4: CCB12 Getting Started with Couchbase App Development

4

Couchbase is Faster, Scales and Simplifies

App Servers

API Servers

Couchbase ServerCluster

Page 5: CCB12 Getting Started with Couchbase App Development

5

Download & Install Couchbase

• Downloads at couchbase.com/download

• Provision via wizard in Web Console– Or provision via REST interface: operations folks to automate provisioning

(i.e Chef, puppet, Rightscale rightscript)

• Linux: Ubuntu and Red Hat/CentOS– Packages for most common distributions.

• dpkg -i , rpm -i, etc.

• Mac– Download a .zip, open, drag to Applications

• Windows– Download a setup.exe, double click

Page 6: CCB12 Getting Started with Couchbase App Development

6

Setup Smart Client SDK

• High performance, official client libraries for Java, .NET, PHP, Ruby, C, Python– Community supported for Clojure, JRuby, Perl, Go, Erlang,

Node.js

• Head to couchbase.com/develop for SDKs – Client libraries– Getting Started guides– Tutorial with a sample application– A complete API reference

Page 7: CCB12 Getting Started with Couchbase App Development

7

Client Setup: Getting Cluster Configuration

http://myserver:8091/

{…    "bucketCapabilities": [        "touch",         "sync",         "couchapi"    ],     "bucketCapabilitiesVer": "sync-1.0",     "bucketType": ”couchbase",    "name": "default",     "nodeLocator": "vbucket",     "nodes": [….

Couchbase ClientCouchbase ClientCluster Configuration

over REST

Page 8: CCB12 Getting Started with Couchbase App Development

8

Client Setup: Getting Cluster Configuration

Couchbase ClientCouchbase Client

New Node Added to Cluster and Coming

OnlineCouchbase TopologyCouchbase Topology

UpdateUpdateCouchbase TopologyCouchbase Topology

UpdateUpdate

Page 9: CCB12 Getting Started with Couchbase App Development

9 9

Document Database Basics

Page 10: CCB12 Getting Started with Couchbase App Development

10

The relational approach to model data

http://martinfowler.com/bliki/AggregateOrientedDatabase.html

Page 11: CCB12 Getting Started with Couchbase App Development

11

Compared to a Document Database

• Easy to distribute data• Makes sense to application programmers

o::1001{uid: “ji22jd”,customer: “Ann”,line_items: [

{ sku: 0321293533, quan: 3, unit_price: 48.0 },{ sku: 0321601912, quan: 1, unit_price: 39.0 },{ sku: 0131495054, quan: 1, unit_price: 51.0 }

],payment: { type: “Amex”, expiry: “04/2001”,

last5: 12345}

Page 12: CCB12 Getting Started with Couchbase App Development

12

JSON Documents

• Maps more closely to external API• CRUD Operations, lightweight and implicit schema

• Stored under a unique identifier key

myDocument = { “fields” : [“with basic types”, 3.14159, true], “like” : “your favorite language.”, “status”: { “apis” : true, “databases” : “document” }}

client.set(“mydocumentid”, myDocument);mySavedDocument = client.get(“mydocumentid”);

Page 13: CCB12 Getting Started with Couchbase App Development

13

Object to JSON back to Object

User Object

string uid

string firstname

string lastname

int age

array favorite_colors

string email

u::[email protected]{“uid”: 123456,“firstname”: “Michael”,“lastname”: “Nitschinger”,“age”: 24,“favorite_colors”: [“blue”, “black”],“email”: “michael.nitschinger@cou…”}

User Object

string uid

string firstname

string lastname

int age

array favorite_colors

string email

u::[email protected]{“uid”: 123456,“firstname”: “Michael”,“lastname”: “Nitschinger”,“age”: 24,“favorite_colors”: [“blue”, “black”],“email”: “michael.nitschinger@cou…”}

set()

get()

Page 14: CCB12 Getting Started with Couchbase App Development

1414

Couchbase Operations

Page 15: CCB12 Getting Started with Couchbase App Development

15

The Most Common Mental Adjustment

• In SQL we tend to want to avoid hitting the database as much as possible:–Costly, tying up connection pools and overloading db servers–Even with caching and indexing tricks, and massive

improvements over the years, SQL still gets bogged down by complex joins and huge indexes

• In Couchbase, get’s and set’s are so fast they are trivial, and not bottlenecks, this is hard for many people to accept at first

Page 16: CCB12 Getting Started with Couchbase App Development

16

Couchbase Basic Operations

• get (key)– Retrieve a document

• set (key, value)– Store a document, overwrites if exists

• add (key, value)– Store a document, error/exception if exists

• replace (key, value)– Store a document, error/exception if doesn’t exist

• cas (key, value, cas)– Compare and swap, mutate document only if it hasn’t changed

while executing this operation

Page 17: CCB12 Getting Started with Couchbase App Development

17

Couchbase Basic Operations (cont’d)

Atomic Counters are a special structure in Couchbase, they are executed in order and are Positive Integer Values•set (key, value)– Use set to initialize the counter• cb.set(“my_counter”, 1)

•incr (key)– Increase an atomic counter value, default by 1• cb.incr(“my_counter”) # now it’s 2

•decr (key)– Decrease an atomic counter value, default by 1• cb.decr(“my_counter”) # now it’s 1

Page 18: CCB12 Getting Started with Couchbase App Development

18

INCR / DECR

• Maintain a numerical counter• Good for shared counters with tons of increments• Example: game scores• Can INCR by any integer• Accessible as a JSON number in views

• We'll look at maintaining a leaderboard in the next session

Page 19: CCB12 Getting Started with Couchbase App Development

19

Simple Example in Ruby

# user.rbrequire “rubygems”require “couchbase”

class Userattr_accessor :name, :email, :title, :twitter

def initialize(attr = {}) attr.each do |name, value| setter = "#{name}=” next unless respond_to?(setter) send(setter, value) endend

def save client = Couchbase.bucket client.set(@email.downcase, self.to_json)endend

# example.rbrequire “./user.rb”

u1 = User.new({ :email => “michael.nitschinger@c…”,:name => “Michael Nitschinger”,:title => “Developer Advocate”,:twitter => “@daschl”

})

u1.save

Page 20: CCB12 Getting Started with Couchbase App Development

20

Add Retrieval

# user.rbrequire “rubygems”require “couchbase”

class Userattr_accessor :name, :email, :title, :twitter

def initialize(attr = {}) ... end

def save client = Couchbase.bucket client.set(@email.downcase, self.to_json)end

def self.find_by_email(email) client = Couchbase.bucket doc = client.get(email.downcase) return doc ? User.new(doc) : nilendend

# example.rbrequire “./user.rb”

u1 = User.new({ :email => “michael.nitschinger@c…”,:name => “Michael Nitschinger”,:title => “Developer Advocate”,:twitter => “@daschl”

})

u1.save

u1 = User.find_by_email(“michael.nitschinger@c…”)

if u1puts “User Found!”puts u1.inspectelseputs “User Not Registered!”end

Page 21: CCB12 Getting Started with Couchbase App Development

21

Add Instance Variables

# user.rbrequire “rubygems”require “couchbase”

class Userattr_accessor :name, :email, :title, :twitterattr_accessor :fb_id, :fb_token

def initialize(attr = {}) ... end

def save ... end

def self.find_by_email(email) client = Couchbase.bucket doc = client.get(email.downcase) return doc ? User.new(doc) : nilendend

# example.rbrequire “./user.rb”

u1 = User.find_by_email(“michael.nitschinger@c…”)

if u1u1.fb_id = “682829292”u1.fb_token = “f02jdjd020d8373730djd02”u1.saveelse# create userend

Page 22: CCB12 Getting Started with Couchbase App Development

22

Distributed System Design: Concurrency Controls

Actor 1 Actor 2

Couchbase Server

CAS mismatchSuccess

# actors.rb

c = Couchbase.bucketc.set(“mydoc”, { :myvalue => nil }

doc1, flags, cas = c.get(“mydoc”, :extended => true)

doc2, flags, cas = c.get(“mydoc”, :extended => true)

#c.set (“mydoc”, { “myvalue”: true }, :cas => cas)

# will fail because cas has changedc.set (“mydoc”, { “myvalue”: true }, :cas => cas)

Page 23: CCB12 Getting Started with Couchbase App Development

2323

Document Modeling

Page 24: CCB12 Getting Started with Couchbase App Development

2424

When considering how to model data for a given application:• Think of a logical container for the data• Think of how data groups together

Basic Document Modeling

Q • Are these separate object in the model layer? • Are these objects accessed together?

Page 25: CCB12 Getting Started with Couchbase App Development

2525

Document Design Options

• One document that contains all related data – Data is de-normalized– Better performance and scale– Eliminate client-side joins

• Separate documents for different object types with cross references – Data duplication is reduced– Objects may not be co-located – Transactions supported only on a document boundary– Most document databases do not support joins

Page 26: CCB12 Getting Started with Couchbase App Development

2626

Basic Document Design: Document ID / Key selection

• Similar to primary keys in relational databases• Documents are sharded based on the document ID• ID based document lookup is extremely fast • ID-Key’s can only appear once in a bucket, unique

Options• UUIDs, date-based IDs, numeric IDs • Hand-crafted (human readable) • Matching prefixes (for multiple related objects)

Q • Do you have a unique way of referencing objects?• Are related objects stored in separate documents?

Page 27: CCB12 Getting Started with Couchbase App Development

2727

• User profile•

• Blog posts– Contain the posts themselves

• Blog comments– Comments from other users• Option 1 - Keep it with Blog Document• Option 2 - Separate it Out

Example: Entities for a Blog

BLOG

Page 28: CCB12 Getting Started with Couchbase App Development

2828

Blog Document – Option 1 – Single document

{

“_id”: “daschl_Hello_World”,“author”: “daschl”, “type”: “post”“title”: “Hello World”,“format”: “markdown”, “body”: “Hello from [Couchbase](http://couchbase.com).”, “html”: “<p>Hello from <a href=\“http: …,

“comments”: [ [“format”: “markdown”, “body”:”Awesome post!”], [“format”: “plain”, “body”:”Like it.” ]]

}

Blog Post Object

string id

string author

string type

string title

string format

string body

string html

array comments

Page 29: CCB12 Getting Started with Couchbase App Development

2929

Blog Document – Option 2 - Split into Multiple Docs

{ “_id”: “daschl_Hello_World”,“author”: “daschl”, “type”: “post”“title”: “Hello World”,“format”: “markdown”, “body”: “Hello from [Couchbase](http://couchbase.com).”, “html”: “<p>Hello from <a href=\“http: …”,“num_comments”: 2}

Blog Post Object

string id

string author

string type

string title

string format

string body

string html

int num_comments

Comment Object

string format

string body

int id

{“_id”: “daschl_Hello_World_1”,“format”: “markdown”,“body”: “Awesome post!”}{“_id”: “daschl_Hello_World_2”,“format”: “plain”,“body”: “Love It!”}

Page 30: CCB12 Getting Started with Couchbase App Development

3030

• You can imagine how to take this to a threaded list

Threaded Comments

Blog

First comment

Reply to comment

More Comments

ListList ListList

Advantages

• Only fetch the data when you need it• For example, rendering part of a web page

• Spread the data and load across the entire cluster

Page 31: CCB12 Getting Started with Couchbase App Development

3131

Demo Time/Questions?