Data at the Speed of your Users Apache Cassandra and Spark for - - PowerPoint PPT Presentation

data at the speed of your users
SMART_READER_LITE
LIVE PREVIEW

Data at the Speed of your Users Apache Cassandra and Spark for - - PowerPoint PPT Presentation

Data at the Speed of your Users Apache Cassandra and Spark for simple, distributed, near real-time stream processing. GOTO Copenhagen 2014 Rustam Aliyev Solution Architect at . @rstml Big Data? Photo:


slide-1
SLIDE 1

Data at the Speed of your Users

Apache Cassandra and Spark for simple, distributed, near real-time stream processing.

GOTO Copenhagen 2014

slide-2
SLIDE 2

Rustam Aliyev

Solution Architect at .

  • @rstml
slide-3
SLIDE 3

Big Data?

Photo: Flickr / Watches En Masse
slide-4
SLIDE 4
  • Volume
  • Variety
  • Velocity
slide-5
SLIDE 5

Velocity = Near Real Time

slide-6
SLIDE 6

Near Real Time?

slide-7
SLIDE 7

0.5 sec ≤ ≤ 60 sec

Near Real Time

slide-8
SLIDE 8

Use Cases

Photo: Flickr / Swiss Army / Jim Pennucci
slide-9
SLIDE 9

Web Analytics Dynamic Pricing Recommendation Fraud Detection

slide-10
SLIDE 10

Architecture

Photo: Ilkin Kangarli / Baku Haydar Aliyev Center
slide-11
SLIDE 11

Architecture Goals

Low Latency High Availability Horizontal Scalability Simplicity

slide-12
SLIDE 12

Stream Processing

Collection Processing Storing Delivery

slide-13
SLIDE 13

Stream Processing

Collection

  • Spark

  • Cassandra

Delivery

slide-14
SLIDE 14

Cassandra

Distributed Database

Photo: Flickr / Hypostyle Hall / Jorge Láscar
slide-15
SLIDE 15

Data Model

slide-16
SLIDE 16

Partition

Cell 1 Cell 2 … Cell 3 Partition Key

slide-17
SLIDE 17

Partition

  • s:

Android storage: 32GB version: 4.4 weight: 130g

sort order on disk

Nexus 5

slide-18
SLIDE 18

Table

  • s:

Android storage: 32GB version: 4.4 weight: 130g Nexus 5

  • s:

iOS storage: 64GB version: 8.0 weight: 129g iPhone 6

  • s:

memory: version: weight: Other

slide-19
SLIDE 19

Distribution

slide-20
SLIDE 20

0000 8000 4000 C000 2000 6000 E000 A000 3D97 Nexus 5

slide-21
SLIDE 21

0000 8000 4000 C000 2000 6000 E000 A000 9C4F iPhone 6

3D97

slide-22
SLIDE 22

Replication

slide-23
SLIDE 23

0000 8000 4000 C000 2000 6000 E000 A000

3D97 9C4F

1 replica

slide-24
SLIDE 24

0000 8000 4000 C000 2000 6000 E000 A000

3D97 9C4F 9C4F 3D97

2 replicas

slide-25
SLIDE 25

Spark

Distributed Data Processing Engine

Photo: Flickr / Sparklers / Alexandra Compo / CreativeCommons
slide-26
SLIDE 26

Fast

In-memory

slide-27
SLIDE 27

Logistic Regression

Running Time (s) 1000 2000 3000 4000 Number of Iterations 1 5 10 20 30

Spark Hadoop

slide-28
SLIDE 28

Easy

slide-29
SLIDE 29

map

  • reduce
slide-30
SLIDE 30

map filter groupBy sort union join leftOuterJoin rightOuterJoin reduce count fold reduceByKey groupByKey cogroup cross zip sample take first partitionBy mapWith pipe save 
 ...

slide-31
SLIDE 31

RDD

Resilient Distributed Datasets

Node 1 Node 2 Node 3 Node 1 Node 2 Node 3

slide-32
SLIDE 32

Operator DAG

groupBy join filter map

Disk RDD Memory RDD

slide-33
SLIDE 33

Spark Streaming

Micro-batching

slide-34
SLIDE 34

RDD

DStream Data Stream

slide-35
SLIDE 35

Spark + Cassandra

DataStax Spark Cassandra Connector

slide-36
SLIDE 36

https://github.com/datastax/spark-cassandra-connector

slide-37
SLIDE 37

       

M M M

 Cassandra Spark Worker Spark Master & Worker

slide-38
SLIDE 38

Demo

  • Twitter Analytics
slide-39
SLIDE 39

Cassandra Data Model

