Using Multi-Node Elasticache with Rails

When using multi-node Elasticache memcached with Rails, it's critically important to get your setup correct.

If you don't, your application will connect to memcached nodes at random (!!!). Resulting in low cache hit rates.

How to setup

Conveniently, there is a gem for this, dalli-elasticache.

gem "dalli-elasticache"
Gemfile

Using the gem for configuration happens all inside of your config/environment files. Here is an example setup for production in production.rb.

  # Grabs all available memcached nodes from AWS and configures them.
  memcached_url = Rails.application.credentials&.memcached&.fetch(:url)
  if memcached_url && !defined?(Rails::Console)
    # memcached_url isn't available when building production assets (in container build). So we skip it.
    elasticache = Dalli::ElastiCache.new(memcached_url)
    config.cache_store = :mem_cache_store, elasticache.servers, { pool_size: ENV.fetch("RAILS_MAX_THREADS") { 4 }, pool_timeout: 5 }
  end
config/environments/production.rb

Notice here that the url is set in our Rails credentials. We only establish the connection if it is present and we are not in a Rails console.

The dalli-elasticache gem retrieves the address for each node and passes them to Dalli. When your application is running, Rails/Dalli will correctly route memcached requests to the same nodes based on the key being set or retrieved.

💡
You cannot (without effort) access your Elasticache instance from outside of the AWS network.

That's all

Hopefully this saved you some time. To learn more, take a look at the dalli-elasticache gem.