cloud native data pipelines (goto chicago 2017)

91
Cloud Native Data Pipelines 1 Sid Anand ( @ r39132 ) GoTo Chicago 2017

Upload: sid-anand

Post on 22-Jan-2018

412 views

Category:

Software


0 download

TRANSCRIPT

Page 1: Cloud Native Data Pipelines (GoTo Chicago 2017)

Cloud Native Data Pipelines

1

Sid Anand (@r39132) GoTo Chicago 2017

Page 2: Cloud Native Data Pipelines (GoTo Chicago 2017)

About Me

2

Work [ed | s] @

Committer & PPMC on

Father of 2

Co-Chair for

Apache Airflow

Page 3: Cloud Native Data Pipelines (GoTo Chicago 2017)

Agari

3

What We Do!

Page 4: Cloud Native Data Pipelines (GoTo Chicago 2017)

Agari : What We Do

4

Page 5: Cloud Native Data Pipelines (GoTo Chicago 2017)

5

Agari : What We Do

Page 6: Cloud Native Data Pipelines (GoTo Chicago 2017)

6

Agari : What We Do

Page 7: Cloud Native Data Pipelines (GoTo Chicago 2017)

7

Agari : What We Do

Page 8: Cloud Native Data Pipelines (GoTo Chicago 2017)

8

Agari : What We Do

Page 9: Cloud Native Data Pipelines (GoTo Chicago 2017)

9

Enterprise Customers

email metadata

apply trust

modelsemail md + trust score

Agari’s Previous EP Version

Agari : What We Do

Batch

Page 10: Cloud Native Data Pipelines (GoTo Chicago 2017)

Quarantine, Label,

PassThrough

10

email metadata

apply trust

modelsemail md + trust score

Agari’s Current EP VersionEnterprise Customers

Agari : What We Do

Near-real time

Page 11: Cloud Native Data Pipelines (GoTo Chicago 2017)

MotivationCloud Native Data Pipelines

11

Page 12: Cloud Native Data Pipelines (GoTo Chicago 2017)

Cloud Native Data Pipelines

12

Big Data Companies like LinkedIn, Facebook, Twitter, & Google have large teams to manage their data pipelines (100s of engineers)

Most start-ups have small teams (10s of engineers) & run in the public cloud. Can they leverage aspects of the public cloud to build comparable pipelines?

Page 13: Cloud Native Data Pipelines (GoTo Chicago 2017)

Cloud Native Data Pipelines

13

Cloud Native Techniques

Open Source Technogies

Data Pipelines seen in Big Data companies

~

Page 14: Cloud Native Data Pipelines (GoTo Chicago 2017)

Design GoalsDesirable Qualities of a Resilient Data Pipeline

14

Page 15: Cloud Native Data Pipelines (GoTo Chicago 2017)

15

Desirable Qualities of a Resilient Data Pipeline

OperabilityCorrectness

Timeliness Cost

Page 16: Cloud Native Data Pipelines (GoTo Chicago 2017)

16

Desirable Qualities of a Resilient Data Pipeline

OperabilityCorrectness

Timeliness Cost

• Data Integrity (no loss, etc…)

• Expected data distributions

• All output within time-bound SLAs

• Minimize Operational Fatigue / Automate Everything

• Fine-grained Monitoring & Alerting of Correctness & Timeliness SLAs

• Quick Recoverability

• Pay-as-you-go

Page 17: Cloud Native Data Pipelines (GoTo Chicago 2017)

Quickly Recoverable

17

• Bugs happen!

• Bugs in Predictive Data Pipelines have a large blast radius

• Optimize for MTTR

Page 18: Cloud Native Data Pipelines (GoTo Chicago 2017)

Predictive Analytics @ AgariUse Cases

18

Page 19: Cloud Native Data Pipelines (GoTo Chicago 2017)

Use Cases

19

Apply trust models (message scoring)

batch + near real time

Build trust models

batch

(Enterprise Protect)Focus of this talk

Page 20: Cloud Native Data Pipelines (GoTo Chicago 2017)

Use-Case : Message Scoring (batch)Batch Pipeline Architecture

20

Page 21: Cloud Native Data Pipelines (GoTo Chicago 2017)

Use-Case : Message Scoring

21

enterprise Aenterprise Benterprise C

S3

S3 uploads an Avro file every 15 minutes

