advanced cassandra

54
©2013 DataStax Confidential. Do not distribute without consent. @PatrickMcFadin Patrick McFadin Chief Evangelist, DataStax Advanced Cassandra 1

Upload: datastax-academy

Post on 20-Feb-2017

384 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: Advanced Cassandra

©2013 DataStax Confidential. Do not distribute without consent.

@PatrickMcFadin

Patrick McFadinChief Evangelist, DataStax

Advanced Cassandra

1

Page 2: Advanced Cassandra

Does Apache Cassandra Work?

Page 3: Advanced Cassandra
Page 4: Advanced Cassandra

Motivations

Page 5: Advanced Cassandra
Page 6: Advanced Cassandra

Cassandra is not…

6

A Data Ocean or Pond., Lake

An In-Memory Database

A Key-Value Store

A magical database unicorn that farts rainbows

Page 7: Advanced Cassandra

7

When to use…

Loose data model (joins, sub-selects) Absolute consistency (aka gotta have ACID) No need to use anything else You’ll miss the long, candle lit dinners with your Oracle rep that always end with “what’s your budget look like this year?”

Oracle, MySQL, Postgres or <RDBMS>

Page 8: Advanced Cassandra

Uptime is a top priority Unpredictable or high scaling requirements Workload is transactional Willing to put the time or effort into understanding how Cassandra works and how to use it.

8

When to use…

Use Oracle when you want to count your money. Use Cassandra when you want to make money.

Cassandra

Page 9: Advanced Cassandra

Copy n Paste your relational model

APACHE

CASSANDRA

Page 10: Advanced Cassandra
Page 11: Advanced Cassandra

1000 Node Cluster

Scaling up

Page 12: Advanced Cassandra

Stick the landing

12

Going to deploy in production!

Not sure about this!

Done!

Page 13: Advanced Cassandra

Topology considerations

Replication Strategy

CREATE KEYSPACE killrvideo WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : 3 };

StrategyCopies

Page 14: Advanced Cassandra

Topology considerations

• Default • One data center

SimpleStrategy

NetworkTopologyStrategy

• Use for multi-data center • Just use this always

Page 15: Advanced Cassandra

NetworkTopologyStrategy

CREATE KEYSPACE Product_Catalog WITH REPLICATION = { 'class' : 'NetworkTopologyStrategy', 'replication_factor' : 3 };

CREATE KEYSPACE EU_Customer_Data WITH REPLICATION = { 'class' : 'NetworkTopologyStrategy', 'eu1' : 3 ‘eu2’ : 3 ‘us1’ : 0 };

Symmetric

Asymmetric

No copies in the US

Page 16: Advanced Cassandra

Application• Closer to customers • No downtime

Product_Catalog RF=3Product_Catalog RF=3 EU_Customer_Data RF=3

EU_Customer_Data RF=0

Product_Catalog RF=3EU_Customer_Data RF=3

Page 17: Advanced Cassandra

Snitches

Page 18: Advanced Cassandra

SnitchesDC1

DC1: RF=3

Node Primary Replica Replica

10.0.0.1 00-25 76-100 51-75

10.0.0.2 26-50 00-25 76-100

10.0.0.3 51-75 26-50 00-25

10.0.0.4 76-100 51-75 26-50

10.0.0.1 00-25

10.0.0.4 76-100

10.0.0.2 26-50

10.0.0.3 51-75

76-100 51-75

00-25 76-100

26-50 00-25

51-75 26-50

Client

Where do I place this data?

?

Dynamic SnitchingRoute based on node performance

Page 19: Advanced Cassandra

Snitches

SimpleSnitch

GossipingPropertyFileSnitch

RackInferringSnitch

PropertyFileSnitch

EC2Snitch

GoogleCloudSnitchCloudStackSnitch

EC2MultiRegionSnitch

Page 20: Advanced Cassandra

Snitches

• Most typically used in production • Absolute placement

