13.07.2015 Views

Real-time Engineering at Uber and the Evolution of an Event-Driven Architecture Presentation

Real-time Engineering at Uber and the Evolution of an Event-Driven Architecture Presentation

Real-time Engineering at Uber and the Evolution of an Event-Driven Architecture Presentation

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>Real</strong>-<strong>time</strong><strong>Engineering</strong><strong>at</strong> <strong>Uber</strong>wolski@uber.com


Lords <strong>of</strong> <strong>the</strong> Trip<strong>Real</strong>-<strong>time</strong> <strong>Engineering</strong>


An<strong>at</strong>omy <strong>of</strong> a TripLooking for a ride


An<strong>at</strong>omy <strong>of</strong> a TripRequesting a ride


An<strong>at</strong>omy <strong>of</strong> a TripDisp<strong>at</strong>ching a driver


An<strong>at</strong>omy <strong>of</strong> a TripPicking you up


Service-Orient<strong>at</strong>ionGeosp<strong>at</strong>ial Proxy, Car Loc<strong>at</strong>or, Pricing, ETAs,R<strong>an</strong>king, Dynamic Configur<strong>at</strong>ion, Map-M<strong>at</strong>ching,Reverse Geocoding, User Caching, ...


User Cache… for fault toler<strong>an</strong>ce


End-User<strong>Real</strong>-<strong>time</strong>ServicesUser CacheUser ServicePOST /tripsHappy P<strong>at</strong>h


End-User<strong>Real</strong>-<strong>time</strong>ServicesUser CacheUser ServicePOST /tripsGET /users/123Happy P<strong>at</strong>h


End-User<strong>Real</strong>-<strong>time</strong>ServicesUser CacheUser ServicePOST /tripsGET /users/123GET /users/123Happy P<strong>at</strong>h


End-User<strong>Real</strong>-<strong>time</strong>ServicesUser CacheUser ServicePOST /tripsGET /users/123GET /users/123Happy P<strong>at</strong>h


End-User<strong>Real</strong>-<strong>time</strong>ServicesUser CacheUser ServicePOST /tripsGET /users/123GET /users/123HMSET users:123StoreHappy P<strong>at</strong>h


End-User<strong>Real</strong>-<strong>time</strong>ServicesUser CacheUser ServicePOST /tripsGET /users/123GET /users/123HMSET users:123StoreHappy P<strong>at</strong>h


End-User<strong>Real</strong>-<strong>time</strong>ServicesUser CacheUser ServicePOST /tripsSad P<strong>at</strong>h


End-User<strong>Real</strong>-<strong>time</strong>ServicesUser CacheUser ServicePOST /tripsGET /users/123Sad P<strong>at</strong>h


End-User<strong>Real</strong>-<strong>time</strong>ServicesUser CacheUser ServicePOST /tripsGET /users/123GET /users/123Sad P<strong>at</strong>h


End-User<strong>Real</strong>-<strong>time</strong>ServicesUser CacheUser ServicePOST /tripsGET /users/123GET /users/123Sad P<strong>at</strong>h


End-User<strong>Real</strong>-<strong>time</strong>ServicesUser CacheUser ServicePOST /tripsGET /users/123GET /users/123HMGET users:123StoreSad P<strong>at</strong>h


End-User<strong>Real</strong>-<strong>time</strong>ServicesUser CacheUser ServicePOST /tripsGET /users/123GET /users/123HMGET users:123StoreSad P<strong>at</strong>h


Cache-Served Requests


AirlockVarnish Cache inspired HTTP probehttp://github.com/uber/airlock


Inst<strong>an</strong>ti<strong>at</strong>e your Airlock1 var airlock = new Airlock({2 title: ‘geocod’,3 threshold: 3,4 window: 5,5 maxWait: 64 * 10006 });