Page 22: Cloud Native Data Pipelines (GoTo Chicago 2017)

Use-Case : Message Scoring

22

enterprise Aenterprise Benterprise C

S3

Airflow kicks of a Spark message scoring job

every hour (EMR)

Page 23: Cloud Native Data Pipelines (GoTo Chicago 2017)

Use-Case : Message Scoring

23

enterprise Aenterprise Benterprise C

S3

Spark job writes scored messages and stats to

another S3 bucket

S3

Page 24: Cloud Native Data Pipelines (GoTo Chicago 2017)

Use-Case : Message Scoring

24

enterprise Aenterprise Benterprise C

S3

This triggers SNS/SQS messages events

S3

SNS

SQS

Page 25: Cloud Native Data Pipelines (GoTo Chicago 2017)

Use-Case : Message Scoring

25

enterprise Aenterprise Benterprise C

S3

An Autoscale Group (ASG) of Importers spins up when it detects SQS

messages

S3

SNS

SQS

Importers

ASG

Page 26: Cloud Native Data Pipelines (GoTo Chicago 2017)

26

enterprise Aenterprise Benterprise C

S3

The importers rapidly ingest scored messages and aggregate statistics into

the DB

S3

SNS

SQS

Importers

ASGDB

Use-Case : Message Scoring

Page 27: Cloud Native Data Pipelines (GoTo Chicago 2017)

27

enterprise Aenterprise Benterprise C

S3

Users receive alerts of untrusted emails & can review them in

the web app

S3

SNS

SQS

Importers

ASGDB

Use-Case : Message Scoring

Page 28: Cloud Native Data Pipelines (GoTo Chicago 2017)

28

enterprise Aenterprise Benterprise C

S3 S3

SNS

SQS

Importers

ASGDB

Airflow manages the entire process

Use-Case : Message Scoring

Page 29: Cloud Native Data Pipelines (GoTo Chicago 2017)

29

Architectural ComponentsComponent Role Uses Salient Features Operability Model

Data Lake • All data stored in S3 • All processing uses S3

Scalable, Available, Performant Serverless

Messaging • Reliable, Transactional, Pub/Sub

Scalable, Available, Performant Serverless

ASG General Processing

• Used for importing, data cleansing, business logic

Scalable, Available, Performant Managed

Data Science Processing

• Aggregation • Model Building • Scoring

Nice programming model at the cost of

debugging complexityWe Operate

Workflow Engine

• Coordinates all Spark Jobs & complex flows

Lightweight, DAGs as Code, Steep learning

curveWe Operate

DB Persistence for WebApp

• Holds subset of data needed for Web App Rails + Postgres

‘nuff said We Operate

S3

SNS SQS

Page 30: Cloud Native Data Pipelines (GoTo Chicago 2017)

Tackling Cost & TimelinessLeveraging the AWS Cloud

30

Page 31: Cloud Native Data Pipelines (GoTo Chicago 2017)

Tackling Cost

31

Between Daily Runs During Daily Runs

When running daily, for 23 hours of a day, we didn’t pay for instances in the ASG or EMR

Page 32: Cloud Native Data Pipelines (GoTo Chicago 2017)

Tackling Cost

32

Between Hourly Runs During Hourly Runs

When running daily, for 23 hours of a day, we didn’t pay for instances in the ASG or EMR

This does not help when runs are hourly since AWS charges at an hourly rate for EC2 instances!

Page 33: Cloud Native Data Pipelines (GoTo Chicago 2017)

Tackling TimelinessAuto Scaling Group (ASG)

33

Page 34: Cloud Native Data Pipelines (GoTo Chicago 2017)

ASG - Overview

34

What is it?

A means to automatically scale out/in clusters to handle variable load/traffic

A means to keep a cluster/service of a fixed size always up

Page 35: Cloud Native Data Pipelines (GoTo Chicago 2017)

ASG - Data Pipeline

35

importer

importer

importer

importer

Importer ASG

scale out / inSQS

DB

Page 36: Cloud Native Data Pipelines (GoTo Chicago 2017)

36

Sent

CPU

ACKd/Recvd

CPU-based auto-scaling is good at scaling in/out to keep the average CPU constant

ASG : CPU-based

Page 37: Cloud Native Data Pipelines (GoTo Chicago 2017)

ASG : CPU-based

37