GossipingPropertyFileSnitch

cassandra-rackdc.properties

dc=DC1 rack=RAC1

Page 21: Advanced Cassandra

Booting a datacenterDC1

DC1: RF=3Node Primary Replica Replica

10.0.0.1 00-25 76-100 51-75

10.0.0.2 26-50 00-25 76-100

10.0.0.3 51-75 26-50 00-25

10.0.0.4 76-100 51-75 26-50

10.0.0.1 00-25

10.0.0.4 76-100

10.0.0.2 26-50

10.0.0.3 51-75

76-100 51-75

00-25 76-100

26-50 00-25

51-75 26-50

DC2

Pre-check

• Use NetworkTopologyStrategy • In cassandra.yaml

• auto_bootstrap: false

• add seeds from other DC • Set node location for Snitch

• GossipingPropertyFileSnitch: cassandra-rackdc.properties

• PropertyFileSnitch: cassandra-topology.properties

Page 22: Advanced Cassandra

Booting a datacenterDC1

DC1: RF=3Node Primary Replica Replica

10.0.0.1 00-25 76-100 51-75

10.0.0.2 26-50 00-25 76-100

10.0.0.3 51-75 26-50 00-25

10.0.0.4 76-100 51-75 26-50

10.0.0.1 00-25

10.0.0.4 76-100

10.0.0.2 26-50

10.0.0.3 51-75

76-100 51-75

00-25 76-100

26-50 00-25

51-75 26-50

DC2

10.1.0.1 00-25

10.1.0.4 76-100

10.1.0.2 26-50

10.1.0.3 51-75

76-100 51-75

00-25 76-100

26-50 00-25

51-75 26-50

Node Primary Replica Replica

10.0.0.1 00-25 76-100 51-75

10.0.0.2 26-50 00-25 76-100

10.0.0.3 51-75 26-50 00-25

10.0.0.4 76-100 51-75 26-50

DC2: RF=3

ALTER KEYSPACE

Page 23: Advanced Cassandra

Booting a datacenterDC1

DC1: RF=3Node Primary Replica Replica

10.0.0.1 00-25 76-100 51-75

10.0.0.2 26-50 00-25 76-100

10.0.0.3 51-75 26-50 00-25

10.0.0.4 76-100 51-75 26-50

10.0.0.1 00-25

10.0.0.4 76-100

10.0.0.2 26-50

10.0.0.3 51-75

76-100 51-75

00-25 76-100

26-50 00-25

51-75 26-50

DC2

10.1.0.1 00-25

10.1.0.4 76-100

10.1.0.2 26-50

10.1.0.3 51-75

76-100 51-75

00-25 76-100

26-50 00-25

51-75 26-50

Node Primary Replica Replica

10.0.0.1 00-25 76-100 51-75

10.0.0.2 26-50 00-25 76-100

10.0.0.3 51-75 26-50 00-25

10.0.0.4 76-100 51-75 26-50

DC2: RF=3

nodetool rebuild

Page 24: Advanced Cassandra

Security

Page 25: Advanced Cassandra

NoSQL == No Security

Page 26: Advanced Cassandra

User Auth

Step 1 Turn it on

cassandra.yaml

authorizer:PasswordAuthorizerAllowAllAuthorizer

authenticator:AllowAllAuthenticatorPasswordAuthenticator

Page 27: Advanced Cassandra

User Auth

cqlsh -u cassandra -p cassandra

Step 2 Create users

cqlsh> create user dude with password 'manager' superuser;

cqlsh> create user worker with password 'newhire';

cqlsh> list users; name | super ----------+------- cassandra | True worker | False dude | True

Page 28: Advanced Cassandra

User Auth

cqlsh -u cassandra -p cassandra

Step 3 Grant permissions

cqlsh> create user ro_user with password '1234567';

cqlsh> grant all on killrvideo.user to dude;

cqlsh> grant select on killrvideo.user to ro_user;

Page 29: Advanced Cassandra