Seal your HTTP request1 var options = {2 host: ‘http://geocod.uber.local’,3 p<strong>at</strong>h: ‘/reverse/geocode’,4 params: { l<strong>at</strong>: 45.543, lng: -122.654 },5 <strong>time</strong>out: 15006 };78 airlock.seal(options, function(err, addr) {9 if (err) return callback(err);10 // do something interesting with addr11 });


Coupling, <strong>the</strong> Quiet KillerA Push Notific<strong>at</strong>ions Case Study


“Your <strong>Uber</strong> is on <strong>the</strong> way. Jeff (4.9stars) will pick you up in 2 minutes.”smsClient.sendDisp<strong>at</strong>chAccepted(...);


“Your <strong>Uber</strong> is on <strong>the</strong> way. Jeff (4.9stars) will pick you up in 2 minutes.”smsClient.sendDisp<strong>at</strong>chAccepted(...);pushClient.sendDisp<strong>at</strong>chAccepted(...);


“Your <strong>Uber</strong> is on <strong>the</strong> way. Jeff (4.9stars) will pick you up in 2 minutes.”smsClient.sendDisp<strong>at</strong>chAccepted(...);pushClient.sendDisp<strong>at</strong>chAccepted(...);disp<strong>at</strong>chAccepted.publish(...)


1 disp<strong>at</strong>chAccepted.publish({2 driverFirstName: ‘Jeff’,3 driverR<strong>at</strong>ing: 4.9,4 eta: 120,5 smsEnabled: false6 });


End-User<strong>Real</strong>-<strong>time</strong>ServicesKafkaNotific<strong>at</strong>ionServiceSMS ServiceAccept Disp<strong>at</strong>chThe H<strong><strong>an</strong>d</strong><strong>of</strong>f


End-User<strong>Real</strong>-<strong>time</strong>ServicesKafkaNotific<strong>at</strong>ionServiceSMS ServiceAccept Disp<strong>at</strong>chPublishThe H<strong><strong>an</strong>d</strong><strong>of</strong>f


End-User<strong>Real</strong>-<strong>time</strong>ServicesKafkaNotific<strong>at</strong>ionServiceSMS ServiceAccept Disp<strong>at</strong>chPublishSubscribeThe H<strong><strong>an</strong>d</strong><strong>of</strong>f


End-User<strong>Real</strong>-<strong>time</strong>ServicesKafkaNotific<strong>at</strong>ionServiceSMS ServiceAccept Disp<strong>at</strong>chPublishSubscribeSendThe H<strong><strong>an</strong>d</strong><strong>of</strong>f


End-User<strong>Real</strong>-<strong>time</strong>ServicesKafkaNotific<strong>at</strong>ionServiceSMS ServiceAccept Disp<strong>at</strong>chPublishSubscribeSendPushThe H<strong><strong>an</strong>d</strong><strong>of</strong>f


<strong>Real</strong>-<strong>time</strong>ServicesKafka LeafKafkaAggreg<strong>at</strong>eOut-<strong>of</strong>-B<strong><strong>an</strong>d</strong>Consumerpublish(to: topicwith: d<strong>at</strong>a)ZYXStoreForwardBA Z Y Xsubscribe(to: topic)DiskKafka <strong>Architecture</strong>


<strong>Event</strong>-<strong>Driven</strong> APIAlerts, Analytics, ETAs, Fraud, Pricing,Marketplace Metrics, Visualiz<strong>at</strong>ions


DO make events a first-class citizendisp<strong>at</strong>chAccepted.publish({driver: driver,trip: trip});


DO make it easy to adorn yourevents with common propertiesdecor<strong>at</strong>e(event).with(‘common’).with(‘driver’).with(‘vehicle’);


DO consider throughput <strong><strong>an</strong>d</strong>l<strong>at</strong>ency


DO give yourself “<strong>an</strong> out” by versioning your eventsDO give your consumers <strong>the</strong> rawest <strong>of</strong> d<strong>at</strong>a


DON’T forget th<strong>at</strong> Kafka is a dependency tooDON’T publish events for actions th<strong>at</strong> aren’tiniti<strong>at</strong>ed by your serviceDON’T pollute your event stream withunnecessary inform<strong>at</strong>ion


StormRedistribute your d<strong>at</strong>a


Kafka Topics Storm Spouts Storm Bolts RedisCh<strong>an</strong>nelstrip_requestedS1trip_beg<strong>an</strong>S2B1trip_ch<strong>an</strong>gestrip_endedS3


Kafka Topics Storm Spouts Storm Bolts RedisCh<strong>an</strong>nelstrip_requestedB3S1trip_beg<strong>an</strong>S2B2B1trip_ch<strong>an</strong>gestrip_endedB4S3B5


Stream MergingFor applic<strong>at</strong>ion-specific streams


Kafka <strong>Event</strong>StreamStorm Spouts Storm Bolts Kafka D<strong>at</strong>aStreamtrip_requestedS1driver_disp<strong>at</strong>chedMdisp<strong>at</strong>ch_dist<strong>an</strong>cesS2


Outpace Complexity


Th<strong>an</strong>ks for listening!Oh, <strong><strong>an</strong>d</strong> we’re hiring:wolski@uber.com

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!