FEARLESS AWS LAMBDAS @johnchapin symphonia.io - - PowerPoint PPT Presentation

fearless aws lambdas
SMART_READER_LITE
LIVE PREVIEW

FEARLESS AWS LAMBDAS @johnchapin symphonia.io - - PowerPoint PPT Presentation

FEARLESS AWS LAMBDAS @johnchapin symphonia.io http://bit.ly/symph-qcon-fearless john@symphonia.io WHAT IS LAMBDA? LAMBDA PERFORMANCE LAMBDA + JAVA LAMBDA + THE JVM CHOOSING THE JVM WHAT IS LAMBDA? Serverless Serverless traits


slide-1
SLIDE 1

FEARLESS AWS LAMBDAS

@johnchapin symphonia.io

slide-2
SLIDE 2

http://bit.ly/symph-qcon-fearless
 
 john@symphonia.io

slide-3
SLIDE 3

WHAT IS LAMBDA? LAMBDA PERFORMANCE LAMBDA + JAVA LAMBDA + THE JVM CHOOSING THE JVM

slide-4
SLIDE 4

WHAT IS LAMBDA?

slide-5
SLIDE 5

Serverless

slide-6
SLIDE 6
slide-7
SLIDE 7

Serverless traits

  • 1. No management of long-lived host or application instances
  • 2. Self auto-scaling/provisioning, based on load
  • 3. Costs based on precise usage, zero usage = zero cost
  • 4. Performance capability defined in terms other than host

size/count

  • 5. Implicit high availability
slide-8
SLIDE 8

Backend as a Service
 (BaaS) Functions as a Service
 (FaaS)

slide-9
SLIDE 9

FaaS attributes

Runs user code Event driven Auto scaled/provisioned Precise costs

slide-10
SLIDE 10

Lambda platform

Java, Javascript, Python, C# Integrated with other AWS services Scales up in milliseconds $ per GB/sec, 100ms increments

slide-11
SLIDE 11

Lambda history

November 2014 - Node.js, 1GB, 60s June 2015 - Java, 1.5GB July 2015 - API Gateway October 2015 - Python, 300s November 2016 - C#, Lambda@Edge

slide-12
SLIDE 12

API Gateway DynamoDB S3 Kinesis

Serverless ecosystem

SQS SNS Step Functions X-Ray

slide-13
SLIDE 13

Runtime environment

128MB to 1.5GB memory 2 virtual CPUs 500MB /tmp STDOUT, STDERR to Cloudwatch Logs

slide-14
SLIDE 14

Behind the scenes

Containers on EC2 Created on demand Reaped when idle, old, or obsolete

slide-15
SLIDE 15

LAMBDA PERFORMANCE

slide-16
SLIDE 16

Performance challenges

Layers of abstraction Diverse components Error handling and retries Event batching Scaling

slide-17
SLIDE 17

Benchmark Lambda

Java 8 Minimal dependencies 2 threads, 500 iterations of fib(30) Various memory settings

slide-18
SLIDE 18

Benchmark goal

Show performance is proportional to memory setting 1.5GB should be 12x faster than 128MB

slide-19
SLIDE 19

Expected performance

slide-20
SLIDE 20

Measured performance (us-west-2)

slide-21
SLIDE 21

US-EAST-1 strikes again!

slide-22
SLIDE 22

WTF? (Feb 2017, us-west-2)

slide-23
SLIDE 23

Benchmark conclusions

Memory = consistency (mostly) Benchmark over long periods of time Benchmark in multiple regions

slide-24
SLIDE 24

Cold starts

  • 1. Platform receives event
  • 2. Platform inits container
  • 3. Container inits language runtime
  • 4. Language runtime inits user code
  • 5. Platform passes event to container
slide-25
SLIDE 25

Cold starts (us-west-2)

slide-26
SLIDE 26

Cold starts

2 days of data (us-west-2) 128MB - 1.8% of the time 1.5GB - 0.97% of the time

slide-27
SLIDE 27

LAMBDA + JAVA

slide-28
SLIDE 28

io.symphonia.Lambda::handler

slide-29
SLIDE 29

package io.symphonia; public class Lambda { public String handler(String input) { return input; } }

slide-30
SLIDE 30

package io.symphonia; public class Lambda { public void handler(int n) { // do something ... } }

slide-31
SLIDE 31

package io.symphonia; import java.io.InputStream; import java.io.OutputStream; public class Lambda { public void handler(InputStream input, OutputStream output) { // Read from the InputStream // Write to the OutputStream } }

slide-32
SLIDE 32

package io.symphonia; import com.amazonaws.services.lambda.runtime.CognitoIdentity; import com.amazonaws.services.lambda.runtime.Context; public class Lambda { public String handler(String input, Context context) { // Inspect Context CognitoIdentity identity = context.getIdentity(); int remaining = context.getRemainingTimeInMillis(); // do something ... return input; } }

slide-33
SLIDE 33

Handling input

Lambda runtime will deserialize JSON -> POJOs Include event POJOs as source Avoid large dependencies just for event classes

  • AWS event types are scattered across libraries

Or, parse incoming JSON yourself (InputStream)

slide-34
SLIDE 34

package io.symphonia; public class Lambda { public String handler(MyInputObject inputObject) { return inputObject.getField(); } public static class MyInputObject { String field; public String getField() { return field; } public void setField(String field) { this.field = field; } } }

slide-35
SLIDE 35

package io.symphonia; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3ClientBuilder; import java.util.UUID; public class Lambda { private AmazonS3 s3client; private String bucket = "myBucket"; public Lambda() { s3client = AmazonS3ClientBuilder.defaultClient(); } public void handler(String key) { s3client.putObject(bucket, key, UUID.randomUUID().toString()); } }

slide-36
SLIDE 36

Deployment

Deployment artifact is a zip file For Java, an uberjar Use mvn-shade-plugin or similar

  • Your code, plus your dependencies
slide-37
SLIDE 37

Multi-Lambda applications

Multi-module Maven project AWS Bill-of-materials (BOM)

  • dependencyManagement for AWS SDKs

Serverless Application Model (SAM)

slide-38
SLIDE 38

LAMBDA + THE JVM

slide-39
SLIDE 39

Lambda’s JVM runtime

OpenJDK 1.8 Server VM

  • XX:MaxHeapSize = 85% of configured Lambda memory
  • XX:+UseSerialGC
  • XX:+TieredCompilation
  • Xshare:on
slide-40
SLIDE 40

JVM cold starts

Class loading Initialization

  • Constructors, static initialization blocks

Alternative language runtime loading (Clojure!) JIT compilation

slide-41
SLIDE 41

The Lambda diet

Fewer classes = faster startup

  • Ruthlessly cull dependencies
  • AWS libraries can be bloated!

mvn dependency:tree, sbt dependencyStats

slide-42
SLIDE 42

Cloudwatch Logs

System.out/err output goes to Cloudwatch Logs One “log group” per Lambda (by default) Within “log group” , one “log stream” per container From Cloudwatch, can aggregate and/or forward

slide-43
SLIDE 43

System.out.nope

System.out.println is bad for the normal reasons *Real* logging is better Lambda runtime can add RequestId to Log4J logs aws-lambda-java-log4j uses Log4J 1.2 ☹

slide-44
SLIDE 44

lambda-logging

SLF4J + Logback 😁 Sane default configuration w/ AWS RequestId Open Source (Apache 2 license)

  • io.symphonia/lambda-logging “1.0.0”
  • github.com/symphoniacloud/lambda-monitoring/
slide-45
SLIDE 45

Cloudwatch Metrics

No built-in business metrics Lambda platform metrics

  • Errors, Duration, Invocations, Throttles

Naive metrics collection approach is dangerous!

  • Cloudwatch has account-level API limits 🔦
slide-46
SLIDE 46

Cloudwatch Metric Filters

Built into Cloudwatch! Scalable! Scrape Cloudwatch Logs data using special (finicky) patterns Generates and post Cloudwatch metrics

slide-47
SLIDE 47

lambda-metrics

Codahale metrics and lambda-logging Maven plugin builds Metric Filters to scrape logs, post to CW Open Source (Apache 2 license)

  • io.symphonia/lambda-metrics “1.0.0”
  • github.com/symphoniacloud/lambda-monitoring
slide-48
SLIDE 48

CHOOSING THE JVM

slide-49
SLIDE 49

Ideal application

Latency tolerant Regularly invoked Computationally intensive

slide-50
SLIDE 50

TL;DR

Use Lambda’s JVM runtime Reduce and amortize cold start impact Benchmark extensively Use real logging and metrics

slide-51
SLIDE 51

http://bit.ly/symph-qcon-fearless
 
 john@symphonia.io