Top Banner
PATELLA MEMOIZATION INTO MEMCACHED DONE IN RESQUE JEFF DWYER PATIENTSLIKEME @JDWYAH
65

Patella railsconf 2012

Jan 15, 2015

Download

Technology

jdwyah

This talk will feature: memcache, resque, a bit of metaprogramming, a look at caching in the wild and code that fixes some usual problems, and a fairly epic SQL query with some nice Postgres features you should know about.
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Patella railsconf 2012

PATELLAMEMOIZATION INTO MEMCACHED DONE IN RESQUE

JEFF DWYER

PATIENTSLIKEME

@JDWYAH

Page 2: Patella railsconf 2012

TODAY

Engineers will never be successful if we are the brake on innovation.

Technique for innovating safely

Learn a bit about meta-programming

Page 3: Patella railsconf 2012

TODAY

Setup the problem

Sketch the solution

Nitty Gritty Details

Page 4: Patella railsconf 2012

TODAY

Setup the problem

Sketch the solution

Nitty Gritty Details

Page 5: Patella railsconf 2012

1) NIH PRESENTATION IN 4 WEEKS!

Integrate clinicaltrials.gov into our site

Search by trial type

Search by trial phase

Search by trial conditions mapped from Mesh to Meddra

Search by trial facility locations…

• Location search…

Page 6: Patella railsconf 2012
Page 7: Patella railsconf 2012

WE HAVE A CHOICE

Page 8: Patella railsconf 2012

WHAT IS RIGHT

PostGIS spatial database extensions for PostgreSQL

MongoDB built in support for two dimensional geospatial indexes

Page 9: Patella railsconf 2012

AND WHAT IS EASYsqrt(pow(69.1 * (clinical_trial_locations.lat - 40.948073),2) + pow(53.0 * (clinical_trial_locations.lng - -90.36871),2)) AS distance

Page 10: Patella railsconf 2012

CHOOSE THE EASY!

Page 11: Patella railsconf 2012

CHOOSE THE EASY!

Who knows if location is even important?

Who knows if this project is even important?

MongoDB requires dev setup, automated staging setup, production setup, monitoring.

Page 12: Patella railsconf 2012

BUT, OH GOD THE HUMANITY

<query plan pic>

Page 13: Patella railsconf 2012

BUT, OH GOD THE HUMANITY

<query plan pic>

Page 14: Patella railsconf 2012

2) PATIENT LIKE ME SEARCH

Page 15: Patella railsconf 2012

2) PATIENT LIKE ME SEARCH

Page 16: Patella railsconf 2012

PATIENT SEARCH RANKING

Very basic search

Plus very complex ordering

Not as many great solutions in this space

N^2 similarity matrix @ 100k patients about 4 TB

And did I mention it’s N^2?

Postgres is an amazingly viable solution.

Page 17: Patella railsconf 2012

ELEGANT CODE…

Page 18: Patella railsconf 2012

LOVELY SQL…

Page 19: Patella railsconf 2012

BUT IT’S JUST THIS SIDE OF ‘REAL-TIME’

One second queries just don’t fly.

And oh, yeah 16 people hitting it at the same time would clobber the servers.

Page 20: Patella railsconf 2012

3) A FORWARD LOOKING TIME MACHINE

Maybe those were aberrations?

Crazy right?

Page 21: Patella railsconf 2012

A FORWARD LOOKING TIME MACHINE

Page 22: Patella railsconf 2012

AND HERE’S MY CEO PROMISING IT AT TED

Page 23: Patella railsconf 2012

A FORWARD LOOKING TIME MACHINE

Page 24: Patella railsconf 2012

STEPPING BACK

Conflict

• Relational data is most easily queried relationally. • Relational queries don’t necessarily scale and stay in the

millisecond range

• Denormalized queries & special solutions scale• But take longer to implement

• (note) This isn’t just SQL, I’m talking about anything slow

We want to experiment/fail fast

• But we don’t want…

Page 25: Patella railsconf 2012

DON’T WANT TO LET THIS:

Page 26: Patella railsconf 2012

TURN INTO:

Page 27: Patella railsconf 2012

TURN INTO: :-C

Page 28: Patella railsconf 2012

TURN INTO: :-C

Page 29: Patella railsconf 2012

TODAY

Setup the problem

Sketch the solution

