diff --git a/doc/BlpopCommand.html b/doc/BlpopCommand.html
index 9c64390af..7627ed717 100644
--- a/doc/BlpopCommand.html
+++ b/doc/BlpopCommand.html
@@ -16,7 +16,7 @@
ExpireCommand
@@ -28,12 +28,15 @@
#sidebar
GenericCommandsSidebar
1.1)=
+
Time complexity: O(1)Set a timeout on the specified key. After the timeout the key will beautomatically delete by the server. A key with an associated timeout issaid to be volatile in Redis terminology.
-
Voltile keys are stored on disk like the other keys, the timeout is persistenttoo like all the other aspects of the dataset. Saving a dataset containingthe dataset and stopping the server does not stop the flow of time as Redisregisters on disk when the key will no longer be available as Unix time, andnot the remaining seconds.
+
Voltile keys are stored on disk like the other keys, the timeout is persistenttoo like all the other aspects of the dataset. Saving a dataset containingexpires and stopping the server does not stop the flow of time as Redisstores on disk the time when the key will no longer be available as Unixtime, and not the remaining seconds.
EXPIREAT works exctly like EXPIRE but instead to get the number of secondsrepresenting the Time To Live of the key as a second argument (that is arelative way of specifing the TTL), it takes an absolute one in the form ofa UNIX timestamp (Number of seconds elapsed since 1 Gen 1970).
-
EXPIREAT was introduced in order to implement [Persistence append only saving mode] so that EXPIRE commands are automatically translated into EXPIREAT commands for the append only file. Of course EXPIREAT can alsoused by programmers that need a way to simply specify that a given key should expire at a given time in the future.
-
When the key is set to a new value using the SET command, the INCR commandor any other command that modify the value stored at key the timeout isremoved from the key and the key becomes non volatile.
-
Write operations like LPUSH, LSET and every other command that has theeffect of modifying the value stored at a volatile key have a special semantic:basically a volatile key is destroyed when it is target of a write operation.See for example the following usage pattern:
+
EXPIREAT was introduced in order to implement the Append Only File persistence modeso that EXPIRE commands are automatically translated into EXPIREAT commands for the append only file. Of course EXPIREAT can alsoused by programmers that need a way to simply specify that a given key should expire at a given time in the future.
+
Since Redis 2.1.3 you can update the value of the timeout of a key alreadyhaving an expire set. It is also possible to undo the expire at allturning the key into a normal key using the PERSIST command.
+
When the key is set to a new value using the SET command, or when a keyis destroied via DEL, the timeout is removed from the key.
+
IMPORTANT: Since Redis 2.1.3 or greater, there are no restrictions aboutthe operations you can perform against volatile keys, however older versionsof Redis, including the current stable version 2.0.0, has the followinglimitations:
+
Write operations like LPUSH, LSET and every other command that has theeffect of modifying the value stored at a volatile key have a special semantic:basically a volatile key is destroyed when it is target of a write operation.See for example the following usage pattern:
% ./redis-cli lpush mylist foobar /Users/antirez/hack/redis
OK
@@ -45,8 +48,13 @@ OK
OK
% ./redis-cli lrange mylist 0 -1 /Users/antirez/hack/redis
1. newelement
-
What happened here is that lpush against the key with a timeout set deletedthe key before to perform the operation. There is so a simple rule, writeoperations against volatile keys will destroy the key before to perform theoperation. Why Redis uses this behavior? In order to retain an importantproperty: a server that receives a given number of commands in the samesequence will end with the same dataset in memory. Without the delete-on-writesemantic what happens is that the state of the server depends on the timeof the commands to. This is not a desirable property in a distributed databasethat supports replication.
-
Trying to call EXPIRE against a key that already has an associated timeoutwill not change the timeout of the key, but will just return 0. If insteadthe key does not have a timeout associated the timeout will be set and EXPIREwill return 1.
+
What happened here is that LPUSH against the key with a timeout set deletedthe key before to perform the operation. There is so a simple rule, writeoperations against volatile keys will destroy the key before to perform theoperation. Why Redis uses this behavior? In order to retain an importantproperty: a server that receives a given number of commands in the samesequence will end with the same dataset in memory. Without the delete-on-writesemantic what happens is that the state of the server depends on the timethe commands were issued. This is not a desirable property in a distributed databasethat supports replication.
+
Even when the volatile key is not modified as part of a write operation, if it is
+read in a composite write operation (such as SINTERSTORE) it will be cleared at the
+start of the operation. This is done to avoid concurrency issues in replication.
+Imagine a key that is about to expire and the composite operation is run against it.
+On a slave node, this key might already be expired, which leaves you with a
+desync in your dataset.
Trying to call EXPIRE against a key that already has an associated timeoutwill not change the timeout of the key, but will just return 0. If insteadthe key does not have a timeout associated the timeout will be set and EXPIREwill return 1.
Redis does not constantly monitor keys that are going to be expired.Keys are expired simply when some client tries to access a key, andthe key is found to be timed out.
Of course this is not enough as there are expired keys that will neverbe accessed again. This keys should be expired anyway, so once everysecond Redis test a few keys at random among keys with an expire set.All the keys that are already expired are deleted from the keyspace.
Each time a fixed number of keys where tested (100 by default). So ifyou had a client setting keys with a very short expire faster than 100for second the memory continued to grow. When you stopped to insertnew keys the memory started to be freed, 100 keys every second in thebest conditions. Under a peak Redis continues to use more and more RAMeven if most keys are expired in each sweep.
@@ -56,8 +64,10 @@ OK
This means that at any given moment the maximum amount of keys alreadyexpired that are using memory is at max equal to max setting operations per second divided by 4.
Integer reply, specifically:
1: the timeout was set.
-0: the timeout was not set since the key already has an associated timeout, or the key does not exist.
-
+0: the timeout was not set since the key already has an associated timeout
+ (this may happen only in Redis versions < 2.1.3, Redis >= 2.1.3 will
+ happily update the timeout), or the key does not exist.
+
Ok let's start with the problem:
redis> set a 100
@@ -76,7 +86,8 @@ EXPIRE a 5
INCR a
Imagine a Redis version that does not implement the "Delete keys with an expire set on write operation" semantic.
-Running the above example with the 10 seconds pause will lead to 'a' being set to the value of 1, as it no longer exists when INCR is called 10 seconds later.
Instead if we drop the 10 seconds pause, the result is that 'a' is set to 101.
And in the practice timing changes! For instance the client may wait 10 seconds before INCR, but the sequence written in the Append Only File (and later replayed-back as fast as possible when Redis is restarted) will not have the pause. Even if we add a timestamp in the AOF, when the time difference is smaller than our timer resolution, we have a race condition.
The same happens with master-slave replication. Again, consider the example above: the client will use the same sequence of commands without the 10 seconds pause, but the replication link will slow down for a few seconds due to a network problem. Result? The master will contain 'a' set to 101, the slave 'a' set to 1.
The only way to avoid this but at the same time have reliable non time dependent timeouts on keys is to destroy volatile keys when a write operation is attempted against it.
After all Redis is one of the rare fully persistent databases that will give you EXPIRE. This comes to a cost :)
+Running the above example with the 10 seconds pause will lead to 'a' being set to the value of 1, as it no longer exists when INCR is called 10 seconds later.
Instead if we drop the 10 seconds pause, the result is that 'a' is set to 101.
And in the practice timing changes! For instance the client may wait 10 seconds before INCR, but the sequence written in the Append Only File (and later replayed-back as fast as possible when Redis is restarted) will not have the pause. Even if we add a timestamp in the AOF, when the time difference is smaller than our timer resolution, we have a race condition.
The same happens with master-slave replication. Again, consider the example above: the client will use the same sequence of commands without the 10 seconds pause, but the replication link will slow down for a few seconds due to a network problem. Result? The master will contain 'a' set to 101, the slave 'a' set to 1.
The only way to avoid this but at the same time have reliable non time dependent timeouts on keys is to destroy volatile keys when a write operation is attempted against it.
After all Redis is one of the rare fully persistent databases that will give you EXPIRE. This comes to a cost :)
Since Redis 2.1.3 there are no longer restrictions in the use you can do of write commands against volatile keys, still the replication and AOF file are guaranteed to be fully consistent.
In order to obtain a correct behavior without sacrificing consistency now when a key expires, a DEL operation is synthesized in both the AOF file and against all the attached slaves. This way the expiration process is centralized in the master instance, and there is no longer a chance of consistency errors.
However while the slaves while connected to a master will not expire keys independently, they'll still take the full state of the expires existing in the dataset, so when a slave is elected to a master it will be able to expire the keys independently, fully acting as a master.
+
diff --git a/doc/FAQ.html b/doc/FAQ.html
index 7c012b2cf..531fb708e 100644
--- a/doc/FAQ.html
+++ b/doc/FAQ.html
@@ -58,7 +58,7 @@ Redis for the same objects. This happens because when data is in
memory is full of pointers, reference counters and other metadata. Add
to this malloc fragmentation and need to return word-aligned chunks of
memory and you have a clear picture of what happens. So this means to
-have 10 times the I/O between memory and disk than otherwise needed.
- #sidebar
GenericCommandsSidebar
+ #sidebar
GenericCommandsSidebar 2.1.0)=
+
+
-
MULTI, EXEC and DISCARD commands are the fundation of Redis Transactions.A Redis Transaction allows to execute a group of Redis commands in a singlestep, with two important guarantees:
-
- All the commands in a transaction are serialized and executed sequentially. It can never happen that a request issued by another client is served in the middle of the execution of a Redis transaction. This guarantees that the commands are executed as a single atomic operation.
- Either all of the commands or none are processed. The EXEC command triggers the execution of all the commands in the transaction, so if a client loses the connection to the server in the context of a transaction before calling the MULTI command none of the operations are performed, instead if the EXEC command is called, all the operations are performed. An exception to this rule is when the Append Only File is enabled: every command that is part of a Redis transaction will log in the AOF as long as the operation is completed, so if the Redis server crashes or is killed by the system administrator in some hard way it is possible that only a partial number of operations are registered.
-
A Redis transaction is entered using the MULTI command. The command alwaysreplies with OK. At this point the user can issue multiple commands. Insteadto execute this commands Redis will "queue" them. All the commands areexecuted once EXEC is called.
-
Calling DISCARD instead will flush the transaction queue and will exitthe transaction.
-
The following is an example using the Ruby client:
+MULTI, EXEC, DISCARD and WATCH commands are the fundation of Redis Transactions.
+A Redis Transaction allows the execution of a group of Redis commands in a single
+step, with two important guarantees:
- All the commands in a transaction are serialized and executed sequentially. It can never happen that a request issued by another client is served in the middle of the execution of a Redis transaction. This guarantees that the commands are executed as a single atomic operation.
- Either all of the commands or none are processed. The EXEC command triggers the execution of all the commands in the transaction, so if a client loses the connection to the server in the context of a transaction before calling the MULTI command none of the operations are performed, instead if the EXEC command is called, all the operations are performed. An exception to this rule is when the Append Only File is enabled: every command that is part of a Redis transaction will log in the AOF as long as the operation is completed, so if the Redis server crashes or is killed by the system administrator in some hard way it is possible that only a partial number of operations are registered.
+Since Redis 2.1.0, it's also possible to add a further guarantee to the above two, in the form of optimistic locking of a set of keys in a way very similar to a CAS (check and set) operation. This is documented later in this manual page.
A Redis transaction is entered using the MULTI command. The command always
+replies with OK. At this point the user can issue multiple commands. Instead
+to execute this commands Redis will "queue" them. All the commands are
+executed once EXEC is called.
Calling DISCARD instead will flush the transaction queue and will exit
+the transaction.
The following is an example using the Ruby client:
+
?> r.multi
=> "OK"
>> r.incr "foo"
@@ -46,9 +52,14 @@
>> r.exec
=> [1, 1, 2]
-
As it is possible to see from the session above, MULTI returns an "array" ofreplies, where every element is the reply of a single command in thetransaction, in the same order the commands were queued.
-
When a Redis connection is in the context of a MULTI request, all the commandswill reply with a simple string "QUEUED" if they are correct from thepoint of view of the syntax and arity (number of arguments) of the commaand.Some command is still allowed to fail during execution time.
-
This is more clear if at protocol level: in the following example one commandwill fail when executed even if the syntax is right:
+As it is possible to see from the session above, MULTI returns an "array" of
+replies, where every element is the reply of a single command in the
+transaction, in the same order the commands were queued.
When a Redis connection is in the context of a MULTI request, all the commands
+will reply with a simple string "QUEUED" if they are correct from the
+point of view of the syntax and arity (number of arguments) of the commaand.
+Some command is still allowed to fail during execution time.
This is more clear if at protocol level: in the following example one command
+will fail when executed even if the syntax is right:
+
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
@@ -64,16 +75,21 @@ EXEC
+OK
-ERR Operation against a key holding the wrong kind of value
-MULTI returned a two elements bulk reply in witch one of this is a +OKcode and one is a -ERR reply. It's up to the client lib to find a sensibleway to provide the error to the user.
-IMPORTANT: even when a command will raise an error, all the other commandsin the queue will be processed. Redis will NOT stop the processing ofcommands once an error is found.
-Another example, again using the write protocol with telnet, shows howsyntax errors are reported ASAP instead:
+MULTI returned a two elements bulk reply in witch one of this is a +OK
+code and one is a -ERR reply. It's up to the client lib to find a sensible
+way to provide the error to the user.
IMPORTANT: even when a command will raise an error, all the other commandsin the queue will be processed. Redis will NOT stop the processing ofcommands once an error is found.
+Another example, again using the write protocol with telnet, shows how
+syntax errors are reported ASAP instead:
+
MULTI
+OK
INCR a b c
-ERR wrong number of arguments for 'incr' command
-This time due to the syntax error the "bad" INCR command is not queuedat all.
-DISCARD can be used in order to abort a transaction. No command will beexecuted, and the state of the client is again the normal one, outsideof a transaction. Example using the Ruby client:
+This time due to the syntax error the "bad" INCR command is not queued
+at all.DISCARD can be used in order to abort a transaction. No command will be
+executed, and the state of the client is again the normal one, outside
+of a transaction. Example using the Ruby client:
?> r.set("foo",1)
=> true
>> r.multi
@@ -84,9 +100,64 @@ INCR a b c
=> "OK"
>> r.get("foo")
=> "1"
-
Multi bulk reply, specifically:
-The result of a MULTI/EXEC command is a multi bulk reply where every element is the return value of every command in the atomic transaction.
+
WATCH is used in order to provide a CAS (Check and Set) behavior to
+Redis Transactions.
WATCHed keys are monitored in order to detect changes against this keys.
+If at least a watched key will be modified before the EXEC call, the
+whole transaction will abort, and EXEC will return a nil object
+(A Null Multi Bulk reply) to notify that the transaction failed.
For example imagine we have the need to atomically increment the value
+of a key by 1 (I know we have INCR, let's suppose we don't have it).
The first try may be the following:
+
+val = GET mykey
+val = val + 1
+SET mykey $val
+This will work reliably only if we have a single client performing the operation in a given time.
+If multiple clients will try to increment the key about at the same time
+there will be a race condition. For instance client A and B will read the
+old value, for instance, 10. The value will be incremented to 11 by both
+the clients, and finally SET as the value of the key. So the final value
+will be "11" instead of "12".
Thanks to WATCH we are able to model the problem very well:
+
+WATCH mykey
+val = GET mykey
+val = val + 1
+MULTI
+SET mykey $val
+EXEC
+
+Using the above code, if there are race conditions and another client
+modified the result of val in the time between our call to WATCH and
+our call to EXEC, the transaction will fail.
We'll have just to re-iterate the operation hoping this time we'll not get
+a new race. This form of locking is called optimistic locking and is
+a very powerful form of locking as in many problems there are multiple
+clients accessing a much bigger number of keys, so it's very unlikely that
+there are collisions: usually operations don't need to be performed
+multiple times.So what is WATCH really about? It is a command that will make the EXEC
+conditional: we are asking Redis to perform the transaction only if no
+other client modified any of the WATCHed keys. Otherwise the transaction is not
+entered at all. (Note that if you WATCH a volatile key and Redis expires the key after you WATCHed it, EXEC will still work. More.)
WATCH can be called multiple times. Simply all the WATCH calls will
+have the effects to watch for changes starting from the call, up to the
+moment EXEC is called.
When EXEC is called, either if it will fail or succeed, all keys are
+UNWATCHed. Also when a client connection is closed, everything gets
+UNWATCHed.
It is also possible to use the UNWATCH command (without arguments) in order
+to flush all the watched keys. Sometimes this is useful as we
+optimistically lock a few keys, since possibly we need to perform a transaction
+to alter those keys, but after reading the current content of the keys
+we don't want to proceed. When this happens we just call UNWATCH so that
+the connection can already be used freely for new transactions.A good example to illustrate how WATCH can be used to create new atomic
+operations otherwise not supported by Redis is to implement ZPOP, that is
+a command that pops the element with the lower score from a sorted set
+in an atomic way. This is the simplest implementation:
+
+WATCH zset
+ele = ZRANGE zset 0 0
+MULTI
+ZREM zset ele
+EXEC
+
+If EXEC fails (returns a nil value) we just re-iterate the operation.Multi bulk reply, specifically:
+The result of a MULTI/EXEC command is a multi bulk reply where every element is the return value of every command in the atomic transaction.
+
If a MULTI/EXEC transaction is aborted because of WATCH detected modified keys, a Null Multi Bulk reply is returned.
diff --git a/doc/README.html b/doc/README.html
index f70fe83f0..c71d63861 100644
--- a/doc/README.html
+++ b/doc/README.html
@@ -26,11 +26,42 @@
- = Introduction =
Redis is a database. To be specific, Redis is a database implementing a dictionary, where every key is associated with a value. For example I can set the key "surname_1992" to the string "Smith".
-What makes Redis different from many other key-value stores, is that every single value has a type. The following types are supported:
-The type of a value determines what operations (called commands) are available for the value itself.
-For example you can append elements to a list stored at the key "mylist" using the LPUSH or RPUSH command in O(1). Later you'll be able to get a range of elements with LRANGE or trim the list with LTRIM. Sets are very flexible too, it is possible to add and remove elements from Sets (unsorted collections of strings), and then ask for server-side intersection, union, difference of Sets. Each command is performed through server-side atomic operations.
-Please refer to the
Command Reference to see the full list of operations associated to these data types.
In other words, you can look at Redis as a data structures server. A Redis user is virtually provided with an interface to
Abstract Data Types, saving her from the responsibility to implement concrete data structures and algorithms. Indeed both algorithms and data structures in Redis are properly choosed in order to obtain the best performance.
Redis loads and mantains the whole dataset into memory, but the dataset is persistent, since at the same time it is saved on disk, so that when the server is restarted data can be loaded back in memory.
There are two kind of persistence supported: the first one is called snapshotting. In this mode Redis, from time to time, writes a dump on disk asynchronously. The dataset is loaded from the dump every time the server is (re)started.
Redis can be configured to save the dataset when a certain number of changes is reached and after a given number of seconds elapses. For example, you can configure Redis to save after 1000 changes and at most 60 seconds since the last save. You can specify any combination for these numbers.
Because data is written asynchronously, when a system crash occurs, the last few queries can get lost (that is acceptable in many applications but not in all). In order to make this a non issue Redis supports another, safer persistence mode, called
Append Only File, where every command received altering the dataset (so not a read-only command, but a write command) is written on an append only file ASAP. This commands are
replayed when the server is restarted in order to rebuild the dataset in memory.
Redis Append Only File supports a very handy feature: the server is able to safely rebuild the append only file in background in a non-blocking fashion when it gets too long. You can find
more details in the Append Only File HOWTO.
Whatever will be the persistence mode you'll use Redis supports master-slave replications if you want to stay really safe or if you need to scale to huge amounts of reads.
Redis Replication is trivial to setup. So trivial that all you need to do in order to configure a Redis server to be a slave of another one, with automatic synchronization if the link will go down and so forth, is the following config line:
slaveof 192.168.1.100 6379
.
We provide a Replication Howto if you want to know more about this feature.
Redis can be used as a
memcached on steroids because is as fast as memcached but with a number of features more. Like memcached, Redis also supports setting timeouts to keys so that this key will be automatically removed when a given amount of time passes.
All these features allow to use Redis as the sole DB for your scalable application without the need of any relational database.
We wrote a simple Twitter clone in PHP + Redis to show a real world example, the link points to an article explaining the design and internals in very simple words.
Redis supports multiple databases with commands to atomically move keys from one database to the other. By default DB 0 is selected for every new connection, but using the SELECT command it is possible to select a different database. The MOVE operation can move an item from one DB to another atomically. This can be used as a base for locking free algorithms together with the 'RANDOMKEY' commands.
To really get a feeling about what Redis is and how it works please try reading
A fifteen minutes introduction to Redis data types.
To know a bit more about how Redis works
internally continue reading.
(note, you can skip this section if you are only interested in "formal" doc.)
Later in this document you can find detailed information about Redis commands,
+ = Introduction =
Redis is an extremely fast and powerful key-value store database and server implemented in ANSI C. Redis offers many different ways to do one straightforward thing: store a value ("antirez") to a key ("redis"). While the format of keys must always be simple strings, the power is with the values, which support the following data types:
+Each value type has an associated list of commands which can operate on them, and the
The Redis Command Reference contains an up to date list of these commands, organized primarily by data type. The Redis source also includes a
Redis command line interface which allows you to interact directly with the server, and is the means by which this introduction will provide examples. Once you walk through the
Redis Quick Start Guide to get your instance of Redis running, you can follow along.
One of the most powerful aspects of Redis is the wide range of commands which are optimized to work with specific data value types and executed as atomic server-side operations. The
List type is a great example - Redis implements O(1) operations such as
LPUSH or
RPUSH, which have accompanying
LPOP and
RPOP methods:
+redis> lpush programming_languages C
+OK
+redis> lpush programming_languages Ruby
+OK
+redis> rpush programming_languages Python
+OK
+redis> rpop programming_languages
+Python
+redis> lpop programming_languages
+Ruby
+
More complex operations are available for each data type as well. Continuing with lists, you can get a range of elements with
LRANGE (O(start+n)) or trim the list with
LTRIM (O(n)):
+redis> lpush cities NYC
+OK
+redis> lpush cities SF
+OK
+redis> lpush cities Tokyo
+OK
+redis> lpush cities London
+OK
+redis> lpush cities Paris
+OK
+redis> lrange cities 0 2
+1. Paris
+2. London
+3. Tokyo
+redis> ltrim cities 0 1
+OK
+redis> lpop cities
+Paris
+redis> lpop cities
+London
+redis> lpop cities
+(nil)
+
You can also add and remove elements from a set, and perform intersections, unions, and differences.
Redis can also be looked at as a data structures server. A Redis user is virtually provided with an interface to
Abstract Data Types, saving them from the responsibility of implementing concrete data structures and algorithms -- indeed both algorithms and data structures in Redis are properly chosen in order to obtain the best performance.
Redis loads and mantains the whole dataset into memory, but the dataset is persistent, since at the same time it is saved on disk, so that when the server is restarted data can be loaded back in memory.
There are two kinds of persistence supported: the first one is called snapshotting. In this mode Redis periodically writes to disk asynchronously. The dataset is loaded from the dump every time the server is (re)started.
Redis can be configured to save the dataset when a certain number of changes is reached and after a given number of seconds elapses. For example, you can configure Redis to save after 1000 changes and at most 60 seconds since the last save. You can specify any combination for these numbers.
Because data is written asynchronously, when a system crash occurs, the last few queries can get lost (that is acceptable in many applications but not in all). In order to make this a non issue Redis supports another, safer persistence mode, called
Append Only File, where every command received altering the dataset (so not a read-only command, but a write command) is written on an append only file ASAP. This commands are
replayed when the server is restarted in order to rebuild the dataset in memory.
Redis Append Only File supports a very handy feature: the server is able to safely rebuild the append only file in background in a non-blocking fashion when it gets too long. You can find
more details in the Append Only File HOWTO.
Whatever will be the persistence mode you'll use Redis supports master-slave replications if you want to stay really safe or if you need to scale to huge amounts of reads.
Redis Replication is trivial to setup. So trivial that all you need to do in order to configure a Redis server to be a slave of another one, with automatic synchronization if the link will go down and so forth, is the following config line:
slaveof 192.168.1.100 6379
.
We provide a Replication Howto if you want to know more about this feature.
Redis can be used as a
memcached on steroids because is as fast as memcached but with a number of features more. Like memcached, Redis also supports setting timeouts to keys so that this key will be automatically removed when a given amount of time passes.
All these features allow to use Redis as the sole DB for your scalable application without the need of any relational database.
We wrote a simple Twitter clone in PHP + Redis to show a real world example, the link points to an article explaining the design and internals in very simple words.
Redis supports multiple databases with commands to atomically move keys from one database to the other. By default DB 0 is selected for every new connection, but using the SELECT command it is possible to select a different database. The MOVE operation can move an item from one DB to another atomically. This can be used as a base for locking free algorithms together with the 'RANDOMKEY' commands.
To really get a feeling about what Redis is and how it works please try reading
A fifteen minutes introduction to Redis data types.
To know a bit more about how Redis works
internally continue reading.
(note, you can skip this section if you are only interested in "formal" doc.)
Later in this document you can find detailed information about Redis commands,
the protocol specification, and so on. This kind of documentation is useful
but... if you are new to Redis it is also BORING! The Redis protocol is designed
so that is both pretty efficient to be parsed by computers, but simple enough
@@ -40,7 +71,7 @@ feeling about it, and how it works.
To start just compile redis with 'm
The server will start and log stuff on the standard output, if you want
it to log more edit redis.conf, set the loglevel to debug, and restart it.
You can specify a configuration file as unique parameter:
./redis-server /etc/redis.conf
This is NOT required. The server will start even without a configuration file
-using a default built-in configuration.
Now let's try to set a key to a given value:
+using a default built-in configuration.
Now let's try to set a key to a given value:
$ telnet localhost 6379
Trying 127.0.0.1...
Connected to localhost.
@@ -59,17 +90,17 @@ the point of view of both the server and client but allows us to play with
Redis with the telnet command easily.
The last line of the chat between server and client is "+OK". This means
our key was added without problems. Actually SET can never fail but
the "+OK" sent lets us know that the server received everything and
-the command was actually executed.
Let's try to get the key content now:
+the command was actually executed.
Let's try to get the key content now:
GET foo
$3
bar
Ok that's very similar to 'set', just the other way around. We sent "get foo",
the server replied with a first line that is just the $ character follwed by
the number of bytes the value stored at key contained, followed by the actual
-bytes. Again "\r\n" are appended both to the bytes count and the actual data. In Redis slang this is called a bulk reply.
What about requesting a non existing key?
+bytes. Again "\r\n" are appended both to the bytes count and the actual data. In Redis slang this is called a bulk reply.
What about requesting a non existing key?
GET blabla
$-1
-
When the key does not exist instead of the length, just the "$-1" string is sent. Since a -1 length of a bulk reply has no meaning it is used in order to specifiy a 'nil' value and distinguish it from a zero length value. Another way to check if a given key exists or not is indeed the EXISTS command:
+
When the key does not exist instead of the length, just the "$-1" string is sent. Since a -1 length of a bulk reply has no meaning it is used in order to specifiy a 'nil' value and distinguish it from a zero length value. Another way to check if a given key exists or not is indeed the EXISTS command:
EXISTS nokey
:0
EXISTS foo
diff --git a/doc/SortedSetCommandsSidebar.html b/doc/SortedSetCommandsSidebar.html
index 2534beb20..c2e8fae09 100644
--- a/doc/SortedSetCommandsSidebar.html
+++ b/doc/SortedSetCommandsSidebar.html
@@ -26,7 +26,7 @@