slide-40
SLIDE 40

ALL: 7139 2014-09-21: 220 2014-09-20: 309 2014-09-19: 129

sort order

#hashtag

slide-41
SLIDE 41

CREATE ¡TABLE ¡hashtags ¡( ¡ ¡ ¡ ¡ ¡hashtag ¡text, ¡ ¡ ¡ ¡ ¡interval ¡text, ¡ ¡ ¡ ¡ ¡mentions ¡counter, ¡ ¡ ¡ ¡ ¡PRIMARY ¡KEY((hashtag), ¡interval) ¡ ) ¡WITH ¡CLUSTERING ¡ORDER ¡BY ¡(interval ¡DESC); ¡

slide-42
SLIDE 42

Processing Data Stream

slide-43
SLIDE 43

import ¡com.datastax.spark.connector.streaming._ ¡

  • val ¡sc ¡= ¡new ¡SparkConf() ¡

¡ ¡.setMaster("spark://127.0.0.1:7077") ¡ ¡ ¡.setAppName("Twitter-­‑Demo") ¡ ¡ ¡.setJars("demo-­‑assembly-­‑1.0.jar")) ¡ ¡ ¡.set("spark.cassandra.connection.host", ¡"127.0.0.1") ¡

  • val ¡ssc ¡= ¡new ¡StreamingContext(sc, ¡Seconds(2)) ¡
  • val ¡stream ¡= ¡TwitterUtils. ¡

¡ ¡createStream(ssc, ¡None, ¡Nil, ¡storageLevel ¡= ¡StorageLevel.MEMORY_ONLY_SER_2) ¡

  • val ¡hashTags ¡= ¡stream.flatMap(tweet ¡=> ¡

¡ ¡tweet.getText.toLowerCase.split(" ¡"). ¡ ¡ ¡filter(tags.contains(Seq("#iphone", ¡"#android")))) ¡

  • val ¡tagCounts ¡= ¡hashTags.map((_, ¡1)).reduceByKey(_ ¡+ ¡_) ¡
  • val ¡tagCountsAll ¡= ¡tagCounts.map{ ¡

¡ case ¡(tag, ¡mentions) ¡=> ¡(tag, ¡mentions, ¡"ALL") ¡ } ¡

  • tagCountsAll.saveToCassandra( ¡
slide-44
SLIDE 44

import ¡com.datastax.spark.connector.streaming._ ¡

  • val ¡sc ¡= ¡new ¡SparkConf() ¡

¡ ¡.setMaster("spark://127.0.0.1:7077") ¡ ¡ ¡.setAppName("Twitter-­‑Demo") ¡ ¡ ¡.setJars("demo-­‑assembly-­‑1.0.jar")) ¡ ¡ ¡.set("spark.cassandra.connection.host", ¡"127.0.0.1") ¡

  • val ¡ssc ¡= ¡new ¡StreamingContext(sc, ¡Seconds(2)) ¡
  • val ¡stream ¡= ¡TwitterUtils. ¡

¡ ¡createStream(ssc, ¡None, ¡Nil, ¡storageLevel ¡= ¡StorageLevel.MEMORY_ONLY_SER_2) ¡

  • val ¡hashTags ¡= ¡stream.flatMap(tweet ¡=> ¡

¡ ¡tweet.getText.toLowerCase.split(" ¡"). ¡ ¡ ¡filter(tags.contains(Seq("#iphone", ¡"#android")))) ¡

  • val ¡tagCounts ¡= ¡hashTags.map((_, ¡1)).reduceByKey(_ ¡+ ¡_) ¡
  • val ¡tagCountsAll ¡= ¡tagCounts.map{ ¡

¡ case ¡(tag, ¡mentions) ¡=> ¡(tag, ¡mentions, ¡"ALL") ¡ } ¡

  • tagCountsAll.saveToCassandra( ¡
slide-45
SLIDE 45

import ¡com.datastax.spark.connector.streaming._ ¡

  • val ¡sc ¡= ¡new ¡SparkConf() ¡

¡ ¡.setMaster("spark://127.0.0.1:7077") ¡ ¡ ¡.setAppName("Twitter-­‑Demo") ¡ ¡ ¡.setJars("demo-­‑assembly-­‑1.0.jar")) ¡ ¡ ¡.set("spark.cassandra.connection.host", ¡"127.0.0.1") ¡

  • val ¡ssc ¡= ¡new ¡StreamingContext(sc, ¡Seconds(2)) ¡
  • val ¡stream ¡= ¡TwitterUtils. ¡