Sent

CPU

Recv

Premature Scale-in

Premature Scale-in:

• The CPU drops to noise-levels before all messages are consumed

• This causes scale in to occur while the last few messages are still being committed

Page 38: Cloud Native Data Pipelines (GoTo Chicago 2017)

38

Scale-out: When Visible Messages > 0 (a.k.a. when queue depth > 0)

Scale-in: When Invisible Messages = 0 (a.k.a. when the last in-flight message is ACK’d)

This causes the ASG to grow

This causes the ASG to shrink

ASG : Queue-based

Page 39: Cloud Native Data Pipelines (GoTo Chicago 2017)

Auto Scaling GroupsBuild & Deploy

39

Page 40: Cloud Native Data Pipelines (GoTo Chicago 2017)

ASG - Build & Deploy

40

Component Role Details

Spins up Cloud Resources• Spins up SQS, Kinesis, EC2, ASG,

ELB, etc.. and associate them using Terraform

• A better version of Chef & Puppet

• Sets up an EC2 instance

• Agentless, idempotent, & declarative tool to set up EC2 instances, by installing & configuring packages, and more

• Spins up an EC2 instance for the purposes of building an AMI!

• Can be used with Ansible & Terraform to bake AMIs & Launch Auto-Scaling Groups

Page 41: Cloud Native Data Pipelines (GoTo Chicago 2017)

ASG - Build & Deploy

41

EC2 Step 1 : Packer spins up a temporary EC2 node - a blank canvas!

Page 42: Cloud Native Data Pipelines (GoTo Chicago 2017)

EC2

ASG - Build & Deploy

42

EC2 Step 1 : Packer spins up a temporary EC2 node - a blank canvas!

Step 2 : Packer runs an Ansible role against the EC2 node to set it up.

Page 43: Cloud Native Data Pipelines (GoTo Chicago 2017)

EC2

ASG - Build & Deploy

43

EC2

Step 2 : Packer runs an Ansible role against the EC2 node to set it up.

Step 3 : Snapshots the machine & register the AMI.EC2

Step 1 : Packer spins up a temporary EC2 node - a blank canvas!

Page 44: Cloud Native Data Pipelines (GoTo Chicago 2017)

EC2

ASG - Build & Deploy

44

EC2

Step 2 : Packer runs an Ansible role against the EC2 node to set it up.

Step 3 : Snapshots the machine & register the AMI.EC2

Step 4 : Terminates the EC2 instance!

Step 1 : Packer spins up a temporary EC2 node - a blank canvas!

Page 45: Cloud Native Data Pipelines (GoTo Chicago 2017)

EC2

ASG - Build & Deploy

45

EC2

Step 2 : Packer runs an Ansible role against the EC2 node to set it up.

Step 3 : Snapshots the machine & register the AMI.EC2

Step 4 : Terminates the EC2 instance!

Step 5 : Using the AMI, Terraform spins up an auto-scaled compute cluster (ASG)

Step 1 : Packer spins up a temporary EC2 node - a blank canvas!

ASG

Page 46: Cloud Native Data Pipelines (GoTo Chicago 2017)

46

Desirable Qualities of a Resilient Data Pipeline

OperabilityCorrectness

Timeliness Cost• ASG • EMR Spark

Daily • ASG • EMR Spark Hourly ASG • No Cost Savings

Page 47: Cloud Native Data Pipelines (GoTo Chicago 2017)

Tackling Operability & CorrectnessLeveraging Tooling

47

Page 48: Cloud Native Data Pipelines (GoTo Chicago 2017)

48

A simple way to author, configure, manage workflows

Provides visual insight into the state & performance of workflow runs

Integrates with our alerting and monitoring tools

Tackling Operability : Requirements

Page 49: Cloud Native Data Pipelines (GoTo Chicago 2017)

Apache AirflowWorkflow Automation & Scheduling

49

Page 50: Cloud Native Data Pipelines (GoTo Chicago 2017)

50

Airflow: Author DAGs in Python! No need to bundle many config files!

Apache Airflow - Authoring DAGs

Page 51: Cloud Native Data Pipelines (GoTo Chicago 2017)

51

Airflow: Visualizing a DAG

Apache Airflow - Authoring DAGs

Page 52: Cloud Native Data Pipelines (GoTo Chicago 2017)

Apache Airflow - Perf. Insights