SSL

http://thelastpickle.com/blog/2015/09/30/hardening-cassandra-step-by-step-part-1-server-to-server.html

10.0.0.1

10.0.0.4 10.0.0.2

10.0.0.3

• Create SSL certificates • Copy to each server • Start each node

Page 30: Advanced Cassandra

Prepared Statements• Built for speed an efficiency

Page 31: Advanced Cassandra

How they work: Prepare

SELECT * FROM user WHERE id = ?

10.0.0.1 00-25

10.0.0.4 76-100

10.0.0.2 26-50

10.0.0.3 51-75

Client

Prepare

Parsed

Hashed Cached

Prepared Statement

Page 32: Advanced Cassandra

How they work: Bind

id = 1 + PreparedStatement Hash

10.0.0.1 00-25

10.0.0.4 76-100

10.0.0.2 26-50

10.0.0.3 51-75

Client

Bind & Execute

Combine Pre-parsed Query and Variable

Execute

Page 33: Advanced Cassandra

Result?

Page 34: Advanced Cassandra

How to Prepare(Statements)

PreparedStatement userSelect = session.prepare(“SELECT * FROM user WHERE id = ?”);BoundStatement userSelectStatement = new BoundStatement(userSelect);

session.execute(userSelectStatement.bind(1));

prepared_stmt = session.prepare (“SELECT * FROM user WHERE id = ?”)bound_stmt = prepared_stmt.bind([1])

session.execute(bound_stmt)

Java

Python

Page 35: Advanced Cassandra

Don’t do this

for (int i = 1; i < 100; i++) { PreparedStatement userSelect = session.prepare(“SELECT * FROM user WHERE id = ?”); BoundStatement userSelectStatement = new BoundStatement(userSelect);

session.execute(userSelectStatement.bind(1));}

Page 36: Advanced Cassandra

Execute vs Execute Async• Very subtle difference • Blocking vs non-blocking call

VS

Page 37: Advanced Cassandra

Async• Request pipelining • One connection for requests • Responses return whenever

Page 38: Advanced Cassandra

Async

for (…) {future = executeAsync(statement)

}

10.0.0.1 00-25

10.0.0.4 76-100

10.0.0.2 26-50

10.0.0.3 51-75

Client

Do something

for (…) {result = future.get

}Block

Page 39: Advanced Cassandra

Batch vs Execute Async

VS

(Potentially)

Page 40: Advanced Cassandra

Load Balancing Policies

