Catalyst Ubers Serverless Platform Shawn Burke - Staff Engineer - - PowerPoint PPT Presentation

catalyst
SMART_READER_LITE
LIVE PREVIEW

Catalyst Ubers Serverless Platform Shawn Burke - Staff Engineer - - PowerPoint PPT Presentation

Catalyst Ubers Serverless Platform Shawn Burke - Staff Engineer Uber Seattle Why Serverless? Complexity! Microservices, Languages, Client Libs, Tools Product teams have basic infrastructure needs Stable, consistent app


slide-1
SLIDE 1

Catalyst

Uber’s Serverless Platform Shawn Burke - Staff Engineer Uber Seattle

slide-2
SLIDE 2

Why Serverless?

  • Complexity!

○ Microservices, Languages, Client Libs, Tools ○ Product teams have basic infrastructure needs

  • Stable, consistent app platform pays huge dividends
  • Abstraction => Simplicity => Leverage
slide-3
SLIDE 3

Why are we building it?

(aka “Why don’t you just use AWS Lambda?”)

  • Multi-cloud strategy
  • Uber doesn’t run prod on AWS today
  • Performance, extensibility requirements

○ New source types ○ Granular visibility/control

  • Integration with existing systems
slide-4
SLIDE 4

Catalyst Goals

  • DEVELOPER FOCUSED: runs on desktop and in prod
  • Dramatically simplify the process of delivering business logic
  • Unify disparate systems with common patterns
  • Pluggability: Multi-Language (handlers), extensible sources
  • Minimal hard dependencies on underlying compute & networking
  • FAST: < 5ms P99 Catalyst “tax”
slide-5
SLIDE 5

End-to-End Experience

  • Standardized service layout and execution
  • Common coding model across sources types
  • Batteries ARE Included: Config, Logging, Metrics, Dashboards, Crash

Bucketing, Multi-Datacenter, Telemetry, Capture/Replay, Tracing

  • Fun, fast iteration loop: code => test => debug => deploy
slide-6
SLIDE 6

Writing Handlers: Go Example

func MyKafkaHandler1(ctx catalyst.Context, msg []byte) error { ctx.Logger().Typed().Info("[my-kafka-topic] MSGS", log.Int32("len", len(msg))) return nil } func RegisterHandlers(catalyst *catalyst.Registry, g group) { catalyst.Register(chttp.Handler(g.HelloWorldHandler, "/", http.MethodGet)) } catalyst.Register(kafka.Handler(MyKafkaHandler1, "my-kafka-topic")) func MyKafkaHandler1(ctx catalyst.Context, msg string) error { ctx.Logger().Typed().Info("[my-kafka-topic] MSGS", log.Int32("len", len(msg))) return nil } func MyKafkaHandler1(ctx context.Context, msg *myJsonStruct) error { catalyst.Logger(ctx).Info("[my-kafka-topic] MSGS", log.Int32("len", len(msg))) return nil } type group struct {} func (g *group) HelloWorldHandler(ctx context.Context, rw http.ResponseWriter, req *http.Request) { rw.Write([]byte(":-)")) }

logger := catalyst.Logger(ctx) config := catalyst.Config(ctx) metrics:= catalyst.Metrics(ctx)

slide-7
SLIDE 7

Writing Handlers: Java

@Group public class Handlers { private static final Logger LOG = LoggerFactory.getLogger(Handlers.class); @Handler @HTTP(path="/", method=Method.GET) public CompletableFuture<String> index(Context ctx) { LOG.info("We just got a message from #{} ", ctx.userHeaders.get("User-Agent")); return CompletableFuture.completedFuture(":-)"); } @Handler @Kafka(topic="my-kafka-topic", consumeGroup="my-cg") public void myTopicMessage(Context ctx, Payload payload) { } }

slide-8
SLIDE 8

Glossary

We have the best words.

  • Source: Converts external events to

Catalyst messages

  • Worker: Binary containing user

code

  • Handler: Individual event handler
  • Group: N handlers; unit of

deployment

slide-9
SLIDE 9

Architecture: Runtime/Data Plane

Nanny

  • Goal State
  • Process Lifecycle & Restart

Worker

  • User Code
  • Dispatching
  • Telemetry
  • Heartbeats

Sources: Kafka, GRPC, HTTP,etc

  • Per Event Type
  • Flow Control
  • Telemetry
  • Capture/Replay

GRPC

  • Each box is a process
  • Worker & Sources

○ Local: Worker from build ○ Production: Worker & Sources from S3

  • Shared Nothing Architecture
slide-10
SLIDE 10

Container

Controller catalyst run Package Build Worker Binary manifest.json Nanny Kafka Source Worker Binary HTTP Request Kafka Message

manifest.json { "group_name": "my_http_demo", "project_name": "examples", "runtime": "go", "handlers": [ { "name": "http_GET_HelloWorldHandler", "source_type": "http", "params": { "method": "GET", "path": "/" }, "config": { ... } }, { "name": "kafka_MyKafkaHandler1", "source_type": "kafka", "params": { "offset": "newest", "topic": "my-kafka-topic", } } ], "built_at": "2017-02-08T14:38:36Z", "platform": "darwin" }`

HTTP Source

slide-11
SLIDE 11

Anatomy of a Request

Source Frontend (Source Author) Backend (Catalyst SDK)

External System

Worker Dispatcher

(Catalyst SDK - Per Language)

User Handlers

Handler ID Headers Raw Payload

Metrics & Logging Manifest

GRPC / UDS Deserialization

slide-12
SLIDE 12

Architecture: Control Plane

Registry S3 Controller CLI GRPC Stream (Goal States) Warming Pool (Containers) RUNNING! Nanny/Container Mission Control Request Capacity MySQL

Metadata Bits Goal State (Manifest) Download: Sources & Worker

slide-13
SLIDE 13

Catalyst Today

  • Written in Go
  • Onboarding customers
  • Persistent Containers, “Tax” P99 ~2ms
  • Production hardening

○ Load testing ○ Testing negative scenarios and failure cases

  • Bringing errors and information close to users
slide-14
SLIDE 14

Catalyst Tomorrow

  • Auto scaling
  • Integrated (source-specific) status reporting

○ E.g. report status of underlying Kafka topics

  • Advanced scenarios

○ Long-tail handlers ○ SLA-based priority ○ Traffic-based placement

  • Goal: Open Source (no timeline quite yet)
slide-15
SLIDE 15

Questions?

sburke@uber.com