SlideShare a Scribd company logo
Finagle: Twitter’s RPC Library 
24 Oct. 2014 
Steve Gury 
@stevegury
> whoami 
stevegury 
2005 2008 2011 2014 time 
Distributed Systems 
Massively Multiplayer Online Games 
Twitter 
Scala
Agenda 
1. Motivation 
2.Finagle TL;DR 
3.Three Key Abstractions 
4.Finagle Big Picture
Motivation & Context 
2006 2010 2014 
>2M Tweets / day 
(January 2009) 
>65M Tweets / day 
(July 2010) 
>500M Tweets / day 
(August 2013)
Agenda 
1. Motivation 
2.Finagle TL;DR 
3.Three Key Abstractions 
4.Finagle Big Picture
Finagle TL;DR 
Compose RPC like you 
compose functions
Composing Functions 
getUserId(name: String): Int getTweets(userId: Int): Tweets 
getTweets(name: String): Tweets 
= getUserId ◦ getTweets (name)
Agenda 
1. Motivation 
2.Finagle TL;DR 
3.Three Key Abstractions 
4.Finagle Big Picture
Futures 
Futures are containers for value 
Pending Successful Failed 
Present
Futures 
a 
val a: Future[Int]
Futures 
a 
b 
val a: Future[Int] 
val b: Future[Int] = a map { x => x + 512 }
Futures 
a 
b 
c 
val a: Future[Int] 
val b: Future[Int] = a map { x => x + 512 } 
val c = a map { x => 64 / x }
Futures 
a 
b 
c 
d 
val a: Future[Int] 
val b: Future[Int] = a map { x => x + 512 } 
val c = a map { x => 64 / x } 
val d = Future.join(b,c)
Futures 
a 
b 
c 
d e 
val a: Future[Int] 
val b: Future[Int] = a map { x => x + 512 } 
val c = a map { x => 64 / x } 
val d = Future.join(b,c) 
val e = d map { case (x, y) => x + y }
Futures 
16 b 
a 
c 
d e 
val a: Future[Int] 
val b: Future[Int] = a map { x => x + 512 } 
val c = a map { x => 64 / x } 
val d = Future.join(b,c) 
val e = d map { case (x, y) => x + y }
Futures 
16 b 
a 
c 
d e 
val a: Future[Int] 
val b: Future[Int] = a map { x => x + 512 } 
val c = a map { x => 64 / x } 
val d = Future.join(b,c) 
val e = d map { case (x, y) => x + y }
Futures 
16 
a 
528 
b 
c 
d e 
val a: Future[Int] 
val b: Future[Int] = a map { x => x + 512 } 
val c = a map { x => 64 / x } 
val d = Future.join(b,c) 
val e = d map { case (x, y) => x + y }
Futures 
16 
a 
528 
b 
c 
d e 
val a: Future[Int] 
val b: Future[Int] = a map { x => x + 512 } 
val c = a map { x => 64 / x } 
val d = Future.join(b,c) 
val e = d map { case (x, y) => x + y }
Futures 
16 
a 
528 
b 
4 
c 
d e 
val a: Future[Int] 
val b: Future[Int] = a map { x => x + 512 } 
val c = a map { x => 64 / x } 
val d = Future.join(b,c) 
val e = d map { case (x, y) => x + y }
Futures 
16 
a 
528 
b 
4 
c 
d e 
val a: Future[Int] 
val b: Future[Int] = a map { x => x + 512 } 
val c = a map { x => 64 / x } 
val d = Future.join(b,c) 
val e = d map { case (x, y) => x + y }
Futures 
16 
a 
528 
b 
4 
c 
d e 
val a: Future[Int] 
val b: Future[Int] = a map { x => x + 512 } 
val c = a map { x => 64 / x } 
val d = Future.join(b,c) 
val e = d map { case (x, y) => x + y }
Futures 
16 
a 
528 
b 
4 
(528, 
4) 
c 
d e 
val a: Future[Int] 
val b: Future[Int] = a map { x => x + 512 } 
val c = a map { x => 64 / x } 
val d = Future.join(b,c) 
val e = d map { case (x, y) => x + y }
Futures 
16 
a 
528 
b 
4 
(528, 
4) 
c 
d e 
val a: Future[Int] 
val b: Future[Int] = a map { x => x + 512 } 
val c = a map { x => 64 / x } 
val d = Future.join(b,c) 
val e = d map { case (x, y) => x + y }
Futures 
16 
a 
528 
b 532 
4 
(528, 
4) 
c 
d e 
val a: Future[Int] 
val b: Future[Int] = a map { x => x + 512 } 
val c = a map { x => 64 / x } 
val d = Future.join(b,c) 
val e = d map { case (x, y) => x + y }
Futures 
0 b 
a 
c 
d e 
val a: Future[Int] 
val b: Future[Int] = a map { x => x + 512 } 
val c = a map { x => 64 / x } 
val d = Future.join(b,c) 
val e = d map { case (x, y) => x + y }
Futures 
0 
a 
512 
b 
c 
d e 
val a: Future[Int] 
val b: Future[Int] = a map { x => x + 512 } 
val c = a map { x => 64 / x } 
val d = Future.join(b,c) 
val e = d map { case (x, y) => x + y }
Futures 
0 
a 
512 
b 
Ex 
c 
d e 
val a: Future[Int] 
val b: Future[Int] = a map { x => x + 512 } 
val c = a map { x => 64 / x } 
val d = Future.join(b,c) 
val e = d map { case (x, y) => x + y }
Futures 
0 
a 
512 
b Ex 
Ex 
c 
d e 
val a: Future[Int] 
val b: Future[Int] = a map { x => x + 512 } 
val c = a map { x => 64 / x } 
val d = Future.join(b,c) 
val e = d map { case (x, y) => x + y }
Futures 
0 
a 
512 
b Ex Ex 
Ex 
c 
d e 
val a: Future[Int] 
val b: Future[Int] = a map { x => x + 512 } 
val c = a map { x => 64 / x } 
val d = Future.join(b,c) 
val e = d map { case (x, y) => x + y }
Futures 
Lots of combinators: 
! 
map -> add an edge+node in the graph 
flatMap -> combine two graphs together 
handle -> deal with exceptions 
join -> merge multiple nodes of the graphs 
select -> select the first node with a value 
! 
…more
Programming with Futures == Building a Graph
Service 
Remember the key idea: treat RPC like functions
Service 
Service is a Function from Request to Response 
! 
trait Service[Request, Response] {! 
def apply(req: Request): Response! 
}! 
! 
Equivalent to Scala’s Function1: Request=>Response
Service 
But it has to be asynchronous, and treat exception as 
value 
! 
trait Service[Request, Response] {! 
def apply(req: Request): Future[Response]! 
}! 
!
Service 
It also has to be closable for proper management of 
resources. 
! 
trait Service[Request, Response] {! 
def apply(req: Request): Future[Response]! 
def close(): Future[Unit]! 
}!
ServiceFactory 
Factory of Service 
(Function that returns a Function)
ServiceFactory 
Function that asynchronously returns a Service 
! 
trait ServiceFactory[Req, Rep] {! 
def apply(): Future[Service[Req, Rep]]! 
def close(): Future[Unit]! 
}
Agenda 
1. Motivation 
2.Finagle TL;DR 
3.Three Key Abstractions 
4.Finagle Big Picture
Transport 
trait Transport[In, Out] { 
def write(req: In): Future[Unit] 
def read(): Future[Out] 
} 
Transport
Dispatcher 
class Dispatcher[A, B] extends Service[…] { 
def apply(req: A): Future[B] 
} 
Dispatcher Transport
Connection Pool 
class ConnPool[A,B] extends ServiceFactory[…]{ 
def apply(): Future[Service[A, B]] 
} 
Connection Dispatcher Transport 
Pool
Load Balancer 
class LoadBalancer[A,B] extends ServiceFactory[…]{ 
def apply(): Future[Service[A, B]] 
} 
Connection Dispatcher Transport 
Pool 
Load 
Balancer
Finagle in Action 
Connection Dispatcher Transport 
Pool 
Load 
Balancer 
val req: Request 
loadbalancer() // LB select an host 
// Pool select a connection
Finagle in Action 
val req: Request 
loadbalancer() flatMap { 
service => // LBService(PoolService(disp)) 
} 
Connection Dispatcher Transport 
Pool 
Load 
Balancer
Finagle in Action 
val req: Request 
loadbalancer() flatMap { 
service => // LBService(PoolService(disp)) 
service(req) // disp write req on Transp. 
} 
Connection Dispatcher Transport 
Pool 
Load 
Balancer
Finagle in Action 
val req: Request 
loadbalancer() flatMap { 
service => // LBService(PoolService(disp)) 
service(req) ensure { 
service.close() // close LBService 
// close PoolService 
} 
} 
Connection Dispatcher Transport 
Pool 
Load 
Balancer
FactoryToService 
class FactoryToService[A, B](factory: ServiceFactory[A, B]) 
extends Service[A, B] 
{ 
def apply(request: A): Future[B] = 
factory() flatMap { service => 
service(request) ensure { 
service.close() 
} 
} 
} 
Connection Dispatcher Transport 
Pool 
Load 
Balancer 
FactoryTo 
Service
Connection Dispatcher Transport 
Pool 
Load 
Balancer 
Finagle is “just” a composition of independent 
functions on top of a Transport 
FactoryTo 
Service
The “Simplified” Full Picture 
Stats 
Timeout 
Draining 
Load Balancer 
Monitor 
Stats 
Failure accrual 
Timeout 
Conn. Pool 
Expiration Dispatcher 
ServiceFactory 
Service
The Stack is configured for you 
You rarely have to configured the stack, we have a series 
of predefined stack for you. 
! 
scala> val client: ServiceFactory[Req, Res] = Http.client! 
.newClient(“localhost:8080")! 
!
The Stack is configured for you 
You rarely have to configured the stack, we have a series 
of predefined stack for you. 
! 
scala> val client: Service[Req, Res] = Http.client! 
.newClient(“localhost:8080")! 
.toService! 
scala> client(req)!
The Stack is configured for you 
You rarely have to configured the stack, we have a series 
of predefined stack for you. 
! 
scala> val client: Service[Req, Res] = Http.client! 
.configured(DefaultPool.Param(5, 10, 0, 1.minute, 100))! 
.newClient(“localhost:8080")! 
.toService! 
scala> client(req)! 
! 
You can configure any layer of the Stack
Finagle is doing more… 
• Load balancing 
• Connection pooling and request buffering 
• Dynamic membership (Zookeeper) 
• Failure detection and mitigation (fail-fast & failure 
accrual) 
• Statistics for visibility 
• Distributed tracing (Zipkin) 
• Cancellation propagation 
• Automatic retrying 
• Graceful shutdown and request draining 
• GC avoidance - traffic shaping 
• Backup requests
Load balancing
Load balancing 
1 
0 
0 
10
Load balancing 
1 
10 
0
Load balancing 
24 
25 
22 
0
A Better Load Balancer 
Key idea: Use history of recorded latencies to estimate 
the “cost” of sending a request to a server
Experimental Latencies
A better Load Balancer 
First idea: calculate an average of the latencies
Experimental Latencies
A better Load Balancer 
Better idea: calculate EWMA average of the latencies 
EWMA(n+1) = EWMA(n) * ⍺ + (1 - ⍺) * Xn+1
Experimental Latencies
A better Load Balancer 
The devil is in the details 
! 
Recency of data: EWMA unevenly spaced t-Series 
EWMA(n+1) = EWMA(n) * e-td/Tau + (1 - e-td/Tau) * Xn+1 
No history: Initial cost=0 + Probation
Cost & Experimental Latencies
A Better Load Balancer 
The devil is in the details 
! 
Speed of convergence: Cost “rides the peaks” 
Outliers: Decaying cost
Cost & Experimental Latencies
A Better Load Balancer 
The devil is in the details 
! 
CPU intensive: “The Power of 2 Choices”
A Better Load Balancer 
“The Power of 2 Choices in Randomized Load Balancing” P.h.D 
Thesis of M. Mitzenmacher
Load balancing 
0 20 
0 
10 
0 
cost: 20ms 
cost: 10ms 
cost: 10ms
cost: 18ms 
Load balancing 
0 20 
0 
10 
0 
20ms 
cost: 10ms 
cost: 10ms
The “Simplified” Full Picture 
Stats 
Timeout 
Draining 
Load Balancer 
Monitor 
Stats 
Failure accrual 
Timeout 
Conn. Pool 
Expiration Dispatcher 
ServiceFactory 
Service
Finagle’s Architecture 
Experience from writing “large scale” software 
! 
Independent modules 
Simple contracts 
Powerful combinators
Conclusion 
• Finagle is a library that lets you treat RPC as functions 
• Finagle is itself composed of independent functions 
• Very widely used at Twitter, Foursquare, Tumblr, 
Pinterest, SoundCloud… 
• Protocol agnostic (thrift, http, redis, mysql…) 
Github: github.com/twitter/finagle 
“Your server as a Function” http://monkey.org/~marius/ 
funsrv.pdf
@finagle 
@stevegury

More Related Content

PDF
Functional Systems @ Twitter
DOCX
Cg my own programs
DOC
COMPUTER GRAPHICS LAB MANUAL
DOC
Computer graphics
DOCX
Advance java
DOC
SE Computer, Programming Laboratory(210251) University of Pune
DOCX
CLUSTERGRAM
PDF
Computer graphics lab manual
Functional Systems @ Twitter
Cg my own programs
COMPUTER GRAPHICS LAB MANUAL
Computer graphics
Advance java
SE Computer, Programming Laboratory(210251) University of Pune
CLUSTERGRAM
Computer graphics lab manual

What's hot (20)

PDF
Computer Graphics Lab
PDF
The Uncertain Enterprise
DOCX
imager package in R and examples..
PDF
Computer graphics lab report with code in cpp
DOCX
Computer graphics lab assignment
DOCX
Computer Graphics Lab File C Programs
PPT
Struct examples
DOCX
Graphics practical lab manual
DOCX
Mosaic plot in R.
PDF
Computer graphics lab manual
PPT
computer graphics practicals
PPTX
Deep learning study 3
DOCX
Wap in c to draw a line using DDA algorithm
PDF
Writing SOLID C++ [gbgcpp meetup @ Zenseact]
PPT
Parallel Prefix Adders Presentation
PDF
Reactive Collections
PDF
CLIM Undergraduate Workshop: Tutorial on R Software - Huang Huang, Oct 23, 2017
PDF
Cbse question paper class_xii_paper_2000
Computer Graphics Lab
The Uncertain Enterprise
imager package in R and examples..
Computer graphics lab report with code in cpp
Computer graphics lab assignment
Computer Graphics Lab File C Programs
Struct examples
Graphics practical lab manual
Mosaic plot in R.
Computer graphics lab manual
computer graphics practicals
Deep learning study 3
Wap in c to draw a line using DDA algorithm
Writing SOLID C++ [gbgcpp meetup @ Zenseact]
Parallel Prefix Adders Presentation
Reactive Collections
CLIM Undergraduate Workshop: Tutorial on R Software - Huang Huang, Oct 23, 2017
Cbse question paper class_xii_paper_2000
Ad

Viewers also liked (7)

PDF
Numba Overview
PDF
Scaling PyData Up and Out
PDF
PyData Paris 2015 - Track 3.3 Antoine Pitrou
PDF
Buzzwords Numba Presentation
PDF
Numba: Flexible analytics written in Python with machine-code speeds and avo...
PDF
Accelerate Your Python* Code through Profiling, Tuning, and Compilation Part ...
PDF
Numba: Array-oriented Python Compiler for NumPy
Numba Overview
Scaling PyData Up and Out
PyData Paris 2015 - Track 3.3 Antoine Pitrou
Buzzwords Numba Presentation
Numba: Flexible analytics written in Python with machine-code speeds and avo...
Accelerate Your Python* Code through Profiling, Tuning, and Compilation Part ...
Numba: Array-oriented Python Compiler for NumPy
Ad

Similar to Scala.io (20)

PDF
Async Microservices with Twitter's Finagle
PDF
Julio Capote, Twitter
PDF
Facebook C++网络库Wangle调研
ODP
Finagle and Java Service Framework at Pinterest
PPT
PDF
Principles of the Play framework
PDF
Ruslan.shevchenko: most functional-day-kiev 2014
PDF
Sequence and Traverse - Part 2
PDF
Using Akka Futures
PDF
Finagle By Twitter Engineer @ Knoldus
PDF
Scala-Gopher: CSP-style programming techniques with idiomatic Scala.
PDF
pure-functional-programming.pdf
PDF
Voxxed Days Vienna - The Why and How of Reactive Web-Applications on the JVM
PPTX
Tools for Making Machine Learning more Reactive
PDF
Pure Future
PPTX
Exploring Twitter's Finagle technology stack for microservices
PDF
The things we don't see – stories of Software, Scala and Akka
PDF
Large volume data analysis on the Typesafe Reactive Platform - Big Data Scala...
PDF
The Future starts with a Promise
PDF
Reactive Web-Applications @ LambdaDays
Async Microservices with Twitter's Finagle
Julio Capote, Twitter
Facebook C++网络库Wangle调研
Finagle and Java Service Framework at Pinterest
Principles of the Play framework
Ruslan.shevchenko: most functional-day-kiev 2014
Sequence and Traverse - Part 2
Using Akka Futures
Finagle By Twitter Engineer @ Knoldus
Scala-Gopher: CSP-style programming techniques with idiomatic Scala.
pure-functional-programming.pdf
Voxxed Days Vienna - The Why and How of Reactive Web-Applications on the JVM
Tools for Making Machine Learning more Reactive
Pure Future
Exploring Twitter's Finagle technology stack for microservices
The things we don't see – stories of Software, Scala and Akka
Large volume data analysis on the Typesafe Reactive Platform - Big Data Scala...
The Future starts with a Promise
Reactive Web-Applications @ LambdaDays

Recently uploaded (20)

PDF
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
PDF
Understanding Forklifts - TECH EHS Solution
PPTX
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PDF
2025 Textile ERP Trends: SAP, Odoo & Oracle
PDF
Softaken Excel to vCard Converter Software.pdf
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PPTX
ISO 45001 Occupational Health and Safety Management System
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PDF
Design an Analysis of Algorithms II-SECS-1021-03
PDF
Nekopoi APK 2025 free lastest update
PPTX
ManageIQ - Sprint 268 Review - Slide Deck
PDF
How Creative Agencies Leverage Project Management Software.pdf
PDF
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
PPTX
history of c programming in notes for students .pptx
PPTX
Introduction to Artificial Intelligence
PDF
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
PPTX
CHAPTER 12 - CYBER SECURITY AND FUTURE SKILLS (1) (1).pptx
PPT
Introduction Database Management System for Course Database
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
Understanding Forklifts - TECH EHS Solution
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
Wondershare Filmora 15 Crack With Activation Key [2025
2025 Textile ERP Trends: SAP, Odoo & Oracle
Softaken Excel to vCard Converter Software.pdf
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
Odoo Companies in India – Driving Business Transformation.pdf
ISO 45001 Occupational Health and Safety Management System
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
Design an Analysis of Algorithms II-SECS-1021-03
Nekopoi APK 2025 free lastest update
ManageIQ - Sprint 268 Review - Slide Deck
How Creative Agencies Leverage Project Management Software.pdf
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
history of c programming in notes for students .pptx
Introduction to Artificial Intelligence
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
CHAPTER 12 - CYBER SECURITY AND FUTURE SKILLS (1) (1).pptx
Introduction Database Management System for Course Database

Scala.io

  • 1. Finagle: Twitter’s RPC Library 24 Oct. 2014 Steve Gury @stevegury
  • 2. > whoami stevegury 2005 2008 2011 2014 time Distributed Systems Massively Multiplayer Online Games Twitter Scala
  • 3. Agenda 1. Motivation 2.Finagle TL;DR 3.Three Key Abstractions 4.Finagle Big Picture
  • 4. Motivation & Context 2006 2010 2014 >2M Tweets / day (January 2009) >65M Tweets / day (July 2010) >500M Tweets / day (August 2013)
  • 5. Agenda 1. Motivation 2.Finagle TL;DR 3.Three Key Abstractions 4.Finagle Big Picture
  • 6. Finagle TL;DR Compose RPC like you compose functions
  • 7. Composing Functions getUserId(name: String): Int getTweets(userId: Int): Tweets getTweets(name: String): Tweets = getUserId ◦ getTweets (name)
  • 8. Agenda 1. Motivation 2.Finagle TL;DR 3.Three Key Abstractions 4.Finagle Big Picture
  • 9. Futures Futures are containers for value Pending Successful Failed Present
  • 10. Futures a val a: Future[Int]
  • 11. Futures a b val a: Future[Int] val b: Future[Int] = a map { x => x + 512 }
  • 12. Futures a b c val a: Future[Int] val b: Future[Int] = a map { x => x + 512 } val c = a map { x => 64 / x }
  • 13. Futures a b c d val a: Future[Int] val b: Future[Int] = a map { x => x + 512 } val c = a map { x => 64 / x } val d = Future.join(b,c)
  • 14. Futures a b c d e val a: Future[Int] val b: Future[Int] = a map { x => x + 512 } val c = a map { x => 64 / x } val d = Future.join(b,c) val e = d map { case (x, y) => x + y }
  • 15. Futures 16 b a c d e val a: Future[Int] val b: Future[Int] = a map { x => x + 512 } val c = a map { x => 64 / x } val d = Future.join(b,c) val e = d map { case (x, y) => x + y }
  • 16. Futures 16 b a c d e val a: Future[Int] val b: Future[Int] = a map { x => x + 512 } val c = a map { x => 64 / x } val d = Future.join(b,c) val e = d map { case (x, y) => x + y }
  • 17. Futures 16 a 528 b c d e val a: Future[Int] val b: Future[Int] = a map { x => x + 512 } val c = a map { x => 64 / x } val d = Future.join(b,c) val e = d map { case (x, y) => x + y }
  • 18. Futures 16 a 528 b c d e val a: Future[Int] val b: Future[Int] = a map { x => x + 512 } val c = a map { x => 64 / x } val d = Future.join(b,c) val e = d map { case (x, y) => x + y }
  • 19. Futures 16 a 528 b 4 c d e val a: Future[Int] val b: Future[Int] = a map { x => x + 512 } val c = a map { x => 64 / x } val d = Future.join(b,c) val e = d map { case (x, y) => x + y }
  • 20. Futures 16 a 528 b 4 c d e val a: Future[Int] val b: Future[Int] = a map { x => x + 512 } val c = a map { x => 64 / x } val d = Future.join(b,c) val e = d map { case (x, y) => x + y }
  • 21. Futures 16 a 528 b 4 c d e val a: Future[Int] val b: Future[Int] = a map { x => x + 512 } val c = a map { x => 64 / x } val d = Future.join(b,c) val e = d map { case (x, y) => x + y }
  • 22. Futures 16 a 528 b 4 (528, 4) c d e val a: Future[Int] val b: Future[Int] = a map { x => x + 512 } val c = a map { x => 64 / x } val d = Future.join(b,c) val e = d map { case (x, y) => x + y }
  • 23. Futures 16 a 528 b 4 (528, 4) c d e val a: Future[Int] val b: Future[Int] = a map { x => x + 512 } val c = a map { x => 64 / x } val d = Future.join(b,c) val e = d map { case (x, y) => x + y }
  • 24. Futures 16 a 528 b 532 4 (528, 4) c d e val a: Future[Int] val b: Future[Int] = a map { x => x + 512 } val c = a map { x => 64 / x } val d = Future.join(b,c) val e = d map { case (x, y) => x + y }
  • 25. Futures 0 b a c d e val a: Future[Int] val b: Future[Int] = a map { x => x + 512 } val c = a map { x => 64 / x } val d = Future.join(b,c) val e = d map { case (x, y) => x + y }
  • 26. Futures 0 a 512 b c d e val a: Future[Int] val b: Future[Int] = a map { x => x + 512 } val c = a map { x => 64 / x } val d = Future.join(b,c) val e = d map { case (x, y) => x + y }
  • 27. Futures 0 a 512 b Ex c d e val a: Future[Int] val b: Future[Int] = a map { x => x + 512 } val c = a map { x => 64 / x } val d = Future.join(b,c) val e = d map { case (x, y) => x + y }
  • 28. Futures 0 a 512 b Ex Ex c d e val a: Future[Int] val b: Future[Int] = a map { x => x + 512 } val c = a map { x => 64 / x } val d = Future.join(b,c) val e = d map { case (x, y) => x + y }
  • 29. Futures 0 a 512 b Ex Ex Ex c d e val a: Future[Int] val b: Future[Int] = a map { x => x + 512 } val c = a map { x => 64 / x } val d = Future.join(b,c) val e = d map { case (x, y) => x + y }
  • 30. Futures Lots of combinators: ! map -> add an edge+node in the graph flatMap -> combine two graphs together handle -> deal with exceptions join -> merge multiple nodes of the graphs select -> select the first node with a value ! …more
  • 31. Programming with Futures == Building a Graph
  • 32. Service Remember the key idea: treat RPC like functions
  • 33. Service Service is a Function from Request to Response ! trait Service[Request, Response] {! def apply(req: Request): Response! }! ! Equivalent to Scala’s Function1: Request=>Response
  • 34. Service But it has to be asynchronous, and treat exception as value ! trait Service[Request, Response] {! def apply(req: Request): Future[Response]! }! !
  • 35. Service It also has to be closable for proper management of resources. ! trait Service[Request, Response] {! def apply(req: Request): Future[Response]! def close(): Future[Unit]! }!
  • 36. ServiceFactory Factory of Service (Function that returns a Function)
  • 37. ServiceFactory Function that asynchronously returns a Service ! trait ServiceFactory[Req, Rep] {! def apply(): Future[Service[Req, Rep]]! def close(): Future[Unit]! }
  • 38. Agenda 1. Motivation 2.Finagle TL;DR 3.Three Key Abstractions 4.Finagle Big Picture
  • 39. Transport trait Transport[In, Out] { def write(req: In): Future[Unit] def read(): Future[Out] } Transport
  • 40. Dispatcher class Dispatcher[A, B] extends Service[…] { def apply(req: A): Future[B] } Dispatcher Transport
  • 41. Connection Pool class ConnPool[A,B] extends ServiceFactory[…]{ def apply(): Future[Service[A, B]] } Connection Dispatcher Transport Pool
  • 42. Load Balancer class LoadBalancer[A,B] extends ServiceFactory[…]{ def apply(): Future[Service[A, B]] } Connection Dispatcher Transport Pool Load Balancer
  • 43. Finagle in Action Connection Dispatcher Transport Pool Load Balancer val req: Request loadbalancer() // LB select an host // Pool select a connection
  • 44. Finagle in Action val req: Request loadbalancer() flatMap { service => // LBService(PoolService(disp)) } Connection Dispatcher Transport Pool Load Balancer
  • 45. Finagle in Action val req: Request loadbalancer() flatMap { service => // LBService(PoolService(disp)) service(req) // disp write req on Transp. } Connection Dispatcher Transport Pool Load Balancer
  • 46. Finagle in Action val req: Request loadbalancer() flatMap { service => // LBService(PoolService(disp)) service(req) ensure { service.close() // close LBService // close PoolService } } Connection Dispatcher Transport Pool Load Balancer
  • 47. FactoryToService class FactoryToService[A, B](factory: ServiceFactory[A, B]) extends Service[A, B] { def apply(request: A): Future[B] = factory() flatMap { service => service(request) ensure { service.close() } } } Connection Dispatcher Transport Pool Load Balancer FactoryTo Service
  • 48. Connection Dispatcher Transport Pool Load Balancer Finagle is “just” a composition of independent functions on top of a Transport FactoryTo Service
  • 49. The “Simplified” Full Picture Stats Timeout Draining Load Balancer Monitor Stats Failure accrual Timeout Conn. Pool Expiration Dispatcher ServiceFactory Service
  • 50. The Stack is configured for you You rarely have to configured the stack, we have a series of predefined stack for you. ! scala> val client: ServiceFactory[Req, Res] = Http.client! .newClient(“localhost:8080")! !
  • 51. The Stack is configured for you You rarely have to configured the stack, we have a series of predefined stack for you. ! scala> val client: Service[Req, Res] = Http.client! .newClient(“localhost:8080")! .toService! scala> client(req)!
  • 52. The Stack is configured for you You rarely have to configured the stack, we have a series of predefined stack for you. ! scala> val client: Service[Req, Res] = Http.client! .configured(DefaultPool.Param(5, 10, 0, 1.minute, 100))! .newClient(“localhost:8080")! .toService! scala> client(req)! ! You can configure any layer of the Stack
  • 53. Finagle is doing more… • Load balancing • Connection pooling and request buffering • Dynamic membership (Zookeeper) • Failure detection and mitigation (fail-fast & failure accrual) • Statistics for visibility • Distributed tracing (Zipkin) • Cancellation propagation • Automatic retrying • Graceful shutdown and request draining • GC avoidance - traffic shaping • Backup requests
  • 57. Load balancing 24 25 22 0
  • 58. A Better Load Balancer Key idea: Use history of recorded latencies to estimate the “cost” of sending a request to a server
  • 60. A better Load Balancer First idea: calculate an average of the latencies
  • 62. A better Load Balancer Better idea: calculate EWMA average of the latencies EWMA(n+1) = EWMA(n) * ⍺ + (1 - ⍺) * Xn+1
  • 64. A better Load Balancer The devil is in the details ! Recency of data: EWMA unevenly spaced t-Series EWMA(n+1) = EWMA(n) * e-td/Tau + (1 - e-td/Tau) * Xn+1 No history: Initial cost=0 + Probation
  • 65. Cost & Experimental Latencies
  • 66. A Better Load Balancer The devil is in the details ! Speed of convergence: Cost “rides the peaks” Outliers: Decaying cost
  • 67. Cost & Experimental Latencies
  • 68. A Better Load Balancer The devil is in the details ! CPU intensive: “The Power of 2 Choices”
  • 69. A Better Load Balancer “The Power of 2 Choices in Randomized Load Balancing” P.h.D Thesis of M. Mitzenmacher
  • 70. Load balancing 0 20 0 10 0 cost: 20ms cost: 10ms cost: 10ms
  • 71. cost: 18ms Load balancing 0 20 0 10 0 20ms cost: 10ms cost: 10ms
  • 72. The “Simplified” Full Picture Stats Timeout Draining Load Balancer Monitor Stats Failure accrual Timeout Conn. Pool Expiration Dispatcher ServiceFactory Service
  • 73. Finagle’s Architecture Experience from writing “large scale” software ! Independent modules Simple contracts Powerful combinators
  • 74. Conclusion • Finagle is a library that lets you treat RPC as functions • Finagle is itself composed of independent functions • Very widely used at Twitter, Foursquare, Tumblr, Pinterest, SoundCloud… • Protocol agnostic (thrift, http, redis, mysql…) Github: github.com/twitter/finagle “Your server as a Function” http://monkey.org/~marius/ funsrv.pdf