52

Airflow: Gantt chart view reveals the slowest tasks for a run!

Page 53: Cloud Native Data Pipelines (GoTo Chicago 2017)

53

Apache Airflow - Perf. InsightsAirflow: Task Duration chart view show task completion time trends!

Page 54: Cloud Native Data Pipelines (GoTo Chicago 2017)

54

Airflow: …And easy to integrate with Ops tools!Apache Airflow - Alerting

Page 55: Cloud Native Data Pipelines (GoTo Chicago 2017)

55

Desirable Qualities of a Resilient Data Pipeline

OperabilityCorrectness

Timeliness Cost

Page 56: Cloud Native Data Pipelines (GoTo Chicago 2017)

Use-Case : Message Scoring (near-real time)NRT Pipeline Architecture

56

Page 57: Cloud Native Data Pipelines (GoTo Chicago 2017)

Use-Case : Message Scoring

57

enterprise Aenterprise Benterprise C

Kinesis batch put every second

K

Page 58: Cloud Native Data Pipelines (GoTo Chicago 2017)

Use-Case : Message Scoring

58

enterprise Aenterprise Benterprise C

K

As ASG of scorers is scaled up to one process per core per kinesis shard

Scorers

ASG

Page 59: Cloud Native Data Pipelines (GoTo Chicago 2017)

Use-Case : Message Scoring

59

enterprise Aenterprise Benterprise C

KScorers

ASG

KinesisScorers apply the trust model and send scored messages downstream

Page 60: Cloud Native Data Pipelines (GoTo Chicago 2017)

Use-Case : Message Scoring

60

enterprise Aenterprise Benterprise C

KScorers

ASG

Kinesis

Importers

ASG

As ASG of importers is scaled up to rapidly import messages

DB

Page 61: Cloud Native Data Pipelines (GoTo Chicago 2017)

Use-Case : Message Scoring

61

enterprise Aenterprise Benterprise C

KScorers

ASG

Kinesis

Importers

ASG

Imported messages are also consumed by the

alerter

DB

K

Alerters

ASG

Page 62: Cloud Native Data Pipelines (GoTo Chicago 2017)

Use-Case : Message Scoring

62

enterprise Aenterprise Benterprise C

KScorers

ASG

Kinesis

Importers

ASG

Imported messages are also consumed by the

alerter

DB

K

Alerters

ASG

Quarantine Email

Page 63: Cloud Native Data Pipelines (GoTo Chicago 2017)

63

Stream Processing ArchitectureComponent Role Details Pros Operability Model

Data Lake • All data stored in S3 via Kinesis Firehose

Scalable, Available, Performant, Serverless Serverless

Kinesis Messaging • Streaming transport modeled on Kafka

Scalable, Available, Serverless Serverless

General Processing

• ASG Replacement except for Rails Apps Scalable, Available,

Serverless Serverless

ASG General Processing

• Used for importing, data cleansing, business logic

Scalable, Available, Managed Managed

Data Science Processing

• Model Building We Operate

Workflow Engine• Nightly model builds +

some classic Ops cron workloads

Lightweight, DAGs as Code We Operate

DB Persistence for WebApp

• Holds smaller subset of data needed for Web App

Rails + Postgres ‘nuff said We Operate

Persistence for WebApp

• Aggregation + Search moved from DB to ES

• Model Building queries moved to Elasticache Redis

Faster. more accurate for aggregates, frees up

headroom for DB (polyglot persistence)

Managed

S3

Page 64: Cloud Native Data Pipelines (GoTo Chicago 2017)

InnovationsNRT Pipeline Architecture

64

Page 65: Cloud Native Data Pipelines (GoTo Chicago 2017)

Apache AvroWhat is Avro?

65

Page 66: Cloud Native Data Pipelines (GoTo Chicago 2017)

66

What is Avro?

Avro is a self-describing serialization format that supports

primitive data types : int, long, boolean, float, string, bytes, etc…

complex data types : records, arrays, unions, maps, enums, etc…

many language bindings : Java, Scala, Python, Ruby, etc…

Page 67: Cloud Native Data Pipelines (GoTo Chicago 2017)

67

What is Avro?

Avro is a self-describing serialization format that supports

primitive data types : int, long, boolean, float, string, bytes, etc…

complex data types : records, arrays, unions, maps, enums, etc…

