A Beginner's Guide to Redis

Imagine that we have a small eCommerce website in Rails and we use MySQL to store data for our products, comments, and users. We want to know how many views does every product get.
However, this is something that will change frequently and will need to be retrieved easily. Our team lead suggests using Redis so we start investigating.

What is Redis?

Redis (REmote DIctionary Server) is a super-fast open-source no-SQL key value store; to put it more precisely it is a data structure server. So will that replace your main DB? It can if you want to, but in my experience Redis shines at optimizing your application's performance.

When do we use it?

  • Caching: It is fast and persistent. This makes it a perfect candidate for caching especially when you start hitting the limits of a normal relational DB.

  • Queues: Given that Redis has its own list and sorted list internal data structures it makes a perfect queue.

  • Counters: Being persistent and having atomic commands make it a perfect fit for this usage.

Install Redis

  • Now that this is pretty straight forward we decided to do it separately. Though you can check Redis main quick start.

  • Now run redis-server to start it.

Some basic commands we need

  • SET key value: This sets the value of a certain key SET foo bar

  • GET key: This returns the value of a certain key GET foo -> bar

  • INCRBY key: Will increment the count of the given key. If it wasn't previously set, it will automatically be 0 then incremented. GET key -> nil INCRBY key GET key -> 1

Adding Redis to Rails

  • Add Redis to your gem file. gem 'redis'

  • Now run bundle install.

  • Now let's initialize Redis client when the app is initialized.

# config/initlializers/redis.rb
$redis = Redis.new(:host => 'localhost', :port => 6379)

Now we are ready to start.

Basic counter

Assume that you have products and you want to keep track how many views each product will have. This means that we will need a unique counter for each product. To assure this we can use the product id as the key. The problem with that would be if we want to create counters for another class. Hence, it is always better to add a namespace before an id. By doing that, we will have something like product:id as our key.

We will need to define 2 methods:

  • a method to get the number of views for a certain product.

  • a method to increment the number of views for a certain product.

Given that both are concerned only with products, it is best to add them in the product model.

# models/product_view.rb
class Product  
  def views
    $redis.get("product:#{id}") # this is equivalent to 'GET product:1'
  end

  def viewed!
    $redis.incby("product:#{id}") # this is equivalent to 'INC product:1'
  end
end  

Now let's start using them!

Currently, all that we do in the products#show is load the product. Let's start using the methods we've defined.

# controllers/products_controller.rb
def show  
  # assuming you load the @product in prepare_product
  @product.viewed!
end  

By this whenever someone loads the products#show the views will be incremented.

Now that we are done with the saving part we can add the count of views to the products#show view.

<h6>  
  Views:
  <span class="badge">
    <%= @product.views %>
  </span>
</h6>  

Conclusion

So we basically just did a quick intro to Redis by getting hands on with a simple example on counting the number of times a certain product is viewed. You can check out a lot more info and advanced topics on Redis on the official website here.

I hope you have found this blog post useful, and feel free to comment with any questions you may have.