<h1><aname="INFO">INFO</a></h1><blockquote>The info command returns different information and statistics about the server in an format that's simple to parse by computers and easy to red by huamns.</blockquote>
#sidebar <ahref="ControlCommandsSidebar.html">ControlCommandsSidebar</a><h1><aname="INFO">INFO</a></h1><blockquote>The info command returns different information and statistics about the server in an format that's simple to parse by computers and easy to red by huamns.</blockquote>
<h2><aname="Return value">Return value</a></h2><ahref="ReplyTypes.html">Bulk reply</a>, specifically in the following format:<br/><br/><preclass="codeblock python"name="code">
<h2><aname="Return value">Return value</a></h2><ahref="ReplyTypes.html">Bulk reply</a>, specifically in the following format:<br/><br/><preclass="codeblock python"name="code">
edis_version:0.07
edis_version:0.07
connected_clients:1
connected_clients:1
...
@@ -39,8 +39,6 @@ total_commands_processed:1
...
@@ -39,8 +39,6 @@ total_commands_processed:1
uptime_in_seconds:25
uptime_in_seconds:25
uptime_in_days:0
uptime_in_days:0
</pre>All the fields are in the form <codename="code"class="python">field:value</code><h2><aname="Notes">Notes</a></h2><ul><li><codename="code"class="python">used_memory</code> is returned in bytes, and is the total number of bytes allocated by the program using <codename="code"class="python">malloc</code>.</li><li><codename="code"class="python">uptime_in_days</code> is redundant since the uptime in seconds contains already the full uptime information, this field is only mainly present for humans.</li><li><codename="code"class="python">changes_since_last_save</code> does not refer to the number of key changes, but to the number of operations that produced some kind of change in the dataset.</li></ul>
</pre>All the fields are in the form <codename="code"class="python">field:value</code><h2><aname="Notes">Notes</a></h2><ul><li><codename="code"class="python">used_memory</code> is returned in bytes, and is the total number of bytes allocated by the program using <codename="code"class="python">malloc</code>.</li><li><codename="code"class="python">uptime_in_days</code> is redundant since the uptime in seconds contains already the full uptime information, this field is only mainly present for humans.</li><li><codename="code"class="python">changes_since_last_save</code> does not refer to the number of key changes, but to the number of operations that produced some kind of change in the dataset.</li></ul>
<i>Time complexity: O(n) (with n being the number of keys in the DB, and assuming keys and pattern of limited length)</i><blockquote>Returns all the keys matching the glob-style <i>pattern</i> asspace separated strings. For example if you have in thedatabase the keys "foo" and "foobar" the command "KEYS foo<codename="code"class="python">*</code>"will return "foo foobar".</blockquote>
<i>Time complexity: O(n) (with n being the number of keys in the DB, and assuming keys and pattern of limited length)</i><blockquote>Returns all the keys matching the glob-style <i>pattern</i> asspace separated strings. For example if you have in thedatabase the keys "foo" and "foobar" the command "KEYS foo<codename="code"class="python">*</code>"will return "foo foobar".</blockquote>
<blockquote>Note that while the time complexity for this operation is O(n)the constant times are pretty low. For example Redis runningon an entry level laptop can scan a 1 million keys databasein 40 milliseconds. Still it's better to consider this one ofthe slow commands that may ruin the DB performance if not usedwith care.</blockquote>
<blockquote>Note that while the time complexity for this operation is O(n)the constant times are pretty low. For example Redis runningon an entry level laptop can scan a 1 million keys databasein 40 milliseconds. Still it's better to consider this one ofthe slow commands that may ruin the DB performance if not usedwith care.</blockquote>
Glob style patterns examples:
Glob style patterns examples:
<ul><li> h?llo will match hello hallo hhllo</li><li> h<b>llo will match hllo heeeello
<ul><li> h?llo will match hello hallo hhllo</li><li> h<b>llo will match hllo heeeello
<blockquote>* h<ahref="ae.html">ae</a>llo will match hello and hallo, but not hillo</blockquote>Use \ to escape special chars if you want to match them verbatim.<h2><aname="Return value">Return value</a></h2><ahref="ReplyTypes.html">Bulk reply</a>, specifically a string in the form of space separated list of keys. Note that most client libraries will return an Array of keys and not a single string with space separated keys (that is, split by "" is performed in the client library usually).<h2><aname="See also">See also</a></h2>
<blockquote>* h<ahref="ae.html">ae</a>llo will match hello and hallo, but not hillo</blockquote>Use \ to escape special chars if you want to match them verbatim.<h2><aname="Return value">Return value</a></h2><ahref="ReplyTypes.html">Bulk reply</a>, specifically a string in the form of space separated list of keys. Note that most client libraries will return an Array of keys and not a single string with space separated keys (that is, split by "" is performed in the client library usually).
<blockquote>* <ahref="RandomkeyCommand.html">RANDOMKEY</a> to get the name of a randomly selected key in O(1).</blockquote></b></li></ul>
<blockquote>Return the UNIX TIME of the last DB save executed with success.A client may check if a <ahref="BgsaveCommand.html">BGSAVE</a> command succeeded reading the LASTSAVEvalue, then issuing a <ahref="BgsaveCommand.html">BGSAVE</a> command and checking at regular intervalsevery N seconds if LASTSAVE changed.</blockquote>
<blockquote>Return the UNIX TIME of the last DB save executed with success.A client may check if a <ahref="BgsaveCommand.html">BGSAVE</a> command succeeded reading the LASTSAVEvalue, then issuing a <ahref="BgsaveCommand.html">BGSAVE</a> command and checking at regular intervalsevery N seconds if LASTSAVE changed.</blockquote>
<h2><aname="Return value">Return value</a></h2><ahref="ReplyTypes.html">Integer reply</a>, specifically an UNIX time stamp.<h2><aname="See also">See also</a></h2>
<h2><aname="Return value">Return value</a></h2><ahref="ReplyTypes.html">Integer reply</a>, specifically an UNIX time stamp.
<i>Time complexity: O(n) (with n being the length of the list)</i><blockquote>Return the specified element of the list stored at the specifiedkey. 0 is the first element, 1 the second and so on. Negative indexesare supported, for example -1 is the last element, -2 the penultimateand so on.</blockquote>
<i>Time complexity: O(n) (with n being the length of the list)</i><blockquote>Return the specified element of the list stored at the specifiedkey. 0 is the first element, 1 the second and so on. Negative indexesare supported, for example -1 is the last element, -2 the penultimateand so on.</blockquote>
<blockquote>If the value stored at key is not of list type an error is returned.If the index is out of range an empty string is returned.</blockquote>
<blockquote>If the value stored at key is not of list type an error is returned.If the index is out of range an empty string is returned.</blockquote>
<blockquote>Note that even if the average time complexity is O(n) asking forthe first or the last element of the list is O(1).</blockquote>
<blockquote>Note that even if the average time complexity is O(n) asking forthe first or the last element of the list is O(1).</blockquote>
<h2><aname="Return value">Return value</a></h2><ahref="ReplyTypes.html">Bulk reply</a>, specifically the requested element.<h2><aname="See also">See also</a></h2>
<h2><aname="Return value">Return value</a></h2><ahref="ReplyTypes.html">Bulk reply</a>, specifically the requested element.
<!-- This is a (PRE) block. Make sure it's left aligned or your toc title will be off. -->
<b>ListCommandsSidebar: Contents</b>
</div>
<h1class="wikiname">ListCommandsSidebar</h1>
<divclass="summary">
</div>
<divclass="narrow">
== List Commands ==<br/><br/><ul><li><ahref="RpushCommand.html">RPUSH</a></li><li><ahref="RpushCommand.html">LPUSH</a></li><li><ahref="LlenCommand.html">LLEN</a></li><li><ahref="LrangeCommand.html">LRANGE</a></li><li><ahref="LtrimCommand.html">LTRIM</a></li><li><ahref="LindexCommand.html">LINDEX</a></li><li><ahref="LsetCommand.html">LSET</a></li><li><ahref="LremCommand.html">LREM</a></li><li><ahref="LpopCommand.html">LPOP</a></li><li><ahref="LpopCommand.html">RPOP</a></li><li><ahref="RpoplpushCommand.html">RPOPLPUSH</a></li><li><ahref="SortCommand.html">SORT</a></li></ul>
<!-- This is a (PRE) block. Make sure it's left aligned or your toc title will be off. -->
<b>Lists: Contents</b><br> <ahref="#Redis List Type">Redis List Type</a><br> <ahref="#Implementation details">Implementation details</a>
</div>
<h1class="wikiname">Lists</h1>
<divclass="summary">
</div>
<divclass="narrow">
#sidebar <ahref="ListCommandsSidebar.html">ListCommandsSidebar</a><h1><aname="Redis List Type">Redis List Type</a></h1>Redis Lists are lists of <ahref="Stings.html">Redis Strings</a>, sorted by insertion order. It's possible to add elements to a Redis List pushing new elements on the head (on the left) or on the tail (on the right) of the list.<br/><br/>The <ahref="RpushCommand.html">LPUSH</a> command inserts a new elmenet on head, while <ahref="RpushCommand.html">RPUSH</a> inserts a new element on tail. A new list is created when one of this operations is performed against an empty key.<br/><br/>For instance if perform the following operations:
<preclass="codeblock python"name="code">
LPUSH mylist a # now the list is "a"
LPUSH mylist b # now the list is "b","a"
RPUSH mylist c # now the list is "b","a","c" (RPUSH was used this time)
</pre>
The resulting list stored at <i>mylist</i> will contain the elements "b","a","c".<br/><br/>The max length of a list is 232-1 elements (4294967295, more than 4 billion of elements per list).<h1><aname="Implementation details">Implementation details</a></h1>Redis Lists are implemented as doubly liked lists. A few commands benefit from the fact the lists are doubly linked in order to reach the needed element starting from the nearest extreme (head or tail). <ahref="LrangeCommand.html">LRANGE</a> and <ahref="LindexCommand.html">LINDEX</a> are examples of such commands.<br/><br/>The use of linked lists also guarantees that regardless of the length of the list pushing and popping are O(1) operations.<br/><br/>Redis Lists cache length information so <ahref="LlenCommand.html">LLEN</a> is O(1) as well.
<i>Time complexity: O(1)</i><blockquote>Return the length of the list stored at the specified key. If thekey does not exist zero is returned (the same behaviour as forempty lists). If the value stored at <i>key</i> is not a list an error is returned.</blockquote>
<i>Time complexity: O(1)</i><blockquote>Return the length of the list stored at the specified key. If thekey does not exist zero is returned (the same behaviour as forempty lists). If the value stored at <i>key</i> is not a list an error is returned.</blockquote>
<i>Time complexity: O(1)</i><blockquote>Atomically return and remove the first (LPOP) or last (RPOP) elementof the list. For example if the list contains the elements "a","b","c" LPOPwill return "a" and the list will become "b","c".</blockquote>
<i>Time complexity: O(1)</i><blockquote>Atomically return and remove the first (LPOP) or last (RPOP) elementof the list. For example if the list contains the elements "a","b","c" LPOPwill return "a" and the list will become "b","c".</blockquote>
<blockquote>If the <i>key</i> does not exist or the list is already empty the specialvalue 'nil' is returned.</blockquote>
<blockquote>If the <i>key</i> does not exist or the list is already empty the specialvalue 'nil' is returned.</blockquote>
<i>Time complexity: O(n) (with n being the length of the range)</i><blockquote>Return the specified elements of the list stored at the specifiedkey. Start and end are zero-based indexes. 0 is the first elementof the list (the list head), 1 the next element and so on.</blockquote>
<i>Time complexity: O(n) (with n being the length of the range)</i><blockquote>Return the specified elements of the list stored at the specifiedkey. Start and end are zero-based indexes. 0 is the first elementof the list (the list head), 1 the next element and so on.</blockquote>
<blockquote>For example LRANGE foobar 0 2 will return the first three elementsof the list.</blockquote>
<blockquote>For example LRANGE foobar 0 2 will return the first three elementsof the list.</blockquote>
<blockquote>_start_ and <i>end</i> can also be negative numbers indicating offsetsfrom the end of the list. For example -1 is the last element ofthe list, -2 the penultimate element and so on.</blockquote>
<blockquote>_start_ and <i>end</i> can also be negative numbers indicating offsetsfrom the end of the list. For example -1 is the last element ofthe list, -2 the penultimate element and so on.</blockquote>
<blockquote>Indexes out of range will not produce an error: if start is overthe end of the list, or start <codename="code"class="python">></code> end, an empty list is returned.If end is over the end of the list Redis will threat it just likethe last element of the list.</blockquote>
<blockquote>Indexes out of range will not produce an error: if start is overthe end of the list, or start <codename="code"class="python">></code> end, an empty list is returned.If end is over the end of the list Redis will threat it just likethe last element of the list.</blockquote>
<h2><aname="Return value">Return value</a></h2><ahref="ReplyTypes.html">Multi bulk reply</a>, specifically a list of elements in the specified range.<h2><aname="See also">See also</a></h2>
<h2><aname="Return value">Return value</a></h2><ahref="ReplyTypes.html">Multi bulk reply</a>, specifically a list of elements in the specified range.
<i>Time complexity: O(N) (with N being the length of the list)</i><blockquote>Remove the first <i>count</i> occurrences of the <i>value</i> element from the list.If <i>count</i> is zero all the elements are removed. If <i>count</i> is negativeelements are removed from tail to head, instead to go from head to tailthat is the normal behaviour. So for example LREM with count -2 and_hello_ as value to remove against the list (a,b,c,hello,x,hello,hello) willlave the list (a,b,c,hello,x). The number of removed elements is returnedas an integer, see below for more information about the returned value.Note that non existing keys are considered like empty lists by LREM, so LREMagainst non existing keys will always return 0.</blockquote>
<i>Time complexity: O(N) (with N being the length of the list)</i><blockquote>Remove the first <i>count</i> occurrences of the <i>value</i> element from the list.If <i>count</i> is zero all the elements are removed. If <i>count</i> is negativeelements are removed from tail to head, instead to go from head to tailthat is the normal behaviour. So for example LREM with count -2 and_hello_ as value to remove against the list (a,b,c,hello,x,hello,hello) willlave the list (a,b,c,hello,x). The number of removed elements is returnedas an integer, see below for more information about the returned value.Note that non existing keys are considered like empty lists by LREM, so LREMagainst non existing keys will always return 0.</blockquote>
<i>Time complexity: O(N) (with N being the length of the list)</i><blockquote>Set the list element at <i>index</i> (see LINDEX for information about the_index_ argument) with the new <i>value</i>. Out of range indexes willgenerate an error. Note that setting the first or last elements ofthe list is O(1).</blockquote>
<i>Time complexity: O(N) (with N being the length of the list)</i><blockquote>Set the list element at <i>index</i> (see LINDEX for information about the_index_ argument) with the new <i>value</i>. Out of range indexes willgenerate an error. Note that setting the first or last elements ofthe list is O(1).</blockquote>
<i>Time complexity: O(n) (with n being len of list - len of range)</i><blockquote>Trim an existing list so that it will contain only the specifiedrange of elements specified. Start and end are zero-based indexes.0 is the first element of the list (the list head), 1 the next elementand so on.</blockquote>
<i>Time complexity: O(n) (with n being len of list - len of range)</i><blockquote>Trim an existing list so that it will contain only the specifiedrange of elements specified. Start and end are zero-based indexes.0 is the first element of the list (the list head), 1 the next elementand so on.</blockquote>
<blockquote>For example LTRIM foobar 0 2 will modify the list stored at foobarkey so that only the first three elements of the list will remain.</blockquote>
<blockquote>For example LTRIM foobar 0 2 will modify the list stored at foobarkey so that only the first three elements of the list will remain.</blockquote>
<blockquote>_start_ and <i>end</i> can also be negative numbers indicating offsetsfrom the end of the list. For example -1 is the last element ofthe list, -2 the penultimate element and so on.</blockquote>
<blockquote>_start_ and <i>end</i> can also be negative numbers indicating offsetsfrom the end of the list. For example -1 is the last element ofthe list, -2 the penultimate element and so on.</blockquote>
...
@@ -36,8 +36,8 @@
...
@@ -36,8 +36,8 @@
LPUSH mylist <someelement>
LPUSH mylist <someelement>
LTRIM mylist 0 99
LTRIM mylist 0 99
</pre><blockquote>The above two commands will push elements in the list taking care thatthe list will not grow without limits. This is very useful when usingRedis to store logs for example. It is important to note that when usedin this way LTRIM is an O(1) operation because in the average casejust one element is removed from the tail of the list.</blockquote>
</pre><blockquote>The above two commands will push elements in the list taking care thatthe list will not grow without limits. This is very useful when usingRedis to store logs for example. It is important to note that when usedin this way LTRIM is an O(1) operation because in the average casejust one element is removed from the tail of the list.</blockquote>
<i>Time complexity: O(1) for every key</i><blockquote>Get the values of all the specified keys. If one or more keys dont existor is not of type String, a 'nil' value is returned instead of the valueof the specified key, but the operation never fails.</blockquote>
<i>Time complexity: O(1) for every key</i><blockquote>Get the values of all the specified keys. If one or more keys dont existor is not of type String, a 'nil' value is returned instead of the valueof the specified key, but the operation never fails.</blockquote>
<h1><aname="MONITOR">MONITOR</a></h1><blockquote>MONITOR is a debugging command that outputs the whole sequence of commandsreceived by the Redis server. is very handy in order to understandwhat is happening into the database. This command is used directlyvia telnet.</blockquote>
#sidebar <ahref="ControlCommandsSidebar.html">ControlCommandsSidebar</a><h1><aname="MONITOR">MONITOR</a></h1><blockquote>MONITOR is a debugging command that outputs the whole sequence of commandsreceived by the Redis server. is very handy in order to understandwhat is happening into the database. This command is used directlyvia telnet.</blockquote>
<preclass="codeblock python"name="code">
<preclass="codeblock python"name="code">
% telnet 127.0.0.1 6379
% telnet 127.0.0.1 6379
Trying 127.0.0.1...
Trying 127.0.0.1...
...
@@ -52,8 +52,8 @@ set foo_a 5
...
@@ -52,8 +52,8 @@ set foo_a 5
hello
hello
</pre><blockquote>The ability to see all the requests processed by the server is useful in orderto spot bugs in the application both when using Redis as a database and asa distributed caching system.</blockquote>
</pre><blockquote>The ability to see all the requests processed by the server is useful in orderto spot bugs in the application both when using Redis as a database and asa distributed caching system.</blockquote>
<blockquote>In order to end a monitoring session just issue a QUIT command by hand.</blockquote>
<blockquote>In order to end a monitoring session just issue a QUIT command by hand.</blockquote>
<h2><aname="Return value">Return value</a></h2><b>Non standard return value</b>, just dumps the received commands in an infinite flow.<h2><aname="See also">See also</a></h2>
<h2><aname="Return value">Return value</a></h2><b>Non standard return value</b>, just dumps the received commands in an infinite flow.
<blockquote>Move the specified key from the currently selected DB to the specifieddestination DB. Note that this command returns 1 only if the key wassuccessfully moved, and 0 if the target key was already there or if thesource key was not found at all, so it is possible to use MOVE as a lockingprimitive.</blockquote>
<blockquote>Move the specified key from the currently selected DB to the specifieddestination DB. Note that this command returns 1 only if the key wassuccessfully moved, and 0 if the target key was already there or if thesource key was not found at all, so it is possible to use MOVE as a lockingprimitive.</blockquote>
<i>Time complexity: O(1) to set every key</i><blockquote>Set the the rispective keys to the rispective values. MSET will replace oldvalues with new values, while MSETNX will not perform any operation at alleven if just a single key already exists.</blockquote>
<i>Time complexity: O(1) to set every key</i><blockquote>Set the the rispective keys to the rispective values. MSET will replace oldvalues with new values, while MSETNX will not perform any operation at alleven if just a single key already exists.</blockquote>
<blockquote>Because of this semantic MSETNX can be used in order to set different keysrepresenting different fields of an unique logic object in a way thatensures that either all the fields or none at all are set.</blockquote>
<blockquote>Because of this semantic MSETNX can be used in order to set different keysrepresenting different fields of an unique logic object in a way thatensures that either all the fields or none at all are set.</blockquote>
0 if no key was set (at least one key already existed)
0 if no key was set (at least one key already existed)
</pre><h2><aname="See also">See also</a></h2><ul><li><ahref="MgetCommand.html">MGET</a></li><li><ahref="DelCommand.html">DEL</a> (DEL supports deleting multiple keys in a single operation)</li></ul>
<!-- This is a (PRE) block. Make sure it's left aligned or your toc title will be off. -->
<!-- This is a (PRE) block. Make sure it's left aligned or your toc title will be off. -->
<b>QuickStart: Contents</b><br> <ahref="#Quick Start">Quick Start</a><br> <ahref="#Obtain the latest version">Obtain the latest version</a><br> <ahref="#Compile">Compile</a><br> <ahref="#Run the server">Run the server</a><br> <ahref="#Play with the built in client">Play with the built in client</a><br> <ahref="#Further reading">Further reading</a>
<b>QuickStart: Contents</b><br> <ahref="#Obtain the latest version">Obtain the latest version</a><br> <ahref="#Compile">Compile</a><br> <ahref="#Run the server">Run the server</a><br> <ahref="#Play with the built in client">Play with the built in client</a><br> <ahref="#Further reading">Further reading</a>
</div>
</div>
<h1class="wikiname">QuickStart</h1>
<h1class="wikiname">QuickStart</h1>
...
@@ -26,7 +26,7 @@
...
@@ -26,7 +26,7 @@
</div>
</div>
<divclass="narrow">
<divclass="narrow">
<h1><aname="Quick Start">Quick Start</a></h1>This quickstart is a five minutes howto on how to get started with Redis. For more information on Redis check <ahref="http://code.google.com/p/redis/wiki/index"target="_blank">Redis Documentation Index</a>.<h2><aname="Obtain the latest version">Obtain the latest version</a></h2>The latest stable source distribution of Redis can be obtained <ahref="http://code.google.com/p/redis/downloads/list"target="_blank">at this location as a tarball</a>.<br/><br/><preclass="codeblock python"name="code">
= Quick Start =<br/><br/>This quickstart is a five minutes howto on how to get started with Redis. For more information on Redis check <ahref="http://code.google.com/p/redis/wiki/index"target="_blank">Redis Documentation Index</a>.<h2><aname="Obtain the latest version">Obtain the latest version</a></h2>The latest stable source distribution of Redis can be obtained <ahref="http://code.google.com/p/redis/downloads/list"target="_blank">at this location as a tarball</a>.<br/><br/><preclass="codeblock python"name="code">
</pre>The unstable source code, with more features but not ready for production, can be downloaded using git:<br/><br/><preclass="codeblock python python"name="code">
</pre>The unstable source code, with more features but not ready for production, can be downloaded using git:<br/><br/><preclass="codeblock python python"name="code">
$ git clone git://github.com/antirez/redis.git
$ git clone git://github.com/antirez/redis.git
...
@@ -57,18 +57,7 @@ firstvalue
...
@@ -57,18 +57,7 @@ firstvalue
$ ./redis-cli lrange mylist 0 -1
$ ./redis-cli lrange mylist 0 -1
1. thirdvalue
1. thirdvalue
2. secondvalue
2. secondvalue
</pre><ahref="Lists.html">Lists</a> (and <ahref="Sets.html">Sets</a> too) can be sorted:<br/><br/><preclass="codeblock python python python python python python python"name="code">
</pre><h2><aname="Further reading">Further reading</a></h2><ul><li> What to play more with Redis? Read <ahref="IntroductionToRedisDataTypes.html">Fifteen minutes introduction to Redis data types</a>.</li><li> Check all the <ahref="Features.html">Features</a></li><li> Read the full list of available commands in the <ahref="CommandReference.html">Command Reference</a>.</li><li> Start using Redis from your <ahref="SupportedLanguages.html">favorite language</a>.</li><li> Take a look at some <ahref="ProgrammingExamples.html">Programming Examples</a>. </li></ul>
./redis-cli sort mylist alpha
1. secondvalue
2. thirdvalue
</pre>And despite Redis doesn't have integers, you can do some math also:<br/><br/><preclass="codeblock python python python python python python python python"name="code">
$ ./redis-cli get mycounter
(nil)
$ ./redis-cli incr mycounter
1
./redis-cli incr mycounter
2
</pre><h2><aname="Further reading">Further reading</a></h2><ul><li> Check all the <ahref="Features.html">Features</a></li><li> Read the full list of available commands in the <ahref="CommandReference.html">Command Reference</a>.</li><li> Start using Redis from your <ahref="SupportedLanguages.html">favorite language</a>.</li><li> Take a look at some <ahref="ProgrammingExamples.html">Programming Examples</a>. </li></ul>
<h1><aname="Quit">Quit</a></h1><blockquote>Ask the server to silently close the connection.</blockquote>
#sidebar <ahref="ConnectionHandlingSidebar.html">ConnectionHandlingSidebar</a><h1><aname="Quit">Quit</a></h1><blockquote>Ask the server to silently close the connection.</blockquote>
<h2><aname="Return value">Return value</a></h2>None. The connection is closed as soon as the QUIT command is received.
<h2><aname="Return value">Return value</a></h2>None. The connection is closed as soon as the QUIT command is received.
<!-- This is a (PRE) block. Make sure it's left aligned or your toc title will be off. -->
<!-- This is a (PRE) block. Make sure it's left aligned or your toc title will be off. -->
<b>README: Contents</b><br> <ahref="#Introduction">Introduction</a><br> <ahref="#Beyond key-value databases">Beyond key-value databases</a><br> <ahref="#What are the differences between Redis and Memcached?">What are the differences between Redis and Memcached?</a><br> <ahref="#What are the differences between Redis and Tokyo Cabinet / Tyrant?">What are the differences between Redis and Tokyo Cabinet / Tyrant?</a><br> <ahref="#Does Redis support locking?">Does Redis support locking?</a><br> <ahref="#Multiple databases support">Multiple databases support</a><br> <ahref="#Redis Data Types">Redis Data Types</a><br> <ahref="#Implementation Details">Implementation Details</a><br> <ahref="#Redis Tutorial">Redis Tutorial</a><br> <ahref="#License">License</a><br> <ahref="#Credits">Credits</a>
<b>README: Contents</b><br> <ahref="#All data in memory, but saved on disk">All data in memory, but saved on disk</a><br> <ahref="#Master-Slave replication made trivial">Master-Slave replication made trivial</a><br> <ahref="#It's persistent but supports expires">It's persistent but supports expires</a><br> <ahref="#Beyond key-value databases">Beyond key-value databases</a><br> <ahref="#Multiple databases support">Multiple databases support</a><br> <ahref="#Know more about Redis!">Know more about Redis!</a><br> <ahref="#Redis Tutorial">Redis Tutorial</a><br> <ahref="#License">License</a><br> <ahref="#Credits">Credits</a>
</div>
</div>
<h1class="wikiname">README</h1>
<h1class="wikiname">README</h1>
...
@@ -26,32 +26,11 @@
...
@@ -26,32 +26,11 @@
</div>
</div>
<divclass="narrow">
<divclass="narrow">
<h1><aname="Introduction">Introduction</a></h1>Redis is a database. To be specific, Redis is a very simple 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".
= Introduction =<br/><br/>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:<br/><br/><ul><li> String</li><li> List</li><li> Set</li><li> Sorted Set (since version 1.1)</li></ul>
What makes Redis different from many other key-value stores, is that every single value has a type. The following types are supported:<br/><br/><ul><li> String</li><li> List</li><li> Set</li><li> Sorted Set (since version 1.1)</li></ul>
The type of a value determines what operations (called commands) are available for the value itself.
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.
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 <ahref="CommandReference.html">Command Reference</a> to see the full list of operations associated to these data types.<br/><br/>In other words, you can look at Redis as a data structures server. A Redis user is virtually provided with an interface to <ahref="http://en.wikipedia.org/wiki/Abstract_data_type"target="_blank">Abstract Data Types</a>, 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.<br/><br/>Redis loads and mantains the whole dataset into memory, but the dataset is persistent, since from time to time Redis writes a dump on disk asynchronously. The dataset is loaded from the dump every time the server is (re)started.<br/><br/>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.<br/><br/>Because data is written asynchronously, when a system crash occurs, the last few queries can get lost (that is acceptable in many applications). Anyway it is possible to make this a non issue, since Redis supports master-slave replication from its early days, being effective even in the case where a few records lost are not acceptable.<h1><aname="Beyond key-value databases">Beyond key-value databases</a></h1>All these features allow to use Redis as the sole DB for your scalable application without the need of any relational database. <ahref="TwitterAlikeExample.html">We wrote a simple Twitter clone in PHP + Redis</a> to show a real world example, the link points to an article explaining the design and internals in very simple words.<h1><aname="What are the differences between Redis and Memcached?">What are the differences between Redis and Memcached?</a></h1>In the following ways:<br/><br/><ul><li> Memcached is not persistent, it just holds everything in memory without saving since its main goal is to be used as a cache. Redis instead can be used as the main DB for the application. We <ahref="TwitterAlikeExample.html">wrote a simple Twitter clone</a> using only Redis as database.</li></ul>
Please refer to the <ahref="CommandReference.html">Command Reference</a> to see the full list of operations associated to these data types.<br/><br/>In other words, you can look at Redis as a data structures server. A Redis user is virtually provided with an interface to <ahref="http://en.wikipedia.org/wiki/Abstract_data_type"target="_blank">Abstract Data Types</a>, 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.<h1><aname="All data in memory, but saved on disk">All data in memory, but saved on disk</a></h1>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.<br/><br/>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.<br/><br/>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.<br/><br/>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 <ahref="AppendOnlyFileHowto.html">Append Only File</a>, 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 <i>replayed</i> when the server is restarted in order to rebuild the dataset in memory.<br/><br/>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 <ahref="AppendOnlyFileHowto.html">more details in the Append Only File HOWTO</a>.<h1><aname="Master-Slave replication made trivial">Master-Slave replication made trivial</a></h1>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.<br/><br/><b>Redis Replication is trivial to setup</b>. 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: <codename="code"class="python">slaveof 192.168.1.100 6379</code>. <ahref="ReplicationHowto.html">We provide a Replication Howto</a> if you want to know more about this feature.<h1><aname="It's persistent but supports expires">It's persistent but supports expires</a></h1>Redis can be used as a <b>memcached on steroids</b> 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.<h1><aname="Beyond key-value databases">Beyond key-value databases</a></h1>All these features allow to use Redis as the sole DB for your scalable application without the need of any relational database. <ahref="TwitterAlikeExample.html">We wrote a simple Twitter clone in PHP + Redis</a> to show a real world example, the link points to an article explaining the design and internals in very simple words.<h1><aname="Multiple databases support">Multiple databases support</a></h1>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.<h1><aname="Know more about Redis!">Know more about Redis!</a></h1>To really get a feeling about what Redis is and how it works please try reading <ahref="IntroductionToRedisDataTypes.html">A fifteen minutes introduction to Redis data types</a>.<br/><br/>To know a bit more about how Redis works <i>internally</i> continue reading.<h1><aname="Redis Tutorial">Redis Tutorial</a></h1>(note, you can skip this section if you are only interested in "formal" doc.)<br/><br/>Later in this document you can find detailed information about Redis commands,
<ul><li> Like memcached Redis uses a key-value model, but while keys can just be strings, values in Redis can be lists and sets, and complex operations like intersections, set/get n-th element of lists, pop/push of elements, can be performed against sets and lists. It is possible to use lists as message queues.</li></ul>
<h1><aname="What are the differences between Redis and Tokyo Cabinet / Tyrant?">What are the differences between Redis and Tokyo Cabinet / Tyrant?</a></h1>Redis and Tokyo Cabinet can be used for the same applications, but actually they are <b>very</b> different beasts. If you read twitter messages of people involved in scalable things both products are reported to work well, but surely there are times where one or the other can be the best choice. Some differences are the followings (I may be biased, make sure to check yourself both the products).<br/><br/><ul><li> Tokyo Cabinet writes synchronously on disk, Redis takes the whole dataset on memory and writes on disk asynchronously. Tokyo Cabinet is safer and probably a better idea if your dataset is going to be bigger than RAM, but Redis is faster (note that Redis supports master-slave replication that is trivial to setup, so you are safe anyway if you want a setup where data can't be lost even after a disaster).</li></ul>
<ul><li> Redis supports higher level operations and data structures. Tokyo Cabinet supports a kind of database that is able to organize data into rows with named fields (in a way very similar to Berkeley DB) but can't do things like server side List and Set operations Redis is able to do: pushing or popping from Lists in an atomic way, in O(1) time complexity, server side Set intersections, <ahref="SORT.html">SortCommand</a> ing of schema free data in complex ways (Btw TC supports sorting in the table-based database format). Redis on the other hand does not support the abstraction of tables with fields, the idea is that you can build this stuff in software easily if you really need a table-alike approach.</li></ul>
<ul><li> Tokyo Cabinet does not implement a networking layer. You have to use a networking layer called Tokyo Tyrant that interfaces to Tokyo Cabinet so you can talk to Tokyo Cabinet in a client-server fashion. In Redis the networking support is built-in inside the server, and is basically the only interface between the external world and the dataset.</li></ul>
<ul><li> Redis is reported to be much faster, especially if you plan to access Tokyo Cabinet via Tokyo Tyrant. Here I can only say that with Redis you can expect 100,000 operations/seconds with a normal Linux box and 50 concurrent clients. You should test Redis, Tokyo, and the other alternatives with your specific work load to get a feeling about performances for your application.</li></ul>
<ul><li> Redis is (IMHO) generally an higher level and simpler to use beast in the operations supported, and to get started. <ahref="Check.html">the command reference CommandReference</a> to get a feeling. You can even start playing with Redis by telnet after reading the five minutes tutorial at the end of this README file. To implement new client libraries is trivial. <ahref="Check.html">the protocol specification ProtocolSpecification</a> for more information.</li></ul><blockquote></blockquote><ul><li> Redis is not an on-disk DB engine like Tokyo: the latter can be used as a fast DB engine in your C project without the networking overhead just linking to the library. Still in many scalable applications you need multiple servers talking with multiple clients, so the client-server model is almost always needed, this is why in Redis this is built-in.</li></ul>
<h1><aname="Does Redis support locking?">Does Redis support locking?</a></h1>No, the idea is to provide atomic primitives in order to make the programmer
able to use redis with locking free algorithms. For example imagine you have
10 computers and one Redis server. You want to count words in a very large text.
This large text is split among the 10 computers, every computer will process
its part and use Redis's INCR command to atomically increment a counter
for every occurrence of the word found.<br/><br/>INCR/DECR are not the only atomic primitives, there are others like PUSH/POP
on lists, POP RANDOM KEY operations, UPDATE and so on. For example you can
use Redis like a Tuple Space (<ahref="http://en.wikipedia.org/wiki/Tuple_space"target="_blank">http://en.wikipedia.org/wiki/Tuple_space</a>) in
order to implement distributed algorithms.<br/><br/>(News: locking with key-granularity is now planned)<h1><aname="Multiple databases support">Multiple databases support</a></h1>Another synchronization primitive is the support for multiple DBs. 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.<h1><aname="Redis Data Types">Redis Data Types</a></h1>Redis supports the following three data types as values:<br/><br/><ul><li> Strings: just any sequence of bytes. Redis strings are binary safe so they can not just hold text, but images, compressed data and everything else.</li><li> Lists: lists of strings, with support for operations like append a new string on head, on tail, list length, obtain a range of elements, truncate the list to a given length, sort the list, and so on.</li><li> Sets: an unsorted set of strings. It is possible to add or delete elements from a set, to perform set intersection, union, subtraction, and so on.</li></ul>
Values can be Strings, Lists or Sets. Keys can be a subset of strings not containing newlines ("\n") and spaces ("").<br/><br/>Note that sometimes strings may hold numeric vaules that must be parsed by
Redis. An example is the INCR command that atomically increments the number
stored at the specified key. In this case Redis is able to handle integers
that can be stored inside a 'long long' type, that is a 64-bit signed integer.<h2><aname="Implementation Details">Implementation Details</a></h2>Strings are implemented as dynamically allocated strings of characters.
Lists are implemented as doubly linked lists with cached length.
Sets are implemented using hash tables that use chaining to resolve collisions.<h1><aname="Redis Tutorial">Redis Tutorial</a></h1>(note, you can skip this section if you are only interested in "formal" doc.)<br/><br/>Later in this document you can find detailed information about Redis commands,
the protocol specification, and so on. This kind of documentation is useful
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
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
so that is both pretty efficient to be parsed by computers, but simple enough
...
@@ -99,8 +78,8 @@ EXISTS foo
...
@@ -99,8 +78,8 @@ EXISTS foo
exist, and ':1' for 'foo', a key that actually exists. Replies starting with the colon character are integer reply.<br/><br/>Ok... now you know the basics, read the <ahref="CommandReference.html">REDIS COMMAND REFERENCE</a> section to
exist, and ':1' for 'foo', a key that actually exists. Replies starting with the colon character are integer reply.<br/><br/>Ok... now you know the basics, read the <ahref="CommandReference.html">REDIS COMMAND REFERENCE</a> section to
learn all the commands supported by Redis and the <ahref="ProtocolSpecification.html">PROTOCOL SPECIFICATION</a>
learn all the commands supported by Redis and the <ahref="ProtocolSpecification.html">PROTOCOL SPECIFICATION</a>
section for more details about the protocol used if you plan to implement one
section for more details about the protocol used if you plan to implement one
for a language missing a decent client implementation.<h1><aname="License">License</a></h1>Redis is released under the BSD license. See the COPYING file for more information.<h1><aname="Credits">Credits</a></h1>Redis is written and maintained by Salvatore Sanfilippo, Aka 'antirez'.<br/><br/>Enjoy,
for a language missing a decent client implementation.<h1><aname="License">License</a></h1>Redis is released under the BSD license. See the COPYING file for more information.<h1><aname="Credits">Credits</a></h1>Redis is written and maintained by Salvatore Sanfilippo, Aka 'antirez'.