many language bindings : Java, Scala, Python, Ruby, etc…

The most common format for storing structured Big Data at rest in HDFS, S3, Google Cloud Storage, etc…

Supports Schema Evolution!

Page 68: Cloud Native Data Pipelines (GoTo Chicago 2017)

Apache AvroWhy is it useful?

68

Page 69: Cloud Native Data Pipelines (GoTo Chicago 2017)

69

Why is Avro Useful?Agari is an IoT company!

Agari Sensors, deployed at customer sites, stream data to Agari’s Cloud SAAS

Data is sent via Kinesis!

enterprise Aenterprise Benterprise C Kinesis

Agari SAAS in AWS

Page 70: Cloud Native Data Pipelines (GoTo Chicago 2017)

70

Why is Avro Useful?

enterprise A :enterprise B :enterprise C : Kinesis

v1v2v3

Agari is an IoT company!

Agari Sensors, deployed at customer sites, stream data to Agari’s Cloud SAAS

Data is sent via Kinesis!

At any point in time, customers run different versions of the Agari Sensor

Agari SAAS in AWS

Page 71: Cloud Native Data Pipelines (GoTo Chicago 2017)

71

Why is Avro Useful?

enterprise A :enterprise B :enterprise C : Kinesis

v1v2v3

Agari is an IoT company!

Agari Sensors, deployed at customer sites, stream data to Agari’s Cloud SAAS

Data is sent via Kinesis!

At any point in time, customers run different versions of the Agari Sensor

These Sensors might send different format versions of the data!

Agari SAAS in AWS

Page 72: Cloud Native Data Pipelines (GoTo Chicago 2017)

72

Why is Avro Useful?

enterprise A :enterprise B :enterprise C : Kinesis

v1v2v3

Agari SAAS in AWS

v4

Agari is an IoT company!

Agari Sensors, deployed at customer sites, stream data to Agari’s Cloud SAAS

Data is sent via Kinesis!

At any point in time, customers run different versions of the Agari Sensor

These Sensors might send different format versions of the data!

Page 73: Cloud Native Data Pipelines (GoTo Chicago 2017)

73

Why is Avro Useful?

enterprise A :enterprise B :enterprise C :

v1v2v3

Avro allows Agari to seamlessly handle different IoT data format versions

Agari SAAS in AWS

Kinesis v4

datum_reader = DatumReader( writers_schema = writers_schema,

readers_schema = readers_schema)

Requirements:

• Schemas are backward-compatible

Page 74: Cloud Native Data Pipelines (GoTo Chicago 2017)

74

Why is Avro Useful?

Agari SAAS in AWS

S1 S2 S3

s3 Spark

Avro Everywhere!

Avro is so useful, we don’t just to communicate between our Sensors & our SAAS infrastructure

We also use it as the common data-interchange format between all services (streaming & batch) within our AWS deployment

Page 75: Cloud Native Data Pipelines (GoTo Chicago 2017)

75

Why is Avro Useful?

Agari SAAS in AWS

S1 S2 S3

s3 Spark

Avro Everywhere!

Good Language Bindings :

Data Pipelines services are written in Java, Ruby, & Python

Page 76: Cloud Native Data Pipelines (GoTo Chicago 2017)

Apache AvroBy Example

76

Page 77: Cloud Native Data Pipelines (GoTo Chicago 2017)

77

{"namespace": "agari", "type": "record", "name": "User", "fields": [ {"name": "name", "type": "string"}, {"name": "favorite_number", "type": ["int", "null"]}, {"name": "favorite_color", "type": ["string", "null"]} ] }

complex type (record)Schema name : User

3 fields in the record: 1 required, 2 optional

Avro Schema Example

Page 78: Cloud Native Data Pipelines (GoTo Chicago 2017)

78

{"namespace": "agari", "type": "record", "name": "User", "fields": [ {"name": "name", "type": "string"}, {"name": "favorite_number", "type": ["int", "null"]}, {"name": "favorite_color", "type": ["string", "null"]} ] }

Data

x 1,000,000,000

Avro Schema Data File Example

Schema

Data

0.0001 %

99.999 %

Data

Data

Data

Data

Data

Data

Data

Data

Data

Data

Data

Data

Data

Data

Data

Data

Data

Page 79: Cloud Native Data Pipelines (GoTo Chicago 2017)

