What is Memcached?

David Morales
Jan 28 · 4 min read

Memcached is a free and open-source high-performance memory caching system. It’s typically used to cache database data, API calls or page rendering chunks in RAM to increase the application performance.

It can store data as little as a number, or as big as a finished HTML page.

The system is designed to be accessed through TCP so it can work in a separate server, and can also be distributed among several servers, summing up a big hash table to store data.

When running out of space, the older data is overwritten. So it must be treated as a transitory (not-persisted) cache, meaning that your data may not still be there.

Installation

If you’re using macOS, it’s very easy to install Memcached using Homebrew:

$ brew install memcached

Then you can start it using this command:

$ /usr/local/opt/memcached/bin/memcached

If you are using Linux, you can use your distribution’s package manager to install it easily.

Connecting

The default port is 11211. Let’s try to connect using Telnet:

$ telnet localhost 11211
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.

Great! The server is up. Now quit Telnet (using the quit command) and let’s install a Ruby gem to interact with the server more comfortably:

gem install dalli

Run a Ruby console (irb) and connect to the server using the default port:

require 'dalli'
cache = Dalli::Client.new('localhost')
=> #<Dalli::Client:0x007f999d867e80 @servers=["localhost"], @options={}, @ring=nil>

Basic storage

Let’s start playing with Memcached storing a string and then getting it:

cache.set 'greet', 'hello'
cache.get 'greet'
=> "hello"

As you see, set is used to set a value to a key, which will be overwritten if it already exists. get is used to get the key value.

Data can also be limited by some time in seconds:

cache.set 'greet', 'hello', 5
cache.get 'greet'
=> "hello"
sleep 5
cache.get 'greet'
=> nil

Multiple values can be get in a unique query using get_multi, resulting in a hash:

cache.set 'greet1', 'hello'
cache.set 'greet2', 'good morning'
cache.get_multi 'greet1', 'greet2'
=> {"greet1"=>"hello", "greet2"=>"good morning"}

Let’s free some memory by deleting those greetings:

cache.delete 'greet1'
cache.delete 'greet2'
cache.get_multi 'greet1', 'greet2'
=> {}

If you want to delete all keys, the flush operation is what you need:

cache.flush
=> [true]

Adding data

The set command overwrites the value if the key already exists:

cache.set 'greet', 'hello'
cache.get 'greet'
=> "hello"
cache.set 'greet', 'good morning'
cache.get 'greet'
=> "good morning"

To avoid this, the add command can be used instead, which will create the value if the key doesn’t exist:

# It doesn't overwrite an existing key (defined in the previous code block)
cache.add 'greet', 'good evening'
cache.get 'greet'
=> "good morning"

Replacing data

replace is used to replace data for an existing key:

cache.replace 'greet', 'hi there!'
cache.get 'greet'
=> "hi there!"

But it will do nothing if the key doesn’t exist:

cache.replace 'non existing greet', 'hi there!'
=> nil

Appending and prepending data

In order to append or prepend data, Dalli requires it to be previously set as raw:

cache.set 'greet', 'hello', 0, raw: true

Now we can append:

cache.append 'greet', '!'
cache.get 'greet'
=> "hello!"

And prepend:

cache.prepend 'greet', 'hey! '
cache.get 'greet'
=> "hey! hello!"

Increment and decrement data

Another useful case is to have a counter, so it can be incremented or decremented.

cache.set 'counter', 1, 0, raw: true
cache.incr 'counter'
=> 2
cache.incr 'counter', 2
=> 4
cache.decr 'counter'
=> 3
cache.decr 'counter', 3
=> 0

Check and set

Imagine having a value that can be updated by any concurrent client (trying to update it at the same time). Wouldn’t that be a problem? That’s a race condition that can be controlled using the cas operation, that checks if the value has been changed by other client before updating it.

It works like a set operation, but it requires a block:

cache.set 'config', 'foo'
cache.cas('config') { 'bar' }
cache.get 'config'
=> "bar"

Therefore, this is an atomic operation.

Conclusion

We have seen what’s Memcached and how it can be used directly using the Dalli gem. It may seem simple, but it can help a big web application to work faster like many important companies are doing, such as YouTube, Reddit, Facebook, Twitter, and Wikipedia.

Sometimes it’s essential to work with Memcached directly, for instance when developing a service with special needs. There are other times where the framework (Ruby on Rails for example) can store its cache out of the box in Memcached using a gem like Dalli.

The Startup

Get smarter at building your thing. Join The Startup’s +800K followers.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store