5 lessons learned in building streaming applications at microsoft bing scale

9
Top Five Lessons Learned in Building Streaming Applications at Microsoft Bing Scale Renyi Xiong Microsoft

Upload: shareddatamsft

Post on 18-Feb-2017

104 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: 5 lessons learned in building streaming applications at Microsoft Bing scale

Top Five Lessons Learned in Building Streaming Applications

at Microsoft Bing Scale

Renyi XiongMicrosoft

Page 2: 5 lessons learned in building streaming applications at Microsoft Bing scale

Bing Scale Problem – Log Merging

Edge3.2 GB/s

UI-Layout2.8 GB/s

Click69 MB/s

Kafka in

every DC

E E E E

U U U U

C C C C

MergedLog

Raw Logs Databus Event Merge Pipeline

10-minute App-Time Window10

Kafka

Databus1 2 3 4

• Merge Bing query events with click events• Lambda architecture: batch- and stream-processing shares the same C#

library• Spark Streaming in C#

Page 3: 5 lessons learned in building streaming applications at Microsoft Bing scale

Mobius Talk

• Tomorrow afternoon 3pm at Imperial• Mobius: C# Language Binding for Spark

Page 4: 5 lessons learned in building streaming applications at Microsoft Bing scale

Lesson 1: Use UpdateStateByKey to join DStreams• Problem

• Application time is not supported in Spark 1.6. • Solution – UpdateStateByKey

• UpdateStateByKey takes a custom JoinFunction as input parameter;• Custom JoinFunction enforces time window based on Application Time;• UpdateStateByKey maintains partially joined events as the state

Edge DStreamClick DStream

Batch job 1RDD @ time 1

Batch job 2RDD @ time 2

State DStream

UpdateStateByKey

Batch job 3RDD @ time 3

Pseudo CodeIterator[(K, S)] JoinFunction( int pid, Iterator[(K:key, Iterator[V]:newEvents, S:oldState)] events){

val currentTime = events.newEvents.max(e => e.eventTime);

foreach (var e in events) { val newState = <oldState join newEvents> if (oldState.min(s => s.eventTime) + TimeWindow < currentTime) // TimeWindow 10minutes <output to external storage> else return (key, newState) }}

UpdateStateByKey C# APIPairDStreamFunctions.cs, https://github.com/Microsoft/Mobius

Page 5: 5 lessons learned in building streaming applications at Microsoft Bing scale

Lesson 2: Dynamic Repartition with Kafka Direct Approach

• Problem• Unbalanced Kafka partitions caused delay in the pipeline

• Solution – Dynamic Repartition1. Repartition data from one Kafka partition into multiple RDDs without extra shuffling

cost of DStream.Repartition2. Repartition threshold is configurable per topic

After Dynamic Repartition

Pseudo Codeclass DynamicPartitionKafkaRDD(kafkaPartitionOffsetRanges) override def getPartitions { // repartition threshold per topic loaded from config val maxRddPartitionSize = Map<topic, partitionSize>

// apply max repartition threshold kafkaPartitionOffsetRanges.flatMap { case o => val rddPartitionSize = maxRddPartitionSize(o.topic) (o.fromOffset until o.untilOffset by rddPartitionSize).map( s => (o.topic, o.partition, s, (o.untilOffset, s + rddPartitionSize))) } }

Source CodeDynamicPartitionKafkaRDD.scala - https://github.com/Microsoft/Mobius

2-minute interval Before Dynamic Repartition

Page 6: 5 lessons learned in building streaming applications at Microsoft Bing scale

Lesson 3: On-time Kafka fetch job submission• Problem

• Overall job delay accumulates due to transient slow/hot Kafka broker issue.

• Solution• Submit Kafka Fetch job on batch interval in a separate thread,

even when previous batch delayed.

Job#A2 UpdateStateByKey

Job#A1 Fetch data

Batch-A

New Thread

Job#A3 Checkpoint

Job#B2 UpdateStateByKey

Job#B1 Fetch data

Batch-B

Job#B3 Checkpoint

Job#C2 UpdateStateByKey

Job#C1 Fetch data

Batch-C

Job#C3checkpoint

Main Thread

Submit Job

Pseudo Codeclass CSharpStateDStream override def compute { val lastState = getOrCompute (validTime - batchInterval)

val rdd = parent.getOrCompute(validTime) if (!lastBatchCompleted) { // if last batch not complete yet // run Fetch data job to materialize rdd in a separate thread rdd.cache() ThreadPool.execute(sc.runJob(rdd)) // wait for job to complele }

<compute UpdateStateByKey Dstream> }

Source CodeCSharpDStream.scala - https://github.com/Microsoft/Mobius

Driver perspective

Page 7: 5 lessons learned in building streaming applications at Microsoft Bing scale

Lesson 4: Parallel Kafka metadata refresh• Problem

• Fetching Kafka metadata from multiple data centers often takes more time than expected.

• Solution• Customize DirectKafkaInputDStream, move metadata refresh for each {topic, data-center} to a

separate thread

Kafkaoffset range 1

t3

Main Thread

t2

New Thread

t1

Kafkaoffset range 2

Kafkaoffset range 3

batch 1 batch 2 batch 3Batch Job Submission

Kafka Metadata refresh

Pseudo Codeclass DynamicPartitionKafkaInputDStream {

// starts a separate schedule thread at refreshOffsetsInterval refreshOffsetsScheduler.scheduleAtFixedRate( <get offset ranges> <enqueue offset ranges> )

override def compute { <dequeue offset ranges nonblockingly> <generate kafka RDD> }}Source CodeDynamicPartitionKafkaInputDStream.scala - https://github.com/Microsoft/Mobius

Driver perspective

Page 8: 5 lessons learned in building streaming applications at Microsoft Bing scale

Lesson 5: Parallel Kafka metadata refresh + RDD materialization

• Problem• Kafka data fetch and data processing not in parallel

• Solution• Take Lesson 4 further• In metadata refresh thread, materialize and cache

Kafka RDD

Kafkaoffset range 1

RDD.Cache

t3

Main Thread

t2

New Thread

t1

Kafkaoffset range 2

RDD.Cache

Kafkaoffset range 3

RDD.Cache

batch 1 batch 2 batch 3Batch Job Submission

Kafka Metadata refresh

Driver perspective Pseudo Codeclass DynamicPartitionKafkaInputDStream

// starts a separate schedule thread at refreshOffsetsInterval refreshOffsetsScheduler.scheduleAtFixedRate( <get offset ranges> <generate kafka RDD> // materialize and cache sc.runJob(kafkaRdd.cache) <enqueue kafka RDD> )

override def compute { <dequeue kafka RDD nonblockingly> }

Source CodeDynamicPartitionKafkaInputDStream.scala - https://github.com/Microsoft/Mobius

Page 9: 5 lessons learned in building streaming applications at Microsoft Bing scale

THANK YOU.• Special thanks to TD and Ram from Databricks for all the support• Contact us

• Renyi Xiong, [email protected]• Kaarthik Sivashanmugam, [email protected][email protected]