Nitty Gritty Details

Page 30: Patella railsconf 2012

WHAT WE WANT

Trivially easy way for developers to declare that some methods are not to be run without adult supervision.

Consistent framework so that ops doesn’t need to be afraid of new, sometimes expensive experiments.

Page 31: Patella railsconf 2012

SOLUTION SPACE

Doing it right all the time

• Too slow and expensive• Slows innovation

Page 32: Patella railsconf 2012

SOLUTION SPACE

Memoization

• Brilliant• Functional Programming Nirvana• No cache-key shenanagins

• But also no expiry…

• There’s just one thing…• It only works in a single request

Page 33: Patella railsconf 2012

SOLUTION SPACE

Memcached

• Great• Simple to setup.

• Could be simpler. Handmade cache keys feels wrong.

• But it doesn’t solve our :-C problem.• The first request still slams the server.

• So you do some cache warming thing…• But this is a PITA again.

Page 34: Patella railsconf 2012

WHAT COULD MAKE THIS SIMPLER?

Remove one constraint.

A basic Rails.cache.fetch guarantees you a result

• But no performance guarantee

Flip that deal around.

• Guarantee performance• Don’t guarantee a result• It’s ok not to know the answer!

Page 35: Patella railsconf 2012

BUT IT NEEDS A NAME!

Page 36: Patella railsconf 2012
Page 37: Patella railsconf 2012

TECHNOLOGIES!

Memoization into Memcached with everything calculated in Resque.

Page 38: Patella railsconf 2012

TODAY

Setup the problem

Sketch the solution

Nitty Gritty Details

Page 39: Patella railsconf 2012

PATELLA DEVELOPER INTERFACE

Page 40: Patella railsconf 2012

SEND LATER

Super easy way to just do something later while in the same context.

Most workers are real boring.

Single worker for suffices for many background jobs.

Makes testing/development easier by bypassing Resque in configuration.

AR extension. Coordinates logging / monitoring.

Page 41: Patella railsconf 2012

SENDLATER

User.send_later :expensive, arg1, arag2

Page 42: Patella railsconf 2012

SENDLATER RESQUE WORKER

Page 43: Patella railsconf 2012

MEMOIZATION

SendLater gets things calculated in Resque, but that’s step 1.

We still need:

Memoization.

Stored in memcached.

Page 44: Patella railsconf 2012

THIS IS NOT A GOOD SLIDE

Page 45: Patella railsconf 2012

PATELLA RESULT

Page 46: Patella railsconf 2012

THE METHOD

Page 47: Patella railsconf 2012

WITH PATELLA

Page 48: Patella railsconf 2012

THE REPLACEMENT

Page 49: Patella railsconf 2012

THE ONE THAT DOES THE WORK

Page 50: Patella railsconf 2012

MAYBE IT’S BETTER NOW?

Page 51: Patella railsconf 2012

DOG PILE

Page 52: Patella railsconf 2012

THE REPLACEMENT

Page 53: Patella railsconf 2012

DOG PILE

Page 54: Patella railsconf 2012

LONG ARGUMENTS

Page 55: Patella railsconf 2012

LONG ARGUMENTS

Page 56: Patella railsconf 2012

LONG ARGUMENTS

Page 57: Patella railsconf 2012

SOFT EXPIRATION

Memcached is great, but it doesn’t tell you when something expires.

Our strategy was to add a ‘soft_expiry’

This gets stored along with the result.

Then recalculate if soft_expiry < now()

Page 58: Patella railsconf 2012

ABJALWAYS BE JSON

Beware putting not JSON in memcached

You really don’t want to know

Page 59: Patella railsconf 2012

META IS MAGIC

Page 60: Patella railsconf 2012

REAL LIFE

Page 61: Patella railsconf 2012

PRETTY BORING

Except that it works.

Round 1: Major Pain Points

Round 2: Magic Scaling Sprinkles

Super alpha gem here:

https://github.com/kbrock/patella

Alternative https://github.com/csquared/rack-worker

Very REST-ish, request based.

Page 62: Patella railsconf 2012

JOE@JOERODRIGUEZ

Page 63: Patella railsconf 2012

AMY@AMYNEWELL

Page 64: Patella railsconf 2012

KEENAN@KBROCK

Page 65: Patella railsconf 2012

WINFIELD@WPETERSON