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: Flickr / Watches En Masse
� � � Volume Variety Velocity
Velocity = Near Real Time
Near Real Time?
Near Real Time 0.5 sec ≤ ≤ 60 sec
Use Cases Photo: Flickr / Swiss Army / Jim Pennucci
Web Analytics Dynamic Pricing Recommendation Fraud Detection
Architecture Photo: Ilkin Kangarli / Baku Haydar Aliyev Center
Architecture Goals Low Latency High Availability Horizontal Scalability Simplicity
Stream Processing � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � Collection Processing Storing Delivery
Stream Processing � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � Collection Delivery � � Spark Cassandra
Cassandra Distributed Database Photo: Flickr / Hypostyle Hall / Jorge Láscar
Data Model
Partition Cell 1 Cell 2 Cell 3 … Partition Key
Partition os: storage: version: weight: Nexus 5 Android 32GB 4.4 130g sort order on disk
Table os: storage: version: weight: Nexus 5 Android 32GB 4.4 130g os: storage: version: weight: iPhone 6 iOS 64GB 8.0 129g os: memory: version: weight: Other
Distribution
0000 Nexus 5 3D97 2000 E000 C000 4000 6000 A000 8000
0000 iPhone 6 9C4F 2000 E000 C000 4000 3D97 6000 A000 8000
Replication
1 replica 0000 2000 E000 C000 4000 3D97 6000 A000 9C4F 8000
2 replicas 0000 2000 E000 C000 4000 3D97 9C4F 6000 A000 3D97 9C4F 8000
Spark Distributed Data Processing Engine Photo: Flickr / Sparklers / Alexandra Compo / CreativeCommons
Fast In-memory
Logistic Regression 4000 3000 Running Time (s) Spark 2000 Hadoop 1000 1 5 10 20 30 Number of Iterations
Easy
map reduce �
map reduce sample filter count take groupBy fold first sort reduceByKey partitionBy union groupByKey mapWith join cogroup pipe leftOuterJoin cross save rightOuterJoin zip ...
RDD Resilient Distributed Datasets Node 2 Node 1 Node 3 Node 2 Node 1 Node 3
Operator DAG groupBy join map filter Disk RDD Memory RDD
Spark Streaming Micro-batching
RDD Data Stream DStream
Spark + Cassandra DataStax Spark Cassandra Connector
https://github.com/datastax/spark-cassandra-connector
M Cassandra Spark Worker M Spark Master & Worker M
Demo � � Twitter Analytics
Cassandra Data Model
ALL: 2014-09-21: 2014-09-20: 2014-09-19: #hashtag 7139 220 309 129 sort order
CREATE ¡TABLE ¡hashtags ¡( ¡ ¡ ¡ ¡ ¡hashtag ¡text, ¡ ¡ ¡ ¡ ¡interval ¡text, ¡ ¡ ¡ ¡ ¡mentions ¡counter, ¡ ¡ ¡ ¡ ¡PRIMARY ¡KEY((hashtag), ¡interval) ¡ ) ¡WITH ¡CLUSTERING ¡ORDER ¡BY ¡(interval ¡DESC); ¡
Processing Data Stream
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( ¡
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( ¡
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( ¡
� 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() ¡
� 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() ¡
Recommend
More recommend