artsy / garner

A set of Rack middleware and cache helpers that implement various caching strategies.
MIT License
344 stars 24 forks source link

garnered_find slower than find? #88

Open joeyAghion opened 9 years ago

joeyAghion commented 9 years ago

I encountered this surprise in our own application, and was able to reproduce it from a checkout of garner with the minimal models used by specs:

$ GARNER_MEMCACHE_SERVER=localhost bundle exec irb -I lib/
irb(main):001:0> require 'rspec'
=> true
irb(main):002:0> require './spec/support/cache'
=> true
irb(main):003:0> require './spec/support/mongoid'
=> true
irb(main):004:0> Monger.delete_all
=> 100
irb(main):005:0> (1..100).each { |i| Monger.create!(name: "monger ##{i}") }
=> 1..100
irb(main):006:0> ids = Monger.pluck(:_id); ids.size
=> 100
irb(main):007:0> n = 100
=> 100
irb(main):008:0> Benchmark.bm(15) do |x|
irb(main):009:1*   x.report('find') { n.times { ids.each{|id| Monger.find(id) } } }
irb(main):010:1>   x.report('garnered_find') { n.times { ids.each{|id| Monger.garnered_find(id) } } }
irb(main):011:1> end
                      user     system      total        real
find              4.210000   0.440000   4.650000 (  5.451388)
garnered_find     8.770000   0.910000   9.680000 ( 11.849314)

It's possible that this set-up isn't configuring the cache optimally, but I'd expect this to be sufficient to see cache hits and the library's benefits. What am I doing wrong?

dblock commented 9 years ago

I don't think you're doing anything wrong. In this benchmark you're taking a 0 latency local scenario in which cost of network is 0, cost inside a database lookup vs. memcached lookup is a memory read, ie. identical, but overall Garner cost is higher because Garner does two lookups in memcached. Realistically your roundtrip with MongoDB should be significantly slower than two roundtrips to Memcached, but I would prove that with a production system under load - it's possible that it's not the case for something with high throughput.

joeyAghion commented 9 years ago

I would agree, except that I initially investigated this because of similar results from our production system (with additional network latency, presumably). I didn't trust those results because there were so many other variables possibly impacting them.

dblock commented 9 years ago

I do think MongoDB is extremely fast, all in-memory, etc., so I am not so surprised - the assumption that memcached is somehow faster for a simple lookup probably no longer stands. I would bulk replace all garnered finds with find and see whether that has any negative impact at all.

mzikherman commented 9 years ago

I've already done that on some endpoints that I'd been chipping away at performance with, due to some benchmark tests. I'll monitor those for a bit.