Devoxx London 2017 - Rethinking Services With Stateful Streams

84
Rethinking Services with Stateful Streams Ben Stopford @benstopford

Transcript of Devoxx London 2017 - Rethinking Services With Stateful Streams

Page 1: Devoxx London 2017 - Rethinking Services With Stateful Streams

Rethinking Services with Stateful Streams

Ben Stopford @benstopford

Page 2: Devoxx London 2017 - Rethinking Services With Stateful Streams
Page 3: Devoxx London 2017 - Rethinking Services With Stateful Streams

What are microservices really about?

Page 4: Devoxx London 2017 - Rethinking Services With Stateful Streams

GUI

UI Service

Orders Service

Returns Service

Fulfilment Service

Payment Service

Stock Service

Splitting the Monolith? Single Process /Code base

/Deployment

Many Processes /Code bases

/Deployments

Page 5: Devoxx London 2017 - Rethinking Services With Stateful Streams

Orders Service

Autonomy?

Page 6: Devoxx London 2017 - Rethinking Services With Stateful Streams

Orders Service

Stock Service

Email Service

Fulfillment Service

Independently Deployable

Independently Deployable

Independently Deployable

Independently Deployable

Page 7: Devoxx London 2017 - Rethinking Services With Stateful Streams

Independence is where services get

their value

Page 8: Devoxx London 2017 - Rethinking Services With Stateful Streams

Allows Scaling

Page 9: Devoxx London 2017 - Rethinking Services With Stateful Streams

Scaling in terms of people

What happens when we grow?

Page 10: Devoxx London 2017 - Rethinking Services With Stateful Streams

Companies are inevitably a collection of applications They must work together to some degree

Page 11: Devoxx London 2017 - Rethinking Services With Stateful Streams

Interconnection is an afterthought

FTP / Enterprise Messaging etc

Page 12: Devoxx London 2017 - Rethinking Services With Stateful Streams

Internal World

External world

External world

External World

External world

Service Boundary

Services Force Us To Consider The External World

Page 13: Devoxx London 2017 - Rethinking Services With Stateful Streams

Internal World

External world

External world

External World

External world

Service Boundary

External World is something we should Design For

Page 14: Devoxx London 2017 - Rethinking Services With Stateful Streams

Independence comes at a cost

$$$

Page 15: Devoxx London 2017 - Rethinking Services With Stateful Streams

Orders Object

Statement Object getOpenOrders(),

Less Surface Area = Less Coupling

Encapsulate State

Encapsulate Functionality

Consider Two Objects in one address space

Encapsulation => Loose Coupling

Page 16: Devoxx London 2017 - Rethinking Services With Stateful Streams

Change 1 Change 2

Redeploy

Singly-deployable apps are easy

Page 17: Devoxx London 2017 - Rethinking Services With Stateful Streams

Orders Service Statement Service getOpenOrders(),

Independently Deployable Independently Deployable

Synchronized changes are painful

Page 18: Devoxx London 2017 - Rethinking Services With Stateful Streams

Services work best where requirements are isolated in a single

bounded context

Page 19: Devoxx London 2017 - Rethinking Services With Stateful Streams

Single Sign On Business Service authorise(),

It’s unlikely that a Business Service would need the internal SSO state / function to change

Single Sign On

Page 20: Devoxx London 2017 - Rethinking Services With Stateful Streams

SSO has a tightly bounded context

Page 21: Devoxx London 2017 - Rethinking Services With Stateful Streams

But business services are

different

Page 22: Devoxx London 2017 - Rethinking Services With Stateful Streams

Catalog Authorisation

Most business services share the same core datasets.

Most services live in here

Page 23: Devoxx London 2017 - Rethinking Services With Stateful Streams

The futures of business services

are far more tightly intertwined.

Page 24: Devoxx London 2017 - Rethinking Services With Stateful Streams

We need encapsulation to hide internal state. Be loosely coupled.

But we need the freedom to slice & dice shared data like any other

dataset

Page 25: Devoxx London 2017 - Rethinking Services With Stateful Streams

But data systems have little to do

with encapsulation

Page 26: Devoxx London 2017 - Rethinking Services With Stateful Streams

Service Database

Data on inside

Data on outside

Data on inside

Data on outside

Interface hides data

Interface amplifies

data

Databases amplify the data they hold

Page 27: Devoxx London 2017 - Rethinking Services With Stateful Streams

The data dichotomy Data systems are about exposing data.

Services are about hiding it.

Page 28: Devoxx London 2017 - Rethinking Services With Stateful Streams

Microservices shouldn’t

share a database

Good Advice!

Page 29: Devoxx London 2017 - Rethinking Services With Stateful Streams

So what do we do instead?

Page 30: Devoxx London 2017 - Rethinking Services With Stateful Streams

Service Interface

Database

Data on inside

Data on outside

We wrap a database in a service interface

Page 31: Devoxx London 2017 - Rethinking Services With Stateful Streams

One of two things happens next

Page 32: Devoxx London 2017 - Rethinking Services With Stateful Streams

Service Interface

Database

Either (1) we constantly add to the interface, as datasets grow

getOpenOrders( fulfilled=false, deliveryLocation=CA, orderValue=100, operator=GreatherThan)

Page 33: Devoxx London 2017 - Rethinking Services With Stateful Streams

getOrder(Id)

getOrder(UserId)

getAllOpenOrders()

getAllOrdersUnfulfilled(Id)

getAllOrders()

(1) Services can end up looking like kookie home-grown databases

Page 34: Devoxx London 2017 - Rethinking Services With Stateful Streams

...and DATA amplifies this “Data-Service”

problem

Page 35: Devoxx London 2017 - Rethinking Services With Stateful Streams

(2) Give up and move whole datasets en masse

getAllOrders()

Data Copied Internally

Data Service Business Service

Page 36: Devoxx London 2017 - Rethinking Services With Stateful Streams

This leads to a different problem

Page 37: Devoxx London 2017 - Rethinking Services With Stateful Streams

Data diverges over time

Orders Service

Stock Service

Email Service

Fulfill- ment Service

Page 38: Devoxx London 2017 - Rethinking Services With Stateful Streams

The more mutable copies,

the more data will diverge over time

Page 39: Devoxx London 2017 - Rethinking Services With Stateful Streams

Nice neat services

Service contract too

limiting

Can we change both services

together, easily? NO

Broaden Contract

Eek $$$

NO

YES

Is it a shared

Database?

Frack it! Just give me ALL the data

Data diverges. (many different

versions of the same facts) Lets encapsulate

Lets centralise to one copy

YES

Start here

Cycle of inadequacy:

Page 40: Devoxx London 2017 - Rethinking Services With Stateful Streams

These forces compete in the systems we build

Divergence

Accessibility

Coupling

Page 41: Devoxx London 2017 - Rethinking Services With Stateful Streams

Is there a better way?

Page 42: Devoxx London 2017 - Rethinking Services With Stateful Streams

Two core patterns of system design

Request Driven Event Driven Logic

Page 43: Devoxx London 2017 - Rethinking Services With Stateful Streams

=> a set of very different architectures

Event (widget ordered)

Query (Get my orders)

State change

No state change

Request driven Event Driven

Logic

Aside: Commands, Events & Queries

Command (order widget)

Page 44: Devoxx London 2017 - Rethinking Services With Stateful Streams

Request Driven -> highest Coupling

Commands & Queries

Page 45: Devoxx London 2017 - Rethinking Services With Stateful Streams

Event Driven: Interact through Events,

Don't talk to Services

Page 46: Devoxx London 2017 - Rethinking Services With Stateful Streams

Orders Service

Bus

Event Broadcast => lowest coupling

Stream of events

Do whatever I like J

Very Independent

Page 47: Devoxx London 2017 - Rethinking Services With Stateful Streams

Kafka changes things a bit

Page 48: Devoxx London 2017 - Rethinking Services With Stateful Streams

Kafka: a Streaming Platform

The Log Connectors Connectors

Producer Consumer

Streaming Engine

Page 49: Devoxx London 2017 - Rethinking Services With Stateful Streams

Service Backbone Scalable, Fault Tolerant, Concurrent, Strongly Ordered, Retentive

Page 50: Devoxx London 2017 - Rethinking Services With Stateful Streams

A place to keep the data-on-the-outside

Page 51: Devoxx London 2017 - Rethinking Services With Stateful Streams

Orders Customers

Payments Stock

Events are the shared dataset

Cached Views Suffice

LEAVE DATA IN KAFKA LONG TERM -> Services only need caches

Page 52: Devoxx London 2017 - Rethinking Services With Stateful Streams

Now add Stream Processing

A machine for combining and processing streams of events

Page 53: Devoxx London 2017 - Rethinking Services With Stateful Streams

A Query Engine inside your service

Join Filter Aggr- egate

View

Window

Page 54: Devoxx London 2017 - Rethinking Services With Stateful Streams

Kafka

KTable

Inbound Stream

(Windowed)

State Store Outbound Stream

Changelog Stream

DSL !

Built in disk overflow – A maintained cache embedded inside your service

Your Service

Kafka

Page 55: Devoxx London 2017 - Rethinking Services With Stateful Streams

Window / Tables Cached on disk in your Service

stream

Compacted stream

Join

Stream Data

Stream-Tabular Data

Domain Logic

Tables /

Views

Kafka

Event Driven Service

Page 56: Devoxx London 2017 - Rethinking Services With Stateful Streams

Avg(o.time – p.time) From orders, payment, user Group by user.region over 1 day window emitting every second

Streams & Tables In Streams & Tables Out

Streams

Stream Processing Engine

Table

Derived “Table”

Page 57: Devoxx London 2017 - Rethinking Services With Stateful Streams

Join & Process the outputs of many different services

Email Service

Legacy App Orders Payments Stock

KSTREAMS

Kafka

Page 58: Devoxx London 2017 - Rethinking Services With Stateful Streams

Two core

types of event

driven service

Page 59: Devoxx London 2017 - Rethinking Services With Stateful Streams

Type 1: Event Service

Payments Orders

Stock

Event Driven Service