cluster = Cluster .builder() .addContactPoint("192.168.0.30") .withQueryOptions(new QueryOptions().setConsistencyLevel(ConsistencyLevel.ONE) .withRetryPolicy(DefaultRetryPolicy.INSTANCE) .withLoadBalancingPolicy(new TokenAwarePolicy(new DCAwareRoundRobinPolicy())) .build(); session = cluster.connect("demo");

Page 41: Advanced Cassandra

Data LocalityDC1

DC1: RF=3Node Primary Replica Replica

10.0.0.1 00-25 76-100 51-75

10.0.0.2 26-50 00-25 76-100

10.0.0.3 51-75 26-50 00-25

10.0.0.4 76-100 51-75 26-50

10.0.0.1 00-25

10.0.0.4 76-100

10.0.0.2 26-50

10.0.0.3 51-75

76-100 51-75

00-25 76-100

26-50 00-25

51-75 26-50

Client

Read partition 15

DC2

10.1.0.1 00-25

10.1.0.4 76-100

10.1.0.2 26-50

10.1.0.3 51-75

76-100 51-75

00-25 76-100

26-50 00-25

51-75 26-50

Node Primary Replica Replica

10.0.0.1 00-25 76-100 51-75

10.0.0.2 26-50 00-25 76-100

10.0.0.3 51-75 26-50 00-25

10.0.0.4 76-100 51-75 26-50

DC2: RF=3

Client

Read partition 15

Page 42: Advanced Cassandra

Batch (Logged)• All statements collected on client • Sent in one shot • All done on 1 node

Batch is accepted

All actions are logged on two replicas

Statements executed in sequence

Results are collected and returned

Page 43: Advanced Cassandra

Batches: The good• Great for denormalized inserts/updates

// Looking from the video side to many usersCREATE TABLE comments_by_video ( videoid uuid, commentid timeuuid, userid uuid, comment text, PRIMARY KEY (videoid, commentid)) WITH CLUSTERING ORDER BY (commentid DESC);

// looking from the user side to many videosCREATE TABLE comments_by_user ( userid uuid, commentid timeuuid, videoid uuid, comment text, PRIMARY KEY (userid, commentid)) WITH CLUSTERING ORDER BY (commentid DESC);

Page 44: Advanced Cassandra

Batches: The good• Both inserts are run • On failure, the batch log will replay

BEGIN BATCH INSERT INTO comments_by_video (videoid, userid, commentid, comment) VALUES (99051fe9-6a9c-46c2-b949-38ef78858dd0,d0f60aa8-54a9-4840-b70c-fe562b68842b,now(), 'Worst. Video. Ever.') INSERT INTO comments_by_video (videoid, userid, commentid, comment) VALUES (99051fe9-6a9c-46c2-b949-38ef78858dd0,d0f60aa8-54a9-4840-b70c-fe562b68842b,now(), 'Worst. Video. Ever.')APPLY BATCH;

Page 45: Advanced Cassandra

Batches: The bad“I was doing a load test and nodes started blinking offline”

“Were you using a batch by any chance?”

“Why yes I was! How did you know?”

“How big was each batch?”

“1000 inserts each”

Page 46: Advanced Cassandra

Batches: The bad

BEGIN BATCH 1000 insertsAPPLY BATCH;

10.0.0.1 00-25

10.0.0.4 76-100

10.0.0.2 26-50

10.0.0.3 51-75

Client

Page 47: Advanced Cassandra

Batches: The rules• Keep them small and for atomicity

CASSANDRA-6487 - Warn on large batches (5Kb default)

CASSANDRA-8011 - Fail on large batches (50Kb default)

Page 48: Advanced Cassandra

The alternative

BEGIN BATCH 1000 insertsAPPLY BATCH;

while() { future = session.executeAsync(statement)}

Instead of:

Do this:

Page 49: Advanced Cassandra

Old Row cache: The problem• Reads an entire storage row of data

ID = 1Partition Key

(Storage Row Key)

2014-09-08 12:00:00 : name

SFO

2014-09-08 12:00:00 : temp

63.4

2014-09-08 12:01:00 : name

SFO

2014-09-08 12:00:00 : temp

63.9

2014-09-08 12:02:00 : name

SFO

2014-09-08 12:00:00 : temp

64.0

Need this

Caches this

Page 50: Advanced Cassandra

New Row Cache: The solution• Stores just a few CQL rows

ID = 1Partition Key

(Storage Row Key)

2014-09-08 12:00:00 : name

SFO

2014-09-08 12:00:00 : temp

63.4

2014-09-08 12:01:00 : name

SFO

2014-09-08 12:00:00 : temp

63.9

2014-09-08 12:02:00 : name

SFO

2014-09-08 12:00:00 : temp

64.0

Need this

Caches this

Page 51: Advanced Cassandra

Using row cache

CREATE TABLE user_search_history_with_cache ( id int, search_time timestamp, search_text text, search_results int, PRIMARY KEY (id, search_time)) WITH CLUSTERING ORDER BY (search_time DESC)AND caching = { 'keys' : 'ALL', 'rows_per_partition' : '20' };

Page 52: Advanced Cassandra

Perf increase

95th ms

Requests

Page 53: Advanced Cassandra

Go make something awesome

Page 54: Advanced Cassandra

Thank you!

Bring the questions

Follow me on twitter @PatrickMcFadin