79

{"namespace": "agari", "type": "record", "name": "User", "fields": [ {"name": "name", "type": "string"}, {"name": "favorite_number", "type": ["int", "null"]}, {"name": "favorite_color", "type": ["string", "null"]} ] }

Binary Data block

Avro Schema Streaming Example

Schema

Data

99 %

1 %

Data

Page 80: Cloud Native Data Pipelines (GoTo Chicago 2017)

80

{"namespace": "agari", "type": "record", "name": "User", "fields": [ {"name": "name", "type": "string"}, {"name": "favorite_number", "type": ["int", "null"]}, {"name": "favorite_color", "type": ["string", "null"]} ] }

Binary Data block

Avro Schema Streaming Example

Schema

Data

99 %

1 %

Data

OVERHEAD!!

Page 81: Cloud Native Data Pipelines (GoTo Chicago 2017)

Apache AvroSchema Registry

81

Page 82: Cloud Native Data Pipelines (GoTo Chicago 2017)

82

Schema Registry

(Lambda)

Avro Schema Registry

{"namespace": "agari", "type": "record", "name": "User", "fields": [ {"name": "name", "type": "string"}, {"name": "favorite_number", "type": ["int", "null"]}, {"name": "favorite_color", "type": ["string", "null"]} ] }

register_schema

Message Producer (P)

Page 83: Cloud Native Data Pipelines (GoTo Chicago 2017)

83

Schema Registry

(Lambda)

register_schema returns a UUID

Message Producer (P)

Avro Schema Registry

Page 84: Cloud Native Data Pipelines (GoTo Chicago 2017)

84

Schema Registry

(Lambda)

Message Producer sends UUID +

Message Producer (P)

Data

Message Consumer (C)

Avro Schema Registry

Page 85: Cloud Native Data Pipelines (GoTo Chicago 2017)

85

Schema Registry

(Lambda)

Message Producer (P)

Data

Message Consumer (C)

getSchemaById (UUID)

Avro Schema Registry

Page 86: Cloud Native Data Pipelines (GoTo Chicago 2017)

86

Schema Registry

(Lambda)

Message Producer (P)

Data

Message Consumer (C)

getSchemaById (UUID){"namespace": "agari", "type": "record", "name": "User", "fields": [ {"name": "name", "type": "string"}, {"name": "favorite_number", "type": ["int", "null"]}, {"name": "favorite_color", "type": ["string", "null"]} ] }

Avro Schema Registry

Page 87: Cloud Native Data Pipelines (GoTo Chicago 2017)

87

Schema Registry

(Lambda)

Message Producer (P)

Message Consumer (C)

getSchemaById (UUID){"namespace": "agari", "type": "record", "name": "User", "fields": [ {"name": "name", "type": "string"}, {"name": "favorite_number", "type": ["int", "null"]}, {"name": "favorite_color", "type": ["string", "null"]} ] }

Message Consumers • download & cache the schema

• then decode the data

Avro Schema Registry

Page 88: Cloud Native Data Pipelines (GoTo Chicago 2017)

88

enterprise Aenterprise Benterprise C

KScorers

ASG

Kinesis

Importers

ASG

Imported messages are also consumed by the

alerter

DB

K

Alerters

ASG

SR

SR

SR

Avro Schema Registry

Page 89: Cloud Native Data Pipelines (GoTo Chicago 2017)

89

enterprise Aenterprise Benterprise C

KScorers

ASG

Kinesis

Importers

ASG

Imported messages are also consumed by the

alerter

DB

K

Alerters

ASG

SR

SR

SR

Avro Schema Registry

Page 90: Cloud Native Data Pipelines (GoTo Chicago 2017)

Acknowledgments

90

• Vidur Apparao • Stephen Cattaneo • Jon Chase • Andrew Flury • William Forrester • Chris Haag • Chris Buchanan • Neil Chapin • Wil Collins • Don Spencer

• Scot Kennedy • Natia Chachkhiani • Patrick Cockwell • Kevin Mandich • Gabriel Ortiz • Jacob Rideout • Josh Yang • Julian Mehnle • Gabriel Poon • Spencer Sun • Nathan Bryant

None of this work would be possible without the essential contributions of the team below

Page 91: Cloud Native Data Pipelines (GoTo Chicago 2017)

Questions?

(@r39132)

91