BenMorganIO
BenMorganIO

Reputation: 2046

Redis and Rails Error on Production: ActionView::Template::Error (ERR invalid DB index)

When I am on development, I load up the page and it works fine. No errors. I load up the page on staging and I get a 404. What I am trying to do is cache a portion of a page to increase performance.

This is the error I found in papertrail:

Processing by InstructorsController#index as HTML 
app/web.1:  Read fragment views/staging.example.com/instructors?expires_in=86400/d373c7125bca0fa7485862a5e9f72b99 (10.2ms) 
app/web.1:  Completed 500 Internal Server Error in 238ms 
app/web.1:  cache: [GET /instructors] miss 
app/web.1:  Started GET "/instructors" for 12.34.567.89 at 2014-05-18 23:46:47 +0000 
app/web.1:    Cache digest for app/views/instructors/index.html.erb: d373c7125bca0fa7485862a5e9f72b99 
app/web.1:    Rendered instructors/index.html.erb within layouts/application (14.2ms) 
app/web.1:  ActionView::Template::Error (ERR invalid DB index): 
app/web.1:      1: <% cache expires_in: 1.day do %> 
app/web.1:      2:   <% set_meta_tags keywords: @instructors.keywords %> 
app/web.1:      3:  
app/web.1:      4:   <section id="instructors" class="panel panel-default"> 
app/web.1:    app/views/instructors/index.html.erb:1:in `_app_views_instructors_index_html_erb__1873438065652455666_70314031777140' 
heroku/router:  at=info method=GET path=/instructors host=staging.example.com request_id=c30153a3-bf5d-4e87-ab4f-45e1148db83b fwd="12.34.567.89" dyno=web.1 connect=1ms service=260ms status=500 bytes=1789

Now you know what "appears" to have gone wrong. To be give you some more reading, here's what New Relic has for us:

Error message
ActionView::Template::Error: ERR invalid DB index

Stack trace
…bundle/ruby/2.1.0/gems/redis-3.0.7/lib/redis/client.rb:  97:in `call'
…bundle/ruby/2.1.0/gems/redis-3.0.7/lib/redis/client.rb:  81:in `block in connect'
…bundle/ruby/2.1.0/gems/redis-3.0.7/lib/redis/client.rb: 257:in `with_reconnect'
…bundle/ruby/2.1.0/gems/redis-3.0.7/lib/redis/client.rb:  78:in `connect'
…bundle/ruby/2.1.0/gems/redis-3.0.7/lib/redis/client.rb: 304:in `ensure_connected'
…bundle/ruby/2.1.0/gems/redis-3.0.7/lib/redis/client.rb: 191:in `block in process'
…bundle/ruby/2.1.0/gems/redis-3.0.7/lib/redis/client.rb: 270:in `logging'
…bundle/ruby/2.1.0/gems/redis-3.0.7/lib/redis/client.rb: 190:in `process'
…bundle/ruby/2.1.0/gems/redis-3.0.7/lib/redis/client.rb:  96:in `call'
…vendor/bundle/ruby/2.1.0/gems/redis-3.0.7/lib/redis.rb: 784:in `block in get'
…vendor/bundle/ruby/2.1.0/gems/redis-3.0.7/lib/redis.rb:  37:in `block in synchronize'
       /app/vendor/ruby-2.1.1/lib/ruby/2.1.0/monitor.rb: 211:in `mon_synchronize'
…vendor/bundle/ruby/2.1.0/gems/redis-3.0.7/lib/redis.rb:  37:in `synchronize'
…vendor/bundle/ruby/2.1.0/gems/redis-3.0.7/lib/redis.rb: 783:in `get'
….0/gems/redis-store-1.1.4/lib/redis/store/interface.rb:   5:in `get'
…/gems/redis-store-1.1.4/lib/redis/store/marshalling.rb:  17:in `get'

Now that you know what's gone wrong, here's all the redis information:

# redis.conf
daemonize no
databases 128

# config/environments/production.rb
config.action_controller.perform_caching = true
config.cache_store                       = :redis_store, "#{ENV['REDISCLOUD_URL']}/1"
config.action_dispatch.rack_cache        = {
  metastore:   "#{ENV['REDISCLOUD_URL']}/1/metastore",
  entitystore: "#{ENV['REDISCLOUD_URL']}/1/entitystore"
}

# config.ru
require 'rack'
require 'rack/cache'
require 'redis-rack-cache'

use Rack::Cache,
    metastore:   "#{ENV['REDISCLOUD_URL']}/0/metastore",
    entitystore: "#{ENV['REDISCLOUD_URL']}/0/entitystore"

# Gemfile
source 'https://rubygems.org'
ruby '2.1.2'

gem 'rails', '4.1.1'
gem 'mysql2'
gem 'thin'
gem 'redis-store'
gem 'redis-rails'
gem 'redis-rack-cache'
gem 'redis-namespace'

# app/controllers/instructors_controller.rb
class InstructorsController < ApplicationController
  def index
    @instructors = Instructor.all
  end

  def show
    @instructor = Instructor.find(params[:id])
  end
end

# db/schema.rb
# there are no indexes to be found for the instructors.
create_table "instructors", force: true do |t|
  t.string   "first_name"
  t.string   "last_name"
  t.string   "handle"
  t.string   "google_plus"
  t.text     "bio"
  t.string   "avatar"
  t.datetime "created_at"
  t.datetime "updated_at"
end

# Procfile
web: bundle exec thin start -p $PORT
redis: redis-server redis.conf

Please keep in mind that I've kept it short for brevity to allow you to skim through fast. I'm almost always online, so leave a comment if you need more info. I don't mind.

Upvotes: 1

Views: 1380

Answers (1)

Itamar Haber
Itamar Haber

Reputation: 50082

If I'm not mistaken, it looks like your production environment uses the shared /1 database, which - while not syntactically wrong - is not supported by Redis Cloud. Instead, you should only use the /0 database as all of Redis Cloud's databases are dedicated - for more information on the topic see http://redislabs.com/blog/benchmark-shared-vs-dedicated-redis-instances

Upvotes: 4

Related Questions