¡ ¡createStream(ssc, ¡None, ¡Nil, ¡storageLevel ¡= ¡StorageLevel.MEMORY_ONLY_SER_2) ¡

  • val ¡hashTags ¡= ¡stream.flatMap(tweet ¡=> ¡

¡ ¡tweet.getText.toLowerCase.split(" ¡"). ¡ ¡ ¡filter(tags.contains(Seq("#iphone", ¡"#android")))) ¡

  • val ¡tagCounts ¡= ¡hashTags.map((_, ¡1)).reduceByKey(_ ¡+ ¡_) ¡
  • val ¡tagCountsAll ¡= ¡tagCounts.map{ ¡

¡ case ¡(tag, ¡mentions) ¡=> ¡(tag, ¡mentions, ¡"ALL") ¡ } ¡

  • tagCountsAll.saveToCassandra( ¡
slide-46
SLIDE 46
  • val ¡ssc ¡= ¡new ¡StreamingContext(sc, ¡Seconds(2)) ¡
  • val ¡stream ¡= ¡TwitterUtils. ¡

¡ ¡createStream(ssc, ¡None, ¡Nil, ¡storageLevel ¡= ¡StorageLevel.MEMORY_ONLY_SER_2) ¡

  • val ¡hashTags ¡= ¡stream.flatMap(tweet ¡=> ¡

¡ ¡tweet.getText.toLowerCase.split(" ¡"). ¡ ¡ ¡filter(tags.contains(Seq("#iphone", ¡"#android")))) ¡

  • val ¡tagCounts ¡= ¡hashTags.map((_, ¡1)).reduceByKey(_ ¡+ ¡_) ¡
  • val ¡tagCountsAll ¡= ¡tagCounts.map{ ¡

¡ case ¡(tag, ¡mentions) ¡=> ¡(tag, ¡mentions, ¡"ALL") ¡ } ¡

  • tagCountsAll.saveToCassandra( ¡

¡ "demo_ks", ¡"hashtags", ¡Seq("hashtag", ¡"mentions", ¡"interval")) ¡

  • ssc.start() ¡

ssc.awaitTermination() ¡

slide-47
SLIDE 47
  • val ¡ssc ¡= ¡new ¡StreamingContext(sc, ¡Seconds(2)) ¡
  • val ¡stream ¡= ¡TwitterUtils. ¡

¡ ¡createStream(ssc, ¡None, ¡Nil, ¡storageLevel ¡= ¡StorageLevel.MEMORY_ONLY_SER_2) ¡

  • val ¡hashTags ¡= ¡stream.flatMap(tweet ¡=> ¡

¡ ¡tweet.getText.toLowerCase.split(" ¡"). ¡ ¡ ¡filter(tags.contains(Seq("#iphone", ¡"#android")))) ¡

  • val ¡tagCounts ¡= ¡hashTags.map((_, ¡1)).reduceByKey(_ ¡+ ¡_) ¡
  • val ¡tagCountsByDay ¡= ¡tagCounts.map{ ¡

¡ case ¡(tag, ¡mentions) ¡=> ¡(tag, ¡mentions, ¡DateTime.now.toString("yyyyMMdd")) ¡ } ¡

  • tagCountsByDay.saveToCassandra( ¡

¡ "demo_ks", ¡"hashtags", ¡Seq("hashtag", ¡"mentions", ¡"interval")) ¡

  • ssc.start() ¡

ssc.awaitTermination() ¡

slide-48
SLIDE 48
  • val ¡ssc ¡= ¡new ¡StreamingContext(sc, ¡Seconds(2)) ¡
  • val ¡stream ¡= ¡TwitterUtils. ¡

¡ ¡createStream(ssc, ¡None, ¡Nil, ¡storageLevel ¡= ¡StorageLevel.MEMORY_ONLY_SER_2) ¡

  • val ¡hashTags ¡= ¡stream.flatMap(tweet ¡=> ¡

¡ ¡tweet.getText.toLowerCase.split(" ¡"). ¡ ¡ ¡filter(tags.contains(Seq("#iphone", ¡"#android")))) ¡

  • val ¡tagCounts ¡= ¡hashTags.map((_, ¡1)).reduceByKey(_ ¡+ ¡_) ¡
  • val ¡tagCountsAll ¡= ¡tagCounts.map{ ¡

¡ case ¡(tag, ¡mentions) ¡=> ¡(tag, ¡mentions, ¡"ALL") ¡ } ¡

  • tagCountsAll.saveToCassandra( ¡

¡ "demo_ks", ¡"hashtags", ¡Seq("hashtag", ¡"mentions", ¡"interval")) ¡

  • ssc.start() ¡

ssc.awaitTermination() ¡

slide-49
SLIDE 49

Questions ?