-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve page and partial caching across the site #32
Comments
Was closed accidentally by upstream calagator merge w/ a "fixes ##" mention. |
Additional details / thoughts from Daniel Feb 27th:
As things stand right now, the calendar can sometimes take a few seconds to regenerate when it sees changes. If the server is getting a hit or two a second (we're getting less than a hit a minute) and an event changes, multiple web requests will all see that the cache is out of date, start generating a new cached page and slow the machine down enough that it'll take 10+ more seconds to generate the new cached page...at which time we'll get another 10 requests trying to generate the page and easily overload the server. So yeah, for our existing traffic and scaling more slowly, we're okay for now; for any sudden influx, it could easily become problematic. (note: we could probably set some value in memcache that says we're currently generating a calendar before we start and just have the other requests wait instead of starting to regenerate the calendar again on their own...there are a lot of different possibilities, just nothing has been done yet) |
Good chatting Lindsey, here are some notes on creating pseudo-namespaces in memcached. The reason for "memcached" (with the "d") is that it supports pieces of the protocol that older clients like memcache-client didn't. Since you're on Heroku you probably have a client that supports this, even if the Calagator devs didn't take adantage of the better protocol support, https://github.com/mperham/dalli/wiki/Heroku-Configuration. Here's a simple explanation of how things moved on since "memcache": http://stackoverflow.com/a/1442747/982920 Here's a good strategy for setting prefixes. You can make them site/city specific & then separate by object type (event org, etc) so the cache isn't monolithic:
|
Mike also suggested:
|
Tim Connor comments: |
As caching strategies go the Russian Doll approach you can build with fragment caching is great, but I don't think your app is ready for it. However: (2) Fragment caching defaults to disk storage but it's recommended to back it with memcached or redis to get a lot more speed from it. Since you currently only use memcached you can store things there ... but that's also where you cache flush cascade problems happen. So you either use slower disk cache or lose your fragments when memcache dumps like it does now & then it takes even longer to catch up while the server rebuilds both the memcache & the fragment caches. (3) You could introduce a shared Redis instance to store fragments for one or more servers, which would prevent the overlapping cache expirations. This would actually get you pretty far down the road, but you'll still have the memcache cache shared between all the sites. Essentially that will be a broken cache strategy that's covered for a while by a better cache. But as you grow to new cities you'll either exhaust how far fragments get you & need memcache again ... and it will be a lot bigger problem to solve then. Ignoring the doom & gloom: I'll recommend fixing memcache before you add another cache. I prefer fixing something that's not right rather than patching over it & seeing how long it stays covered. |
From Jesse Cooke: Suggestions:
Where exactly is the bottleneck? Is it in the rendering of the view? Are you rendering too much at once? Do you know exactly what numbers aren't good, and how you'd like to improve them? If not, you need to know the answers to those questions. Performance tuning is all about measurement. There looks to be a lot of stuff going on in the _calendar.html.haml partial. You know, one thing you could do is pre-populate the calendar structure, and then dynamically add events to the days as needed. I mean, Feb 2014 is never going to change, and you'll know exactly what April 2014 is going to look like. If the generation of that HTML is significant, that could be a good place to cache. Reminds me of what an old Smalltalker told me once about date objects... once you create it, you can keep it around forever. There's no need to recalculate a date because it's a fact & it'll never change. |
Zack Hobson: |
That's an interesting point about the calendar populating dynamically. I Sucker_punch may be an interesting option if we purposefully dump the cache |
Yes, we have New Relic. Sort of. It was set-up for our staging site pre-Beta and pre-transition to Heroku. So... I think the below metrics are for a site that isn't representative of our live version, and only a fraction of its traffic, but presumably uses the same bones? If all of that is true, then it should still provide some insight. And.. we're going to need to sync our live sites. |
I added basic key-based russian doll style fragment caching was added in commit 496ea84. We didn't need to upgrade to rails 4, as rails makes a @mbjion, if there's anything in this ticket that you think we should continue to pursue to improve performance, please feel free to open up a new ticket to track it. |
I believe this solution introduced a bug. #81 When an existing event is edited, upon clicking "Update", it shows up perfectly. Social sharing buttons and maps are formatted properly. But as soon as you 'refresh', the Google Map & "Share It" buttons disappear. Seems it's related to caching. |
This is a fairly generic ticket and is meant to be "take a stab at some of the low hanging fruit". The extent of our caching for dynamic content is as follows:
app/views/events/index.html.haml
). If anything changes for any events or venue, for any reason, all caching is cleared for the entire site (see app/observers/cache_observer.rb).That's it.
Also, any changes to any events or venues on any site clears the cache for all sites. Not scalable.
Scope of Ticket
http://37signals.com/svn/posts/3113-how-key-based-cache-expiration-works (also has 67 comments, worth reading)
Event#updated_at
timestamp. You would, however, first have to tie the model objects together so they update the event's timestamp as necessary. The site has a fairly high read vs. edit ratio so slowing down write performance is not a concern.The text was updated successfully, but these errors were encountered: