42
Cassandra Explained Berlin Buzzwords June 6, 2010 Eric Evans [email protected] @jericevans http://blog.sym-link.com

Cassandra Explained

Embed Size (px)

DESCRIPTION

Disruptive Code; September 22, 2010; Stockholm Sweden.

Citation preview

Page 1: Cassandra Explained

Cassandra Explained

Berlin BuzzwordsJune 6, 2010

Eric [email protected]

@jericevanshttp://blog.sym-link.com

Page 2: Cassandra Explained

Outline

● Background● Description● API● Examples

Page 3: Cassandra Explained

Background

Page 4: Cassandra Explained

Influential Papers

● BigTable● Strong consistency● Sparse map data model● GFS, Chubby, et al

● Dynamo● O(1) distributed hash table (DHT)● BASE (aka eventual consistency)● Client tunable consistency/availability

Page 5: Cassandra Explained

NoSQL

● HBase● MongoDB● Riak● Voldemort● Neo4J● Cassandra

● Hypertable● HyperGraphDB● Memcached● Tokyo Cabinet● Redis● CouchDB

Page 6: Cassandra Explained

NoSQL Big data

● HBase● MongoDB● Riak● Voldemort● Neo4J● Cassandra

● Hypertable● HyperGraphDB● Memcached● Tokyo Cabinet● Redis● CouchDB

Page 7: Cassandra Explained

Bigtable / Dynamo

Bigtable● HBase● Hypertable

Dynamo● Riak● Voldemort

Cassandra ??

Page 8: Cassandra Explained

Dynamo-Bigtable Lovechild

Page 9: Cassandra Explained

CAP Theorem “Pick Two”

● CP● Bigtable● Hypertable● HBase

● AP● Dynamo● Voldemort● Cassandra

Page 10: Cassandra Explained

CAP Theorem “Pick Two”

● Consistency● Availability● Partition Tolerance

Page 11: Cassandra Explained

Description

Page 12: Cassandra Explained

Properties

● Symmetric● No single point of failure● Linearly scalable● Ease of administration

● Flexible partitioning, replica placement● Automated provisioning● High availability (eventual consistency)

Page 13: Cassandra Explained

P2P Routing

Page 14: Cassandra Explained

P2P Routing

Page 15: Cassandra Explained

Partitioning

● Random● 128bit namespace, (MD5)● Good distribution

● Order Preserving● Tokens determine namespace● Natural order (lexicographical)● Range / cover queries

● Yours ??

Page 16: Cassandra Explained

Replica Placement

● SimpleSnitch● Default● N-1 successive nodes

● RackInferringSnitch● Infers DC/rack from IP

● PropertyFileSnitch● Configured w/ a properties file

Page 17: Cassandra Explained

Bootstrap

Page 18: Cassandra Explained

Bootstrap

Page 19: Cassandra Explained

Bootstrap

Page 20: Cassandra Explained

Choosing Consistency

Read

Level Description

ZERO N/A

ANY N/A

ONE 1 replica

QUORUM (N / 2) +1

ALL All replicas

Write

Level Description

ZERO Hail Mary

ANY 1 replica (HH)

ONE 1 replica

QUORUM (N / 2) +1

ALL All replicas

R + W > N

Page 21: Cassandra Explained

Quorum ((N/2) + 1)

Page 22: Cassandra Explained

Quorum ((N/2) + 1)

Page 23: Cassandra Explained

Data Model

Page 24: Cassandra Explained

Overview

● Keyspace● Uppermost namespace● Typically one per application

● ColumnFamily● Associates records of a similar kind● Record-level Atomicity● Indexed

● Column● Basic unit of storage

Page 25: Cassandra Explained

Sparse Table

Page 26: Cassandra Explained

Column

● name● byte[]

● Queried against (predicates)● Determines sort order

● value● byte[]

● Opaque to Cassandra

● timestamp● long

● Conflict resolution (Last Write Wins)

Page 27: Cassandra Explained

Column Comparators

● Bytes● UTF8● TimeUUID● Long● LexicalUUID● Composite (third-party)

http://github.com/edanuff/CassandraCompositeType

Page 28: Cassandra Explained

API

Page 29: Cassandra Explained

Low / High

● Thrift● Compact binary RPC framework● 12 different languages

● Idiomatic● Hector (Java)● Pycassa (Python)● Others...

http://wiki.apache.org/cassandra/ClientOptions

Page 30: Cassandra Explained

Thrift Read Methods

● get() → Column● get_slice() → list<Column>● mulitget_slice() → map<key, list<Column>>● get_count() → int● multiget_count() → map<key, int>● get_range_slices()

Page 31: Cassandra Explained

Thrift Write Methods

● insert()● batch_insert()● remove()● batch_mutate()

Page 32: Cassandra Explained

Examples

Page 33: Cassandra Explained

Pycassa – Python Client API

● connect() → Thrift proxy● cf = ColumnFamily(proxy, ksp, cfname)● cf.insert() → long● cf.get() → dict● cf.get_range() → dict

http://github.com/vomjom/pycassa

Page 34: Cassandra Explained

Address Book – Setup

<!-- conf/storage-conf.xml --><Keyspace Name=”AddressBook”> <ColumnFamily Name=”Addresses” CompareWith=”BytesType” RowsCached=”10000” KeysCached=”50%” Comment=”Too lame” /></Keyspace>

Page 35: Cassandra Explained

Adding an entry

key = uuid()

columns = { 'first': 'Eric', 'last': 'Evans', 'email': '[email protected]', 'city': 'Austin', 'zip': 78250}

addresses.insert(key, columns)

Page 36: Cassandra Explained

Fetching a record

# fetching the record by keyrecord = addresses.get(key)

# accessing columns by namezipcode = record['zip']city = record['city']

Page 37: Cassandra Explained

Indexing

<!-- conf/storage-conf.xml --><Keyspace Name=”AddressBook”> <ColumnFamily Name=”Addresses” CompareWith=”BytesType” RowsCached=”10000” KeysCached=”50%” Comment=”Too lame” /> <ColumnFamily Name=”ByCity” CompareWith=”UTF8Type” /></Keyspace>

Page 38: Cassandra Explained

Updating the index

key = uuid()

columns = { 'first': 'Eric', 'last': 'Evans', 'email': '[email protected]', 'city': 'Austin', 'zip': 78250}

addresses.insert(key, columns)byCity.insert('Austin', {key: ''})

Page 39: Cassandra Explained

Timeseries

<!-- conf/storage-conf.xml --><Keyspace Name=”Sites”> <ColumnFamily Name=”Stats” CompareWith=”LongType”/></Keyspace>

Page 40: Cassandra Explained

Logging values

# time as a long, binary, network-orderts = pack('>d', long(time() * 1e6))

stats.insert('org.apache', {ts: value})

Page 41: Cassandra Explained

Slicing

begin = pack('>d', long(s * 1e6))

stats.get_range('org.apache', column_start=begin)

end = pack('>d', long((s + 86400) * 1e6))

stats.get_range(start='org.apache', finish='org.debian', column_start=begin, column_finish=end)

Page 42: Cassandra Explained

Questions?