Join outputs from many other services

Page 60: Devoxx London 2017 - Rethinking Services With Stateful Streams

Orders Service

Kafka

Interactive Queries API

Context Boundary

Type 2: Query Service

Page 61: Devoxx London 2017 - Rethinking Services With Stateful Streams

So we have shared storage in

the Log, and a query engine

layered on top

Page 62: Devoxx London 2017 - Rethinking Services With Stateful Streams

Data Storage + Query Engine == Database?

Data lives here

KAFKA

MY SERVICE

Query lives here

Page 63: Devoxx London 2017 - Rethinking Services With Stateful Streams

Customer Alteration

Service

MI Fraud Fulfillment

Data lives here KAFKA

UI View

Queries processed in each service

1 x Data Storage + n x Query == Shared Database?

Page 64: Devoxx London 2017 - Rethinking Services With Stateful Streams

A Database, Inside Out

Historical Streams

Services embed a

view

Services embed a

view

Services embed a view

Services embed a view

Page 65: Devoxx London 2017 - Rethinking Services With Stateful Streams

Microservices shouldn’t share a

database

Page 66: Devoxx London 2017 - Rethinking Services With Stateful Streams

But this isn’t a normal database

Page 67: Devoxx London 2017 - Rethinking Services With Stateful Streams

Orders Service

Stock Service

Kafka

Fulfilment Service

UI Service

Fraud Service

Remember: Event Broadcast has the lowest coupling

Stream of events

Do whatever I like J

Page 68: Devoxx London 2017 - Rethinking Services With Stateful Streams

It decentralizes responsibility for query processing

Page 69: Devoxx London 2017 - Rethinking Services With Stateful Streams

Orders Service

Stock Service

Kafka

Fulfilment Service

UI Service

Fraud Service

Centralizing immutable data doesn’t affect coupling!

Golden Copy

Do whatever I like J

Page 70: Devoxx London 2017 - Rethinking Services With Stateful Streams

To share a database,

turn it inside out!

Page 71: Devoxx London 2017 - Rethinking Services With Stateful Streams

Shared database

Service Interfaces

Log-Backed Streaming

J !

L !

Event Broadcast

Coupling (Autonomy)

Accessibility Integrity (Divergence)

L !

L !

J !

J !

K !

J !

J !

J !

J !

L !L !

Page 72: Devoxx London 2017 - Rethinking Services With Stateful Streams

--------------------------- World Wide Web ---------------------------

Payment Gateway

Finance Fulfillment

Web Query

Web Command

Start with an event-driven data layer, overlay SSP to (a) process events and (b) create views

Page 73: Devoxx London 2017 - Rethinking Services With Stateful Streams

So…

Page 74: Devoxx London 2017 - Rethinking Services With Stateful Streams

Good architectures have little to do with this:

Page 75: Devoxx London 2017 - Rethinking Services With Stateful Streams

It’s about how systems evolves over time

Page 76: Devoxx London 2017 - Rethinking Services With Stateful Streams

Hang simple services in a decoupled ecosystem

Page 77: Devoxx London 2017 - Rethinking Services With Stateful Streams

Ecosystem that embraces shared data

Historical Streams

Page 78: Devoxx London 2017 - Rethinking Services With Stateful Streams

Break the ties of request driven approaches

Page 79: Devoxx London 2017 - Rethinking Services With Stateful Streams

Designing for DATA on the outside

Page 80: Devoxx London 2017 - Rethinking Services With Stateful Streams

Set your data free!

Data should be available. Data should be under your control.

Page 81: Devoxx London 2017 - Rethinking Services With Stateful Streams

•  Broadcast events •  Retain them in the log •  Compose functions with a

streaming engine •  Build views when you need to

Event Driven Services

Page 82: Devoxx London 2017 - Rethinking Services With Stateful Streams

WIRED Principals •  Wimpy: Start simple, lightweight and fault tolerant.

•  Immutable: Build a retentive, shared narrative.

•  Reactive: Leverage Asynchronicity. Focus on the now.

•  Evolutionary: Use only the data you need today.

•  Decentralized: Receiver driven. Coordination avoiding. No

God services

Page 83: Devoxx London 2017 - Rethinking Services With Stateful Streams

References •  Stopford: The Data Dichotomy:

https://www.confluent.io/blog/data-dichotomy-rethinking-the-way-we-treat-data-and-services/

•  Kleppmann: Turning the Database Inside Out: https://www.confluent.io/blog/turning-the-database-inside-out-with-apache-samza/

•  Helland: Immutability Changes Everything: http://cidrdb.org/cidr2015/Papers/CIDR15_Paper16.pdf

•  Kreps: The Log: https://engineering.linkedin.com/distributed-systems/log-what-every-software-engineer-should-know-about-real-time-datas-unifying

•  Narkhede: Event Sourcing, CQRS & Stream Processing: https://www.confluent.io/blog/event-sourcing-cqrs-stream-processing-apache-kafka-whats-connection/

Page 84: Devoxx London 2017 - Rethinking Services With Stateful Streams

Twitter: @benstopford

Blog of this talk at http://confluent.io/blog