redis官方教程 KEY-VALUE DB 教程
原文地址:http://redis.io/topics/twitter-clone
A case study: Design and implementation of a simple Twitter clone using only the Redis key-value store as database and PHP
In this article I'll explain the design and the implementation of a simple clone of Twitter written using PHP and Redis as only database. The programming community uses to look at key-value stores like special databases that can't be used as drop in replacement for a relational database for the development of web applications. This article will try to prove the contrary.
Our Twitter clone, called Retwis, is structurally simple, has very good performance, and can be distributed among N web servers and M Redis servers with very little effort. You can find the source code here.
We use PHP for the example since it can be read by everybody. The same (or... much better) results can be obtained using Ruby, Python, Erlang, and so on.
Note: Retwis-RB is a port of Retwis to Ruby and Sinatra written by Daniel Lucraft! With full source code included of course, the Git repository is linked in the footer of the web page. The rest of this article targets PHP, but Ruby programmers can also check the other source code, it conceptually very similar.
Note: Retwis-J is a port of Retwis to Java, using the Spring Data Framework, written by Costin Leau. The source code can be found on GitHub and there is comprehensive documentation available at springsource.org.
Key-value stores basics
The essence of a key-value store is the ability to store some data, called value, inside a key. This data can later be retrieved only if we know the exact key used to store it. There is no way to search something by value. In a sense, it is like a very large hash/dictionary, but it is persistent, i.e. when your application ends, the data doesn't go away. So for example I can use the command SET to store the value bar at key foo:
SET foo bar
Redis will store our data permanently, so we can later ask for "What is the value stored at key foo?" and Redis will reply with bar:
GET foo => bar
Other common operations provided by key-value stores are DEL used to delete a given key, and the associated value, SET-if-not-exists (called SETNX on Redis) that sets a key only if it does not already exist, and INCR that is able to atomically increment a number stored at a given key:
SET foo 10
INCR foo => 11
INCR foo => 12
INCR foo => 13
Atomic operations
So far it should be pretty simple, but there is something special about INCR. Think about this, why to provide such an operation if we can do it ourselves with a bit of code? After all it is as simple as:
x = GET foo
x = x + 1
SET foo x
The problem is that doing the increment this way will work as long as there is only a client working with the value x at a time. See what happens if two computers are accessing this data at the same time:
x = GET foo (yields 10)
y = GET foo (yields 10)
x = x + 1 (x is now 11)
y = y + 1 (y is now 11)
SET foo x (foo is now 11)
SET foo y (foo is now 11)
Something is wrong with that! We incremented the value two times, but instead to go from 10 to 12 our key holds 11. This is because the INCR operation done with GET / increment / SET is not an atomic operation. Instead the INCR provided by Redis, Memcached, ..., are atomic implementations, the server will take care to protect the get-increment-set for all the time needed to complete in order to prevent simultaneous accesses.
What makes Redis different from other key-value stores is that it provides more operations similar to INCR that can be used together to model complex problems. This is why you can use Redis to write whole web applications without using an SQL database and without going crazy.
Beyond key-value stores
In this section we will see what Redis features we need to build