TL;DR Redis the AK-47 of databases

AK-47 image from wikipedia

Easy

Installation was super easy, on a mac:

brew install redis

Starting it up was just as easy:

redis-server /usr/local/etc/redis.conf

Using it?

% redis-cli
redis> set this.is.a.key "this is a value"
OK
redis> get this.is.a.key
"this is a value"

Redis also supports more complex data stuctures, but the idea is the same: you set some state to a name. No tables, no schema, no JSON, no map nor reduce. If you don’t get the juxt of this, then please take out your safety pencil and a circle of paper.

Simple

The protocol is machine & human readable. Don’t believe me?

% nc localhost 6379
get this.is.a.key # i typed this
$15               # redis says 15 characters are coming
this is a value   # redis sent 15 characters

The stock config file has on the order of 30 options, 25 uncommented active ones:

% grep -v '^#\|^$' /usr/local/etc/redis.conf
daemonize no
pidfile /usr/local/var/run/redis.pid
port 6379
timeout 300
loglevel verbose
logfile stdout
databases 16
save 900 1
save 300 10
save 60 10000
rdbcompression yes
dbfilename dump.rdb
dir /usr/local/var/db/redis/
appendonly no
appendfsync everysec
vm-enabled no
vm-swap-file /tmp/redis.swap
vm-max-memory 0
vm-page-size 32
vm-pages 134217728
vm-max-threads 4
glueoutputbuf yes
hash-max-zipmap-entries 64
hash-max-zipmap-value 512
activerehashing yes

It’s not that hard to guess what most of these are, but why guess when stock config is so well documented? It seems like the useful 80% of what you can know about the server side is documented there.

There is one authentication method: a password, off by default. If you specify a password in the config file then its simple:

redis> AUTH thepasswordintheconfigfile
OK

Now you can use the database, just use it, seriously. But be warned:

Note: because of the high performance nature of Redis, it is possible to try a lot of passwords in parallel in very short time, so make sure to generate a strong and very long password so that this attack is infeasible.

Backup? Use cp, as in /bin/cp …

% cp /usr/local/var/db/redis/dump.rdb /some/place/to/backup.rdb

Need some more dials, knobs, domain specific configuration languages, obfuscated enterprise grade protocols, ldap authentication, Photoshop integration or some sort of bean? Call up Larry Ellison, he’ll be glad to provide you with an aspect certified enterprise-oriented solution.

Powerful

Does it do transactions? Yes

redis> MULTI
redis> ...
redis> ...
redis> ...
redis> EXEC

The above code will get exclusive rights to the dataset. All other clients' commands will queue up. EDIT: this explanation is wrong, commands are queued, clients are not locked, please see the the docs

But Redis also has optimistic locks that don’t exclusively lock the entire dataset.

redis> WATCH mykey
redis> ...
redis> ...
redis> ...
redis> EXEC

if mykey is modified by another connection any time between the WATCH and EXEC commands, a rollback will result. The important part is that if no one is stepping on anyone else’s toes (data) then there is no queueing. If by chance you do step on someone’s toe, just back off for second and try again.

Pub/Sub

Pub/Sub is a unique and useful feature. A client publishes messages on a channel and zero or more subscribers receive that message. Its kinda like IRC.

# client 1
redis> SUBSCRIBE the.chan
Reading messages... (press Ctrl-c to quit)
1. "subscribe"
2. "the.chan"
3. (integer) 1

# client 2
redis> PUBLISH the.chan "hey guise whats cookin"

# client 1
redis> SUBSCRIBE the.chan
1. "message"
2. "the.chan"
3. "hey guise whats cookin"

Not enough XML for you? Go fsync yourself.

No Surprises

Does it scale? Yep, via replication. One master to many slaves. The slaves ask the master for new data, then everyone has the same data.

The entire dataset is in RAM. This makes things as fast as well, RAM, always. What about when the power goes out? It’s periodically saved to disk.

No virtual memory by default. Everything really is in RAM. If you don’t have enough RAM then turn virtual memory support on.

What about between saves? A log (since the last save) is kept on disk. It can be replayed to recover unsaved data.

Is that log fsynced? Every second by default, but you can configure it.

There are potential windows of time when data can be lost. The important thing is that those windows are known and can be considered instead of surprising you.

AK-47 Appeal

Why Redis appeal to me? Pareto’s principle could be applied: When using software, one could argue that 80% of the time is spent using 20% of features. Redis seems to implement the vital few features very well.

According to AK-47 legend, assault rifles were not popular because of their tendency to consume large amounts of ammo. The Soviets embraced the idea and simply supplied their troops with more ammo. Kinda like Redis and RAM.

There are more and precise guns out there, but you can’t pack them with wet dirt and expect them to fire unconditionally. There are more sophisticated designs, but factories cannot crank them out anywhere in the world, 2nd world or 3rd world. This is because the design of the AK-47 is, for lack of a better term, simple. There is inherent robustness in simplicity. You can shoot an AK-47 if you have two things: an AK-47 and ammo. You can host or replicate a Redis dataset on any machine that has two things: Redis and enough RAM.

In the spirit of full disclosure, I’m a newb to Redis. My knowledge is basically the contents of this post (at the time of writing). I don’t use it in production (yet). Likewise I’m no expert in AK-47s (I’ve never even fired one) or guns in general. I’m aware via notoriety alone.

See also: Unix – The Hole Hawg, by Neal Stephenson