Commit 73287b2b authored by antirez's avatar antirez
Browse files

buliding of release.h moved into an external script. Avoided recompialtion of...

buliding of release.h moved into an external script. Avoided recompialtion of redis.c if git sha1 is the same as the previous one
parent 5436146c
2010-05-16 Redis version is now 1.3.12 (antirez)
2010-05-16 redis version is now 1.3.11 (antirez)
2010-05-16 random refactoring and speedups (antirez)
2010-05-16 faster INCR with very little efforts... (antirez)
2010-05-15 Merge branch 'redis-cli-fix' of http://github.com/tizoc/redis (antirez)
2010-05-15 added pid info to the check memory leaks test, so that those tests don't appear to be duplicated (antirez)
2010-05-15 Merge branch 'integration' of git://github.com/pietern/redis (antirez)
2010-05-14 more endianess detection fix for SHA1 (antirez)
2010-05-14 fixed a warning seen with some GCC version under Linux (antirez)
2010-05-14 initial rough integration test for replication (Pieter Noordhuis)
2010-05-14 store entire server object on the stack instead of just the client (Pieter Noordhuis)
2010-05-14 proc to retrieve values from INFO properties (Pieter Noordhuis)
2010-05-14 one more fix for endianess detection (antirez)
2010-05-14 Fixed sha1.c compilation on Linux, due to endianess detection lameness (antirez)
2010-05-14 ZUNION,ZINTER -> ZUNIONSTORE,ZINTERSTORE (antirez)
2010-05-14 minor fixes to the new test suite, html doc updated (antirez)
2010-05-14 wait for redis-server to be settled and ready for connections (Pieter Noordhuis)
2010-05-14 fix cleaning up tmp folder (Pieter Noordhuis)
2010-05-14 update makefile to use the new test suite (Pieter Noordhuis)
2010-05-14 check for memory leaks before killing a server (Pieter Noordhuis)
2010-05-14 extract code to kill a server to a separate proc (Pieter Noordhuis)
2010-05-14 start servers on different ports to prevent conflicts (Pieter Noordhuis)
2010-05-14 use DEBUG DIGEST in new test suite (Pieter Noordhuis)
2010-05-14 split test suite into multiple files; runs redis-server in isolation (Pieter Noordhuis)
2010-05-14 use DEBUG DIGEST in the test instead of a function that was doing a similar work, but in a much slower and buggy way (antirez)
2010-05-14 Don't rely on cliReadReply being able to return on shutdown (Bruno Deferrari)
2010-05-14 If command is a shutdown, ignore errors on reply (Bruno Deferrari)
2010-05-14 DEBUG DIGEST implemented, in order to improve the ability to test persistence and replication consistency (antirez)
2010-05-13 makefile deps updated (antirez)
2010-05-13 conflicts resolved (antirez)
2010-05-13 feed SETEX as SET and EXPIREAT to AOF (Pieter Noordhuis)
2010-05-13 very strong speedup in saving time performance when there are many integers in the dataset. Instead of decoding the object before to pass them to the rdbSaveObject layer we check asap if the object is integer encoded and can be written on disk as an integer. (antirez)
2010-05-13 include limits.h otherwise no double precison macros (antirez)
2010-05-13 explicitly checks with ifdefs if our floating point and long long assumptions are verified (antirez)
2010-05-13 Yet another version of the double saving code, with comments explaining what's happening there (antirez)
2010-05-12 added overflow check in the double -> long long conversion trick to avoid integer overflows. I think this was not needed in practical terms, but it is safer (antirez)
2010-05-12 use withscores when performing the dataset digest (antirez)
2010-05-12 If a float can be casted to a long long without rounding loss, we can use the integer conversion function to write the score on disk. This is a seriuous speedup (antirez)
2010-05-12 fixed compilation warnings in the AOF sanity check tool (antirez)
2010-05-12 Merge branch 'vm-speedup' (antirez)
2010-05-11 fix to return error when calling INCR on a non-string type (Pieter Noordhuis)
2010-05-11 load objects encoded from disk directly without useless conversion (antirez)
2010-05-11 fixed a problem leading to crashes, as keys can't be currently specially encoded, so we can't encode integers at object loading time... For now this can be fixed passing a few flags, or later can be fixed allowing encoded keys as well (antirez)
2010-05-11 long long to string conversion speedup applied in other places as well. Still the code has bugs, fixing right now... (antirez)
2010-05-11 hand written code to turn a long long into a string -> very big speed win (antirez)
2010-05-11 added specialized function to compare string objects for perfect match that is optimized for this task (antirez)
2010-05-11 better use of encoding inforamtion in dictEncObjKeyCompare (antirez)
2010-05-10 CONFIG now can change appendfsync policy at run time (antirez)
2010-05-10 CONFIG command now supports hot modification of RDB saving parameters. (antirez)
2010-05-10 while loading the rdb file don't add the key to the dictionary at all if it's already expired, instead of removing it just after the insertion. (antirez)
2010-05-10 Merge branch 'check-aof' of git://github.com/pietern/redis (antirez)
2010-05-08 minor changes to improve code readability (antirez)
2010-05-08 swap objects out directly while loading an RDB file if we detect we can't stay in the vm max memory limits anyway (antirez)
2010-05-07 change command names no longer used to zunion/zinter (Pieter Noordhuis)
2010-05-07 DEBUG POPULATE command for fast creation of test databases (antirez)
2010-05-07 update TODO (Pieter Noordhuis)
2010-05-07 swap arguments in blockClientOnSwappedKeys to be consistent (Pieter Noordhuis)
2010-05-07 added function that preloads all keys needed to execute a MULTI/EXEC block (Pieter Noordhuis)
2010-05-07 add sanity check to zunionInterBlockClientOnSwappedKeys, as the number of keys used is provided as argument to the function (Pieter Noordhuis)
2010-05-07 make prototype of custom function to preload keys from the vm match the prototype of waitForMultipleSwappedKeys (Pieter Noordhuis)
2010-05-07 extract preloading of multiple keys according to the command prototype to a separate function (Pieter Noordhuis)
2010-05-07 make append only filename configurable (Pieter Noordhuis)
2010-05-07 don't load value from VM for EXISTS (Pieter Noordhuis)
2010-05-07 swap file name pid expansion removed. Not suited for mission critical software... (antirez)
2010-05-07 Swap file is now locked (antirez)
2010-05-06 Merge branch 'master' into aof-speedup (antirez)
2010-05-06 log error and quit when the AOF contains an unfinished MULTI (antirez)
2010-05-06 log error and quit when the AOF contains an unfinished MULTI (Pieter Noordhuis)
2010-05-06 Merge branch 'master' into check-aof (Pieter Noordhuis)
2010-05-06 hincrby should report an error when called against a hash key that doesn't contain an integer (Pieter Noordhuis)
2010-05-06 AOF writes are now accumulated into a buffer and flushed into disk just before re-entering the event loop. A lot less writes but still this guarantees that AOF is written before the client gets a positive reply about a write operation, as no reply is trasnmitted before re-entering into the event loop. (antirez)
2010-05-06 clarified a few messages in redis.conf (antirez)
2010-05-05 ask for confirmation before AOF is truncated (Pieter Noordhuis)
2010-05-05 str can be free'd outside readString (Pieter Noordhuis)
2010-05-05 moved argument parsing around (Pieter Noordhuis)
2010-05-05 ignore redis-check-aof binary (Pieter Noordhuis)
2010-05-05 allow AOF to be fixed by truncating to the portion of the file that is valid (Pieter Noordhuis)
2010-05-05 tool to check if AOF is valid (Pieter Noordhuis)
2010-05-02 included fmacros.h in linenose.c to avoid compilation warnings on Linux (antirez)
2010-05-02 compilation fix for mac os x (antirez)
2010-05-02 Merge branch 'master' of git@github.com:antirez/redis (antirez)
2010-05-02 On Linux now fdatasync() is used insetad of fsync() in order to flush the AOF file kernel buffers (antirez)
2010-04-30 More tests for APPEND and tests for SUBSTR (antirez)
2010-04-30 linenoise.c updated, now redis-cli can be used in a pipe (antirez) 2010-04-30 linenoise.c updated, now redis-cli can be used in a pipe (antirez)
2010-04-29 redis-cli minor fix (less segfault is better) (antirez) 2010-04-29 redis-cli minor fix (less segfault is better) (antirez)
2010-04-29 New MONITOR output format with timestamp, every command in a single line, string representations (antirez) 2010-04-29 New MONITOR output format with timestamp, every command in a single line, string representations (antirez)
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
# Copyright (C) 2009 Salvatore Sanfilippo <antirez at gmail dot com> # Copyright (C) 2009 Salvatore Sanfilippo <antirez at gmail dot com>
# This file is released under the BSD license, see the COPYING file # This file is released under the BSD license, see the COPYING file
release_hdr := $(shell sh -c './mkreleasehdr.sh')
uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
OPTIMIZATION?=-O2 OPTIMIZATION?=-O2
ifeq ($(uname_S),SunOS) ifeq ($(uname_S),SunOS)
...@@ -14,8 +15,6 @@ endif ...@@ -14,8 +15,6 @@ endif
CCOPT= $(CFLAGS) $(CCLINK) $(ARCH) $(PROF) CCOPT= $(CFLAGS) $(CCLINK) $(ARCH) $(PROF)
DEBUG?= -g -rdynamic -ggdb DEBUG?= -g -rdynamic -ggdb
GIT_SHA1:=$(shell sh -c '(git show-ref --head --hash=8 2> /dev/null || echo 00000000) | head -n1')
GIT_DIRTY:=$(shell sh -c 'git status -s 2> /dev/null | wc -l')
OBJ = adlist.o ae.o anet.o dict.o redis.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o OBJ = adlist.o ae.o anet.o dict.o redis.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o
BENCHOBJ = ae.o anet.o redis-benchmark.o sds.o adlist.o zmalloc.o BENCHOBJ = ae.o anet.o redis-benchmark.o sds.o adlist.o zmalloc.o
CLIOBJ = anet.o sds.o adlist.o redis-cli.o zmalloc.o linenoise.o CLIOBJ = anet.o sds.o adlist.o redis-cli.o zmalloc.o linenoise.o
...@@ -56,7 +55,7 @@ sds.o: sds.c sds.h zmalloc.h ...@@ -56,7 +55,7 @@ sds.o: sds.c sds.h zmalloc.h
zipmap.o: zipmap.c zmalloc.h zipmap.o: zipmap.c zmalloc.h
zmalloc.o: zmalloc.c config.h zmalloc.o: zmalloc.c config.h
redis-server: releaseheader $(OBJ) redis-server: $(OBJ)
$(CC) -o $(PRGNAME) $(CCOPT) $(DEBUG) $(OBJ) $(CC) -o $(PRGNAME) $(CCOPT) $(DEBUG) $(OBJ)
@echo "" @echo ""
@echo "Hint: To run the test-redis.tcl script is a good idea." @echo "Hint: To run the test-redis.tcl script is a good idea."
...@@ -76,11 +75,6 @@ redis-check-dump: $(CHECKDUMPOBJ) ...@@ -76,11 +75,6 @@ redis-check-dump: $(CHECKDUMPOBJ)
redis-check-aof: $(CHECKAOFOBJ) redis-check-aof: $(CHECKAOFOBJ)
$(CC) -o $(CHECKAOFPRGNAME) $(CCOPT) $(DEBUG) $(CHECKAOFOBJ) $(CC) -o $(CHECKAOFPRGNAME) $(CCOPT) $(DEBUG) $(CHECKAOFOBJ)
releaseheader:
@echo "#define REDIS_GIT_SHA1 \"$(GIT_SHA1)\"" > release.h
@echo "#define REDIS_GIT_DIRTY $(GIT_DIRTY)" >> release.h
@touch redis.c # force recompile of redis.c
.c.o: .c.o:
$(CC) -c $(CFLAGS) $(DEBUG) $(COMPILE_TIME) $< $(CC) -c $(CFLAGS) $(DEBUG) $(COMPILE_TIME) $<
......
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<link type="text/css" rel="stylesheet" href="style.css" />
</head>
<body>
<div id="page">
<div id='header'>
<a href="index.html">
<img style="border:none" alt="Redis Documentation" src="redis.png">
</a>
</div>
<div id="pagecontent">
<div class="index">
<!-- This is a (PRE) block. Make sure it's left aligned or your toc title will be off. -->
<b>AppendOnlyFileHowto: Contents</b><br>&nbsp;&nbsp;<a href="#Append Only File HOWTO">Append Only File HOWTO</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#General Information">General Information</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Log rewriting">Log rewriting</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Wait... but how does this work?">Wait... but how does this work?</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#How durable is the append only file?">How durable is the append only file?</a>
</div>
<h1 class="wikiname">AppendOnlyFileHowto</h1>
<div class="summary">
</div>
<div class="narrow">
&iuml;&raquo;&iquest;#sidebar <a href="RedisGuides.html">RedisGuides</a>
<h1><a name="Append Only File HOWTO">Append Only File HOWTO</a></h1><h2><a name="General Information">General Information</a></h2>Append only file is an alternative durability option for Redis. What this mean? Let's start with some fact:<br/><br/><ul><li> For default Redis saves snapshots of the dataset on disk, in a binary file called dump.rdb (by default at least). For instance you can configure Redis to save the dataset every 60 seconds if there are at least 100 changes in the dataset, or every 1000 seconds if there is at least a single change in the dataset. This is known as &quot;Snapshotting&quot;.</li><li> Snapshotting is not very durable. If your computer running Redis stops, your power line fails, or you write killall -9 redis-server for a mistake, the latest data written on Redis will get lost. There are applications where this is not a big deal. There are applications where this is not acceptable and Redis <b>was</b> not an option for this applications.</li></ul>
What is the solution? To use append only file as alternative to snapshotting. How it works?<br/><br/><ul><li> It is an 1.1 only feature.</li><li> You have to turn it on editing the configuration file. Just make sure you have &quot;appendonly yes&quot; somewhere.</li><li> Append only files work this way: every time Redis receive a command that changes the dataset (for instance a SET or LPUSH command) it appends this command in the append only file. When you restart Redis it will first <b>re-play</b> the append only file to rebuild the state.</li></ul>
<h2><a name="Log rewriting">Log rewriting</a></h2>As you can guess... the append log file gets bigger and bigger, every time there is a new operation changing the dataset. Even if you set always the same key &quot;mykey&quot; to the values of &quot;1&quot;, &quot;2&quot;, &quot;3&quot;, ... up to 10000000000 in the end you'll have just a single key in the dataset, just a few bytes! but how big will be the append log file? Very very big.<br/><br/>So Redis supports an interesting feature: it is able to rebuild the append log file, in background, without to stop processing client commands. The key is the command <a href="BGREWRITEAOF.html">BGREWRITEAOF</a>. This command basically is able to use the dataset in memory in order to rewrite the shortest sequence of commands able to rebuild the exact dataset that is currently in memory.<br/><br/>So from time to time when the log gets too big, try this command. It's safe as if it fails you will not lost your old log (but you can make a backup copy given that currently 1.1 is still in beta!).<h2><a name="Wait... but how does this work?">Wait... but how does this work?</a></h2>Basically it uses the same fork() copy-on-write trick that snapshotting already uses. This is how the algorithm works:<br/><br/><ul><li> Redis forks, so now we have a child and a parent.</li><li> The child starts writing the new append log file in a temporary file.</li><li> The parent accumulates all the new changes in an in-memory buffer (but at the same time it writes the new changes in the <b>old</b> append only file, so if the rewriting fails, we are safe).</li><li> When the child finished to rewrite the file, the parent gets a signal, and append the in-memory buffer at the end of the file generated by the child.</li><li> Profit! Now Redis atomically renames the old file into the new one, and starts appending new data into the new file.</li></ul>
<h2><a name="How durable is the append only file?">How durable is the append only file?</a></h2>Check redis.conf, you can configure how many times Redis will fsync() data on disk. There are three options:<br/><br/><ul><li> Fsync() every time a new command is appended to the append log file. Very very slow, very safe.</li><li> Fsync() one time every second. Fast enough, and you can lose 1 second of data if there is a disaster.</li><li> Never fsync(), just put your data in the hands of the Operating System. The faster and unsafer method.</li></ul>
Warning: by default Redis will fsync() after <b>every command</b>! This is because the Redis authors want to ship a default configuration that is the safest pick. But the best compromise for most datasets is to fsync() one time every second.
</div>
</div>
</div>
</body>
</html>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<link type="text/css" rel="stylesheet" href="style.css" />
</head>
<body>
<div id="page">
<div id='header'>
<a href="index.html">
<img style="border:none" alt="Redis Documentation" src="redis.png">
</a>
</div>
<div id="pagecontent">
<div class="index">
<!-- This is a (PRE) block. Make sure it's left aligned or your toc title will be off. -->
<b>AuthCommand: Contents</b><br>&nbsp;&nbsp;<a href="#AUTH _password_">AUTH _password_</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Return value">Return value</a>
</div>
<h1 class="wikiname">AuthCommand</h1>
<div class="summary">
</div>
<div class="narrow">
&iuml;&raquo;&iquest;#sidebar <a href="ConnectionHandlingSidebar.html">ConnectionHandlingSidebar</a><h1><a name="AUTH _password_">AUTH _password_</a></h1><blockquote>Request for authentication in a password protected Redis server.A Redis server can be instructed to require a password before to allow clientsto issue commands. This is done using the <i>requirepass</i> directive in theRedis configuration file.</blockquote>
<blockquote>If the password given by the client is correct the server replies withan OK status code reply and starts accepting commands from the client.Otherwise an error is returned and the clients needs to try a new password.Note that for the high performance nature of Redis it is possible to trya lot of passwords in parallel in very short time, so make sure to generatea strong and very long password so that this attack is infeasible.</blockquote>
<h2><a name="Return value">Return value</a></h2><a href="ReplyTypes.html">Status code reply</a>
</div>
</div>
</div>
</body>
</html>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<link type="text/css" rel="stylesheet" href="style.css" />
</head>
<body>
<div id="page">
<div id='header'>
<a href="index.html">
<img style="border:none" alt="Redis Documentation" src="redis.png">
</a>
</div>
<div id="pagecontent">
<div class="index">
<!-- This is a (PRE) block. Make sure it's left aligned or your toc title will be off. -->
<b>Benchmarks: Contents</b><br>&nbsp;&nbsp;<a href="#How Fast is Redis?">How Fast is Redis?</a><br>&nbsp;&nbsp;<a href="#Latency percentiles">Latency percentiles</a>
</div>
<h1 class="wikiname">Benchmarks</h1>
<div class="summary">
</div>
<div class="narrow">
<h1><a name="How Fast is Redis?">How Fast is Redis?</a></h1>Redis includes the <code name="code" class="python">redis-benchmark</code> utility that simulates <a href="SETs.html">SETs</a>/GETs done by N clients at the same time sending M total queries (it is similar to the Apache's <code name="code" class="python">ab</code> utility). Below you'll find the full output of the benchmark executed against a Linux box.<br/><br/><ul><li> The test was done with 50 simultaneous clients performing 100000 requests.</li><li> The value SET and GET is a 256 bytes string.</li><li> The Linux box is running <b>Linux 2.6</b>, it's <b>Xeon X3320 2.5Ghz</b>.</li><li> Text executed using the loopback interface (127.0.0.1).</li></ul>
Results: <b>about 110000 <a href="SETs.html">SETs</a> per second, about 81000 GETs per second.</b><h1><a name="Latency percentiles">Latency percentiles</a></h1><pre class="codeblock python" name="code">
./redis-benchmark -n 100000
====== SET ======
100007 requests completed in 0.88 seconds
50 parallel clients
3 bytes payload
keep alive: 1
58.50% &lt;= 0 milliseconds
99.17% &lt;= 1 milliseconds
99.58% &lt;= 2 milliseconds
99.85% &lt;= 3 milliseconds
99.90% &lt;= 6 milliseconds
100.00% &lt;= 9 milliseconds
114293.71 requests per second
====== GET ======
100000 requests completed in 1.23 seconds
50 parallel clients
3 bytes payload
keep alive: 1
43.12% &lt;= 0 milliseconds
96.82% &lt;= 1 milliseconds
98.62% &lt;= 2 milliseconds
100.00% &lt;= 3 milliseconds
81234.77 requests per second
====== INCR ======
100018 requests completed in 1.46 seconds
50 parallel clients
3 bytes payload
keep alive: 1
32.32% &lt;= 0 milliseconds
96.67% &lt;= 1 milliseconds
99.14% &lt;= 2 milliseconds
99.83% &lt;= 3 milliseconds
99.88% &lt;= 4 milliseconds
99.89% &lt;= 5 milliseconds
99.96% &lt;= 9 milliseconds
100.00% &lt;= 18 milliseconds
68458.59 requests per second
====== LPUSH ======
100004 requests completed in 1.14 seconds
50 parallel clients
3 bytes payload
keep alive: 1
62.27% &lt;= 0 milliseconds
99.74% &lt;= 1 milliseconds
99.85% &lt;= 2 milliseconds
99.86% &lt;= 3 milliseconds
99.89% &lt;= 5 milliseconds
99.93% &lt;= 7 milliseconds
99.96% &lt;= 9 milliseconds
100.00% &lt;= 22 milliseconds
100.00% &lt;= 208 milliseconds
88109.25 requests per second
====== LPOP ======
100001 requests completed in 1.39 seconds
50 parallel clients
3 bytes payload
keep alive: 1
54.83% &lt;= 0 milliseconds
97.34% &lt;= 1 milliseconds
99.95% &lt;= 2 milliseconds
99.96% &lt;= 3 milliseconds
99.96% &lt;= 4 milliseconds
100.00% &lt;= 9 milliseconds
100.00% &lt;= 208 milliseconds
71994.96 requests per second
</pre>Notes: changing the payload from 256 to 1024 or 4096 bytes does not change the numbers significantly (but reply packets are glued together up to 1024 bytes so GETs may be slower with big payloads). The same for the number of clients, from 50 to 256 clients I got the same numbers. With only 10 clients it starts to get a bit slower.<br/><br/>You can expect different results from different boxes. For example a low profile box like <b>Intel core duo T5500 clocked at 1.66Ghz running Linux 2.6</b> will output the following:
<pre class="codeblock python python" name="code">
./redis-benchmark -q -n 100000
SET: 53684.38 requests per second
GET: 45497.73 requests per second
INCR: 39370.47 requests per second
LPUSH: 34803.41 requests per second
LPOP: 37367.20 requests per second
</pre>Another one using a 64 bit box, a Xeon L5420 clocked at 2.5 Ghz:<br/><br/><pre class="codeblock python python python" name="code">
./redis-benchmark -q -n 100000
PING: 111731.84 requests per second
SET: 108114.59 requests per second
GET: 98717.67 requests per second
INCR: 95241.91 requests per second
LPUSH: 104712.05 requests per second
LPOP: 93722.59 requests per second
</pre>
</div>
</div>
</div>
</body>
</html>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<link type="text/css" rel="stylesheet" href="style.css" />
</head>
<body>
<div id="page">
<div id='header'>
<a href="index.html">
<img style="border:none" alt="Redis Documentation" src="redis.png">
</a>
</div>
<div id="pagecontent">
<div class="index">
<!-- This is a (PRE) block. Make sure it's left aligned or your toc title will be off. -->
<b>BgrewriteaofCommand: Contents</b><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#BGREWRITEAOF">BGREWRITEAOF</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Return value">Return value</a>
</div>
<h1 class="wikiname">BgrewriteaofCommand</h1>
<div class="summary">
</div>
<div class="narrow">
&iuml;&raquo;&iquest;#sidebar <a href="ControlCommandsSidebar.html">ControlCommandsSidebar</a><h3><a name="BGREWRITEAOF">BGREWRITEAOF</a></h3>
<blockquote>Please for detailed information about the Redis Append Only File check<a href="AppendOnlyFileHowto.html">the Append Only File Howto</a>.</blockquote>
<blockquote>BGREWRITEAOF rewrites the Append Only File in background when it gets toobig. The Redis Append Only File is a Journal, so every operation modifyingthe dataset is logged in the Append Only File (and replayed at startup).This means that the Append Only File always grows. In order to rebuildits content the BGREWRITEAOF creates a new version of the append only filestarting directly form the dataset in memory in order to guarantee thegeneration of the minimal number of commands needed to rebuild the database.</blockquote>
<blockquote>The <a href="AppendOnlyFileHowto.html">Append Only File Howto</a> contains further details.</blockquote>
<h2><a name="Return value">Return value</a></h2><a href="ReplyTypes.html">Status code reply</a>
</div>
</div>
</div>
</body>
</html>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<link type="text/css" rel="stylesheet" href="style.css" />
</head>
<body>
<div id="page">
<div id='header'>
<a href="index.html">
<img style="border:none" alt="Redis Documentation" src="redis.png">
</a>
</div>
<div id="pagecontent">
<div class="index">
<!-- This is a (PRE) block. Make sure it's left aligned or your toc title will be off. -->
<b>BgsaveCommand: Contents</b><br>&nbsp;&nbsp;<a href="#BGSAVE">BGSAVE</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Return value">Return value</a>
</div>
<h1 class="wikiname">BgsaveCommand</h1>
<div class="summary">
</div>
<div class="narrow">
&iuml;&raquo;&iquest;#sidebar <a href="ControlCommandsSidebar.html">ControlCommandsSidebar</a><h1><a name="BGSAVE">BGSAVE</a></h1>
<blockquote>Save the DB in background. The OK code is immediately returned.Redis forks, the parent continues to server the clients, the childsaves the DB on disk then exit. A client my be able to check if theoperation succeeded using the <a href="LastsaveCommand.html">LASTSAVE</a> command.</blockquote>
<h2><a name="Return value">Return value</a></h2><a href="ReplyTypes.html">Status code reply</a>
</div>
</div>
</div>
</body>
</html>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<link type="text/css" rel="stylesheet" href="style.css" />
</head>
<body>
<div id="page">
<div id='header'>
<a href="index.html">
<img style="border:none" alt="Redis Documentation" src="redis.png">
</a>
</div>
<div id="pagecontent">
<div class="index">
<!-- This is a (PRE) block. Make sure it's left aligned or your toc title will be off. -->
<b>CommandReference: Contents</b><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Connection handling">Connection handling</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Commands operating on all the kind of values">Commands operating on all the kind of values</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Commands operating on string values">Commands operating on string values</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Commands operating on lists">Commands operating on lists</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Commands operating on sets">Commands operating on sets</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Commands operating on sorted sets (zsets, Redis version &gt;">Commands operating on sorted sets (zsets, Redis version &gt;</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Commands operating on hashes">Commands operating on hashes</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Sorting">Sorting</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Transactions">Transactions</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Publish/Subscribe">Publish/Subscribe</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Persistence control commands">Persistence control commands</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Remote server control commands">Remote server control commands</a>
</div>
<h1 class="wikiname">CommandReference</h1>
<div class="summary">
</div>
<div class="narrow">
&iuml;&raquo;&iquest;= Redis Command Reference =<br/><br/>Every command name links to a specific wiki page describing the behavior of the command.<h2><a name="Connection handling">Connection handling</a></h2><ul><li> <a href="QuitCommand.html">QUIT</a> <code name="code" class="python">close the connection</code></li><li> <a href="AuthCommand.html">AUTH</a> <code name="code" class="python">simple password authentication if enabled</code></li></ul>
<h2><a name="Commands operating on all the kind of values">Commands operating on all the kind of values</a></h2><ul><li> <a href="ExistsCommand.html">EXISTS</a> <i>key</i> <code name="code" class="python">test if a key exists</code></li><li> <a href="DelCommand.html">DEL</a> <i>key</i> <code name="code" class="python">delete a key</code></li><li> <a href="TypeCommand.html">TYPE</a> <i>key</i> <code name="code" class="python">return the type of the value stored at key</code></li><li> <a href="KeysCommand.html">KEYS</a> <i>pattern</i> <code name="code" class="python">return all the keys matching a given pattern</code></li><li> <a href="RandomkeyCommand.html">RANDOMKEY</a> <code name="code" class="python">return a random key from the key space</code></li><li> <a href="RenameCommand.html">RENAME</a> <i>oldname</i> <i>newname</i> <code name="code" class="python">rename the old key in the new one, destroing the newname key if it already exists</code></li><li> <a href="RenamenxCommand.html">RENAMENX</a> <i>oldname</i> <i>newname</i> <code name="code" class="python">rename the old key in the new one, if the newname key does not already exist</code></li><li> <a href="DbsizeCommand.html">DBSIZE</a> <code name="code" class="python">return the number of keys in the current db</code></li><li> <a href="ExpireCommand.html">EXPIRE</a> <code name="code" class="python">set a time to live in seconds on a key</code></li><li> <a href="TtlCommand.html">TTL</a> <code name="code" class="python">get the time to live in seconds of a key</code></li><li> <a href="SelectCommand.html">SELECT</a> <i>index</i> <code name="code" class="python">Select the DB having the specified index</code></li><li> <a href="MoveCommand.html">MOVE</a> <i>key</i> <i>dbindex</i> <code name="code" class="python">Move the key from the currently selected DB to the DB having as index dbindex</code></li><li> <a href="FlushdbCommand.html">FLUSHDB</a> <code name="code" class="python">Remove all the keys of the currently selected DB</code></li><li> <a href="FlushallCommand.html">FLUSHALL</a> <code name="code" class="python">Remove all the keys from all the databases</code></li></ul>
<h2><a name="Commands operating on string values">Commands operating on string values</a></h2><ul><li> <a href="SetCommand.html">SET</a> <i>key</i> <i>value</i> <code name="code" class="python">set a key to a string value</code></li><li> <a href="GetCommand.html">GET</a> <i>key</i> <code name="code" class="python">return the string value of the key</code></li><li> <a href="GetsetCommand.html">GETSET</a> <i>key</i> <i>value</i> <code name="code" class="python">set a key to a string returning the old value of the key</code></li><li> <a href="MgetCommand.html">MGET</a> <i>key1</i> <i>key2</i> ... <i>keyN</i> <code name="code" class="python">multi-get, return the strings values of the keys</code></li><li> <a href="SetnxCommand.html">SETNX</a> <i>key</i> <i>value</i> <code name="code" class="python">set a key to a string value if the key does not exist</code></li><li> <a href="SetexCommand.html">SETEX</a> <i>key</i> <i>time</i> <i>value</i> <code name="code" class="python">Set+Expire combo command</code></li><li> <a href="MsetCommand.html">MSET</a> <i>key1</i> <i>value1</i> <i>key2</i> <i>value2</i> ... <i>keyN</i> <i>valueN</i> <code name="code" class="python">set a multiple keys to multiple values in a single atomic operation</code></li><li> <a href="MsetCommand.html">MSETNX</a> <i>key1</i> <i>value1</i> <i>key2</i> <i>value2</i> ... <i>keyN</i> <i>valueN</i> <code name="code" class="python">set a multiple keys to multiple values in a single atomic operation if none of the keys already exist</code></li><li> <a href="IncrCommand.html">INCR</a> <i>key</i> <code name="code" class="python">increment the integer value of key</code></li><li> <a href="IncrCommand.html">INCRBY</a> <i>key</i> <i>integer</i><code name="code" class="python"> increment the integer value of key by integer</code></li><li> <a href="IncrCommand.html">DECR</a> <i>key</i> <code name="code" class="python">decrement the integer value of key</code></li><li> <a href="IncrCommand.html">DECRBY</a> <i>key</i> <i>integer</i> <code name="code" class="python">decrement the integer value of key by integer</code></li><li> <a href="AppendCommand.html">APPEND</a> <i>key</i> <i>value</i> <code name="code" class="python">append the specified string to the string stored at key</code></li><li> <a href="SubstrCommand.html">SUBSTR</a> <i>key</i> <i>start</i> <i>end</i> <code name="code" class="python">return a substring out of a larger string</code></li></ul>
<h2><a name="Commands operating on lists">Commands operating on lists</a></h2><ul><li> <a href="RpushCommand.html">RPUSH</a> <i>key</i> <i>value</i> <code name="code" class="python">Append an element to the tail of the List value at key</code></li><li> <a href="RpushCommand.html">LPUSH</a> <i>key</i> <i>value</i> <code name="code" class="python">Append an element to the head of the List value at key</code></li><li> <a href="LlenCommand.html">LLEN</a> <i>key</i> <code name="code" class="python">Return the length of the List value at key</code></li><li> <a href="LrangeCommand.html">LRANGE</a> <i>key</i> <i>start</i> <i>end</i> <code name="code" class="python">Return a range of elements from the List at key</code></li><li> <a href="LtrimCommand.html">LTRIM</a> <i>key</i> <i>start</i> <i>end</i> <code name="code" class="python">Trim the list at key to the specified range of elements</code></li><li> <a href="LindexCommand.html">LINDEX</a> <i>key</i> <i>index</i> <code name="code" class="python">Return the element at index position from the List at key</code></li><li> <a href="LsetCommand.html">LSET</a> <i>key</i> <i>index</i> <i>value</i> <code name="code" class="python">Set a new value as the element at index position of the List at key</code></li><li> <a href="LremCommand.html">LREM</a> <i>key</i> <i>count</i> <i>value</i> <code name="code" class="python">Remove the first-N, last-N, or all the elements matching value from the List at key</code></li><li> <a href="LpopCommand.html">LPOP</a> <i>key</i> <code name="code" class="python">Return and remove (atomically) the first element of the List at key</code></li><li> <a href="LpopCommand.html">RPOP</a> <i>key</i> <code name="code" class="python">Return and remove (atomically) the last element of the List at key</code></li><li> <a href="BlpopCommand.html">BLPOP</a> <i>key1</i> <i>key2</i> ... <i>keyN</i> <i>timeout</i> <code name="code" class="python">Blocking LPOP</code></li><li> <a href="BlpopCommand.html">BRPOP</a> <i>key1</i> <i>key2</i> ... <i>keyN</i> <i>timeout</i> <code name="code" class="python">Blocking RPOP</code></li><li> <a href="RpoplpushCommand.html">RPOPLPUSH</a> <i>srckey</i> <i>dstkey</i> <code name="code" class="python">Return and remove (atomically) the last element of the source List stored at _srckey_ and push the same element to the destination List stored at _dstkey_</code></li></ul>
<h2><a name="Commands operating on sets">Commands operating on sets</a></h2><ul><li> <a href="SaddCommand.html">SADD</a> <i>key</i> <i>member</i> <code name="code" class="python">Add the specified member to the Set value at key</code></li><li> <a href="SremCommand.html">SREM</a> <i>key</i> <i>member</i> <code name="code" class="python">Remove the specified member from the Set value at key</code></li><li> <a href="SpopCommand.html">SPOP</a> <i>key</i> <code name="code" class="python">Remove and return (pop) a random element from the Set value at key</code></li><li> <a href="SmoveCommand.html">SMOVE</a> <i>srckey</i> <i>dstkey</i> <i>member</i> <code name="code" class="python">Move the specified member from one Set to another atomically</code></li><li> <a href="ScardCommand.html">SCARD</a> <i>key</i> <code name="code" class="python">Return the number of elements (the cardinality) of the Set at key</code></li><li> <a href="SismemberCommand.html">SISMEMBER</a> <i>key</i> <i>member</i> <code name="code" class="python">Test if the specified value is a member of the Set at key</code></li><li> <a href="SinterCommand.html">SINTER</a> <i>key1</i> <i>key2</i> ... <i>keyN</i> <code name="code" class="python">Return the intersection between the Sets stored at key1, key2, ..., keyN</code></li><li> <a href="SinterstoreCommand.html">SINTERSTORE</a> <i>dstkey</i> <i>key1</i> <i>key2</i> ... <i>keyN</i> <code name="code" class="python">Compute the intersection between the Sets stored at key1, key2, ..., keyN, and store the resulting Set at dstkey</code></li><li> <a href="SunionCommand.html">SUNION</a> <i>key1</i> <i>key2</i> ... <i>keyN</i> <code name="code" class="python">Return the union between the Sets stored at key1, key2, ..., keyN</code></li><li> <a href="SunionstoreCommand.html">SUNIONSTORE</a> <i>dstkey</i> <i>key1</i> <i>key2</i> ... <i>keyN</i> <code name="code" class="python">Compute the union between the Sets stored at key1, key2, ..., keyN, and store the resulting Set at dstkey</code></li><li> <a href="SdiffCommand.html">SDIFF</a> <i>key1</i> <i>key2</i> ... <i>keyN</i> <code name="code" class="python">Return the difference between the Set stored at key1 and all the Sets key2, ..., keyN</code></li><li> <a href="SdiffstoreCommand.html">SDIFFSTORE</a> <i>dstkey</i> <i>key1</i> <i>key2</i> ... <i>keyN</i> <code name="code" class="python">Compute the difference between the Set key1 and all the Sets key2, ..., keyN, and store the resulting Set at dstkey</code></li><li> <a href="SmembersCommand.html">SMEMBERS</a> <i>key</i> <code name="code" class="python">Return all the members of the Set value at key</code></li><li> <a href="SrandmemberCommand.html">SRANDMEMBER</a> <i>key</i> <code name="code" class="python">Return a random member of the Set value at key</code></li></ul>
<h2><a name="Commands operating on sorted sets (zsets, Redis version &gt;">Commands operating on sorted sets (zsets, Redis version &gt;</a></h2> 1.1) ==<br/><br/><ul><li> <a href="ZaddCommand.html">ZADD</a> <i>key</i> <i>score</i> <i>member</i> <code name="code" class="python">Add the specified member to the Sorted Set value at key or update the score if it already exist</code></li><li> <a href="ZremCommand.html">ZREM</a> <i>key</i> <i>member</i> <code name="code" class="python">Remove the specified member from the Sorted Set value at key</code></li><li> <a href="ZincrbyCommand.html">ZINCRBY</a> <i>key</i> <i>increment</i> <i>member</i> <code name="code" class="python">If the member already exists increment its score by _increment_, otherwise add the member setting _increment_ as score</code></li><li> <a href="ZrankCommand.html">ZRANK</a> <i>key</i> <i>member</i> <code name="code" class="python">Return the rank (or index) or _member_ in the sorted set at _key_, with scores being ordered from low to high</code></li><li> <a href="ZrankCommand.html">ZREVRANK</a> <i>key</i> <i>member</i> <code name="code" class="python">Return the rank (or index) or _member_ in the sorted set at _key_, with scores being ordered from high to low</code></li><li> <a href="ZrangeCommand.html">ZRANGE</a> <i>key</i> <i>start</i> <i>end</i> <code name="code" class="python">Return a range of elements from the sorted set at key</code></li><li> <a href="ZrangeCommand.html">ZREVRANGE</a> <i>key</i> <i>start</i> <i>end</i> <code name="code" class="python">Return a range of elements from the sorted set at key, exactly like ZRANGE, but the sorted set is ordered in traversed in reverse order, from the greatest to the smallest score</code></li><li> <a href="ZrangebyscoreCommand.html">ZRANGEBYSCORE</a> <i>key</i> <i>min</i> <i>max</i> <code name="code" class="python">Return all the elements with score &gt;= min and score &lt;= max (a range query) from the sorted set</code></li><li> <a href="ZcardCommand.html">ZCARD</a> <i>key</i> <code name="code" class="python">Return the cardinality (number of elements) of the sorted set at key</code></li><li> <a href="ZscoreCommand.html">ZSCORE</a> <i>key</i> <i>element</i> <code name="code" class="python">Return the score associated with the specified element of the sorted set at key</code></li><li> <a href="ZremrangebyrankCommand.html">ZREMRANGEBYRANK</a> <i>key</i> <i>min</i> <i>max</i> <code name="code" class="python">Remove all the elements with rank &gt;= min and rank &lt;= max from the sorted set</code></li><li> <a href="ZremrangebyscoreCommand.html">ZREMRANGEBYSCORE</a> <i>key</i> <i>min</i> <i>max</i> <code name="code" class="python">Remove all the elements with score &gt;= min and score &lt;= max from the sorted set</code></li><li> <a href="ZunionstoreCommand.html">ZUNIONSTORE / ZINTERSTORE</a> <i>dstkey</i> <i>N</i> <i>key1</i> ... <i>keyN</i> WEIGHTS <i>w1</i> ... <i>wN</i> AGGREGATE SUM|MIN|MAX <code name="code" class="python">Perform a union or intersection over a number of sorted sets with optional weight and aggregate</code></li></ul>
<h2><a name="Commands operating on hashes">Commands operating on hashes</a></h2><ul><li> <a href="HsetCommand.html">HSET</a> <i>key</i> <i>field</i> <i>value</i> <code name="code" class="python">Set the hash field to the specified value. Creates the hash if needed.</code></li><li> <a href="HgetCommand.html">HGET</a> <i>key</i> <i>field</i> <code name="code" class="python">Retrieve the value of the specified hash field.</code></li><li> <a href="HmsetCommand.html">HMSET</a> <i>key</i> <i>field1</i> <i>value1</i> ... <i>fieldN</i> <i>valueN</i> <code name="code" class="python">Set the hash fields to their respective values.</code></li><li> <a href="HincrbyCommand.html">HINCRBY</a> <i>key</i> <i>field</i> <i>integer</i> <code name="code" class="python">Increment the integer value of the hash at _key_ on _field_ with _integer_.</code></li><li> <a href="HexistsCommand.html">HEXISTS</a> <i>key</i> <i>field</i> <code name="code" class="python">Test for existence of a specified field in a hash</code></li><li> <a href="HdelCommand.html">HDEL</a> <i>key</i> <i>field</i> <code name="code" class="python">Remove the specified field from a hash</code></li><li> <a href="HlenCommand.html">HLEN</a> <i>key</i> <code name="code" class="python">Return the number of items in a hash.</code></li><li> <a href="HgetallCommand.html">HKEYS</a> <i>key</i> <code name="code" class="python">Return all the fields in a hash.</code></li><li> <a href="HgetallCommand.html">HVALS</a> <i>key</i> <code name="code" class="python">Return all the values in a hash.</code></li><li> <a href="HgetallCommand.html">HGETALL</a> <i>key</i> <code name="code" class="python">Return all the fields and associated values in a hash.</code></li></ul>
<h2><a name="Sorting">Sorting</a></h2><ul><li> <a href="SortCommand.html">SORT</a> <i>key</i> BY <i>pattern</i> LIMIT <i>start</i> <i>end</i> GET <i>pattern</i> ASC|DESC ALPHA <code name="code" class="python">Sort a Set or a List accordingly to the specified parameters</code></li></ul>
<h2><a name="Transactions">Transactions</a></h2><ul><li> <a href="MultiExecCommand.html">MULTI/EXEC/DISCARD</a> <code name="code" class="python">Redis atomic transactions</code></li></ul>
<h2><a name="Publish/Subscribe">Publish/Subscribe</a></h2><ul><li> <a href="PublishSubscribe.html">SUBSCRIBE/UNSUBSCRIBE/PUBLISH</a> <code name="code" class="python">Redis Public/Subscribe messaging paradigm implementation</code></li></ul>
<h2><a name="Persistence control commands">Persistence control commands</a></h2><ul><li> <a href="SaveCommand.html">SAVE</a> <code name="code" class="python">Synchronously save the DB on disk</code></li><li> <a href="BgsaveCommand.html">BGSAVE</a> <code name="code" class="python">Asynchronously save the DB on disk</code></li><li> <a href="LastsaveCommand.html">LASTSAVE</a> <code name="code" class="python">Return the UNIX time stamp of the last successfully saving of the dataset on disk</code></li><li> <a href="ShutdownCommand.html">SHUTDOWN</a> <code name="code" class="python">Synchronously save the DB on disk, then shutdown the server</code></li><li> <a href="BgrewriteaofCommand.html">BGREWRITEAOF</a> <code name="code" class="python">Rewrite the append only file in background when it gets too big</code></li></ul>
<h2><a name="Remote server control commands">Remote server control commands</a></h2><ul><li> <a href="InfoCommand.html">INFO</a> <code name="code" class="python">Provide information and statistics about the server</code></li><li> <a href="MonitorCommand.html">MONITOR</a> <code name="code" class="python">Dump all the received requests in real time</code></li><li> <a href="SlaveofCommand.html">SLAVEOF</a> <code name="code" class="python">Change the replication settings</code></li></ul>
</div>
</div>
</div>
</body>
</html>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<link type="text/css" rel="stylesheet" href="style.css" />
</head>
<body>
<div id="page">
<div id='header'>
<a href="index.html">
<img style="border:none" alt="Redis Documentation" src="redis.png">
</a>
</div>
<div id="pagecontent">
<div class="index">
<!-- This is a (PRE) block. Make sure it's left aligned or your toc title will be off. -->
<b>Comparisons: Contents</b><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Memcached">Memcached</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Tokyo Cabinet / Toyo Tyrant">Tokyo Cabinet / Toyo Tyrant</a>
</div>
<h1 class="wikiname">Comparisons</h1>
<div class="summary">
</div>
<div class="narrow">
&iuml;&raquo;&iquest;if your are asking yourself how is Redis different fom other key-value stores here you will find it compared to some of the most popular contendors (all great software) in this category. <h2><a name="Memcached">Memcached</a></h2><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, while Redis is <a href="Persistence.html">persistent</a>.</li></ul>
<ul><li> Like memcached Redis uses a key-value model, but while keys can just be strings, values in Redis can be <a href="Lists.html">Lists</a>, <a href="Sets.html">Sets</a> or <a href="SortedSets.html">SortedSets</a> and complex operations like intersections, set/get n-th element of lists, pop/push of elements, can be performed against sets and lists.</li></ul>
<h2><a name="Tokyo Cabinet / Toyo Tyrant">Tokyo Cabinet / Toyo Tyrant</a></h2>Redis and Tokyo Cabinet can be used for the same applications, but actually they are <i>very different</i> 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.<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, Sorting of schema free data in complex ways (By the way 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 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>
</div>
</div>
</div>
</body>
</html>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<link type="text/css" rel="stylesheet" href="style.css" />
</head>
<body>
<div id="page">
<div id='header'>
<a href="index.html">
<img style="border:none" alt="Redis Documentation" src="redis.png">
</a>
</div>
<div id="pagecontent">
<div class="index">
<!-- This is a (PRE) block. Make sure it's left aligned or your toc title will be off. -->
<b>Configuration: Contents</b>
</div>
<h1 class="wikiname">Configuration</h1>
<div class="summary">
</div>
<div class="narrow">
The <code name="code" class="python">redis.conf</code> file included in the source code distribution is a starting point, you should be able to modify it in order do adapt it to your needs without troubles reading the comments inside the file.<br/><br/>In order to start Redis using a configuration file just pass the file name as the sole argument when starting the server:<br/><br/><pre class="codeblock python" name="code">
$ ./redis-server redis.conf
</pre>
</div>
</div>
</div>
</body>
</html>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<link type="text/css" rel="stylesheet" href="style.css" />
</head>
<body>
<div id="page">
<div id='header'>
<a href="index.html">
<img style="border:none" alt="Redis Documentation" src="redis.png">
</a>
</div>
<div id="pagecontent">
<div class="index">
<!-- This is a (PRE) block. Make sure it's left aligned or your toc title will be off. -->
<b>ConnectionHandlingSidebar: Contents</b>
</div>
<h1 class="wikiname">ConnectionHandlingSidebar</h1>
<div class="summary">
</div>
<div class="narrow">
&iuml;&raquo;&iquest;== Connection handling ==<br/><br/><ul><li> <a href="QuitCommand.html">QUIT</a></li><li> <a href="AuthCommand.html">AUTH</a></li></ul>
</div>
</div>
</div>
</body>
</html>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<link type="text/css" rel="stylesheet" href="style.css" />
</head>
<body>
<div id="page">
<div id='header'>
<a href="index.html">
<img style="border:none" alt="Redis Documentation" src="redis.png">
</a>
</div>
<div id="pagecontent">
<div class="index">
<!-- This is a (PRE) block. Make sure it's left aligned or your toc title will be off. -->
<b>ControlCommandsSidebar: Contents</b>
</div>
<h1 class="wikiname">ControlCommandsSidebar</h1>
<div class="summary">
</div>
<div class="narrow">
&iuml;&raquo;&iquest;== Control Commands ==<br/><br/><ul><li> <a href="SaveCommand.html">SAVE</a></li><li> <a href="BgsaveCommand.html">BGSAVE</a></li><li> <a href="BgrewriteaofCommand.html">BGREWRITEAOF</a></li><li> <a href="LastsaveCommand.html">LASTSAVE</a></li><li> <a href="ShutdownCommand.html">SHUTDOWN</a></li><li> <a href="InfoCommand.html">INFO</a></li><li> <a href="MonitorCommand.html">MONITOR</a></li><li> <a href="SlaveofCommand.html">SLAVEOF</a></li></ul>
</div>
</div>
</div>
</body>
</html>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<link type="text/css" rel="stylesheet" href="style.css" />
</head>
<body>
<div id="page">
<div id='header'>
<a href="index.html">
<img style="border:none" alt="Redis Documentation" src="redis.png">
</a>
</div>
<div id="pagecontent">
<div class="index">
<!-- This is a (PRE) block. Make sure it's left aligned or your toc title will be off. -->
<b>Credits: Contents</b><br>&nbsp;&nbsp;<a href="#Credits">Credits</a>
</div>
<h1 class="wikiname">Credits</h1>
<div class="summary">
</div>
<div class="narrow">
<h1><a name="Credits">Credits</a></h1><ul><li> The Redis server was designed and written by <a href="http://invece.org" target="_blank">Salvatore Sanfilippo (aka antirez)</a></li><li> <a href="http://brainspl.at/" target="_blank">Ezra Zygmuntowicz (aka ezmobius)</a> - Ruby client lib initial version and hacking</li><li> <a href="http://qix.it" target="_blank">Ludovico Magnocavallo (aka ludo)</a> - Python clinet lib</li><li> <a href="http://www.adroll.com/" target="_blank">Valentino Volonghi of Adroll</a> - Erlang client lib</li><li> <b>brettbender</b> - found and fixed a bug in sds.c that caused the server to crash at least on 64 bit systems, and anyway to be buggy since we used the same vararg thing against vsprintf without to call va_start and va_end every time.</li><li> <a href="http://www.rot13.org/~dpavlin" target="_blank">Dobrica Pavlinusic</a> - Perl client lib</li><li> Brian Hammond - AUTH command implementation, C++ client lib</li><li> <a href="http://www.clorophilla.net/" target="_blank">Daniele Alessandri</a> - Lua client lib</li><li> Corey Stup - C99 cleanups</li><li> Taylor Weibley - Ruby client improvements</li><li> Bob Potter - Rearrange redisObject struct to reduce memory usage in 64bit environments</li><li> Luca Guidi and Brian McKinney - Ruby client improvements</li><li> Aman Gupta - SDIFF / SDIFFSTORE, other Set operations improvements, ability to disable clients timeout.</li><li> Diego Rosario Brogna - Code and ideas about dumping backtrace on sigsegv and similar error conditions.</li></ul>
p.s. sorry to take this file in sync is hard in this early days. Please drop me an email if I forgot to add your name here!
</div>
</div>
</div>
</body>
</html>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<link type="text/css" rel="stylesheet" href="style.css" />
</head>
<body>
<div id="page">
<div id='header'>
<a href="index.html">
<img style="border:none" alt="Redis Documentation" src="redis.png">
</a>
</div>
<div id="pagecontent">
<div class="index">
<!-- This is a (PRE) block. Make sure it's left aligned or your toc title will be off. -->
<b>DbsizeCommand: Contents</b><br>&nbsp;&nbsp;<a href="#DBSIZE">DBSIZE</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Return value">Return value</a>
</div>
<h1 class="wikiname">DbsizeCommand</h1>
<div class="summary">
</div>
<div class="narrow">
&iuml;&raquo;&iquest;#sidebar <a href="GenericCommandsSidebar.html">GenericCommandsSidebar</a><h1><a name="DBSIZE">DBSIZE</a></h1><blockquote>Return the number of keys in the currently selected database.</blockquote>
<h2><a name="Return value">Return value</a></h2><a href="ReplyTypes.html">Integer reply</a>
</div>
</div>
</div>
</body>
</html>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<link type="text/css" rel="stylesheet" href="style.css" />
</head>
<body>
<div id="page">
<div id='header'>
<a href="index.html">
<img style="border:none" alt="Redis Documentation" src="redis.png">
</a>
</div>
<div id="pagecontent">
<div class="index">
<!-- This is a (PRE) block. Make sure it's left aligned or your toc title will be off. -->
<b>DelCommand: Contents</b><br>&nbsp;&nbsp;<a href="#DEL _key1_ _key2_ ... _keyN_">DEL _key1_ _key2_ ... _keyN_</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Return value">Return value</a>
</div>
<h1 class="wikiname">DelCommand</h1>
<div class="summary">
</div>
<div class="narrow">
&iuml;&raquo;&iquest;#sidebar <a href="GenericCommandsSidebar.html">GenericCommandsSidebar</a><h1><a name="DEL _key1_ _key2_ ... _keyN_">DEL _key1_ _key2_ ... _keyN_</a></h1>
<i>Time complexity: O(1)</i><blockquote>Remove the specified keys. If a given key does not existno operation is performed for this key. The commnad returns the number ofkeys removed.</blockquote>
<h2><a name="Return value">Return value</a></h2><a href="ReplyTypes.html">Integer reply</a>, specifically:<br/><br/><pre class="codeblock python" name="code">
an integer greater than 0 if one or more keys were removed
0 if none of the specified key existed
</pre>
</div>
</div>
</div>
</body>
</html>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<link type="text/css" rel="stylesheet" href="style.css" />
</head>
<body>
<div id="page">
<div id='header'>
<a href="index.html">
<img style="border:none" alt="Redis Documentation" src="redis.png">
</a>
</div>
<div id="pagecontent">
<div class="index">
<!-- This is a (PRE) block. Make sure it's left aligned or your toc title will be off. -->
<b>DesignPatterns: Contents</b>
</div>
<h1 class="wikiname">DesignPatterns</h1>
<div class="summary">
</div>
<div class="narrow">
Use random keys instead of incremental keys in order to avoid a single-key that gets incremented by many servers. This can can't be distributed among servers.
</div>
</div>
</div>
</body>
</html>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<link type="text/css" rel="stylesheet" href="style.css" />
</head>
<body>
<div id="page">
<div id='header'>
<a href="index.html">
<img style="border:none" alt="Redis Documentation" src="redis.png">
</a>
</div>
<div id="pagecontent">
<div class="index">
<!-- This is a (PRE) block. Make sure it's left aligned or your toc title will be off. -->
<b>ExistsCommand: Contents</b><br>&nbsp;&nbsp;<a href="#EXISTS _key_">EXISTS _key_</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Return value">Return value</a>
</div>
<h1 class="wikiname">ExistsCommand</h1>
<div class="summary">
</div>
<div class="narrow">
&iuml;&raquo;&iquest;#sidebar <a href="GenericCommandsSidebar.html">GenericCommandsSidebar</a><h1><a name="EXISTS _key_">EXISTS _key_</a></h1>
<i>Time complexity: O(1)</i><blockquote>Test if the specified key exists. The command returns&quot;0&quot; if the key exists, otherwise &quot;1&quot; is returned.Note that even keys set with an empty string as value willreturn &quot;1&quot;.</blockquote>
<h2><a name="Return value">Return value</a></h2><a href="ReplyTypes.html">Integer reply</a>, specifically:<br/><br/><pre class="codeblock python" name="code">
1 if the key exists.
0 if the key does not exist.
</pre>
</div>
</div>
</div>
</body>
</html>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<link type="text/css" rel="stylesheet" href="style.css" />
</head>
<body>
<div id="page">
<div id='header'>
<a href="index.html">
<img style="border:none" alt="Redis Documentation" src="redis.png">
</a>
</div>
<div id="pagecontent">
<div class="index">
<!-- This is a (PRE) block. Make sure it's left aligned or your toc title will be off. -->
<b>ExpireCommand: Contents</b><br>&nbsp;&nbsp;<a href="#EXPIRE _key_ _seconds_">EXPIRE _key_ _seconds_</a><br>&nbsp;&nbsp;<a href="#EXPIREAT _key_ _unixtime_ (Redis &gt;">EXPIREAT _key_ _unixtime_ (Redis &gt;</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#How the expire is removed from a key">How the expire is removed from a key</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Restrictions with write operations against volatile keys">Restrictions with write operations against volatile keys</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Setting the timeout again on already volatile keys">Setting the timeout again on already volatile keys</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Enhanced Lazy Expiration algorithm">Enhanced Lazy Expiration algorithm</a><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Version 1.0">Version 1.0</a><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Version 1.1">Version 1.1</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Return value">Return value</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#FAQ: Can you explain better why Redis deletes keys with an EXPIRE on write operations?">FAQ: Can you explain better why Redis deletes keys with an EXPIRE on write operations?</a>
</div>
<h1 class="wikiname">ExpireCommand</h1>
<div class="summary">
</div>
<div class="narrow">
&iuml;&raquo;&iquest;#sidebar <a href="GenericCommandsSidebar.html">GenericCommandsSidebar</a><h1><a name="EXPIRE _key_ _seconds_">EXPIRE _key_ _seconds_</a></h1>
<h1><a name="EXPIREAT _key_ _unixtime_ (Redis &gt;">EXPIREAT _key_ _unixtime_ (Redis &gt;</a></h1> 1.1)=
<i>Time complexity: O(1)</i><blockquote>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 <i>volatile</i> in Redis terminology.</blockquote>
<blockquote>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.</blockquote>
<blockquote>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).</blockquote>
<blockquote>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.</blockquote>
<h2><a name="How the expire is removed from a key">How the expire is removed from a key</a></h2><blockquote>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.</blockquote>
<h2><a name="Restrictions with write operations against volatile keys">Restrictions with write operations against volatile keys</a></h2><blockquote>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:</blockquote>
<pre class="codeblock python" name="code">
% ./redis-cli lpush mylist foobar /Users/antirez/hack/redis
OK
% ./redis-cli lpush mylist hello /Users/antirez/hack/redis
OK
% ./redis-cli expire mylist 10000 /Users/antirez/hack/redis
1
% ./redis-cli lpush mylist newelement
OK
% ./redis-cli lrange mylist 0 -1 /Users/antirez/hack/redis
1. newelement
</pre><blockquote>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.</blockquote>
<h2><a name="Setting the timeout again on already volatile keys">Setting the timeout again on already volatile keys</a></h2><blockquote>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.</blockquote>
<h2><a name="Enhanced Lazy Expiration algorithm">Enhanced Lazy Expiration algorithm</a></h2><blockquote>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.</blockquote>
<blockquote>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. </blockquote>
<h3><a name="Version 1.0">Version 1.0</a></h3><blockquote>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.</blockquote>
<h3><a name="Version 1.1">Version 1.1</a></h3><blockquote>Each time Redis:</blockquote>
<ol><li> Tests 100 random keys from expired keys set.</li><li> Deletes all the keys found expired.</li><li> If more than 25 keys were expired, it start again from 1.</li></ol>
<blockquote>This is a trivial probabilistic algorithm, basically the assumption isthat our sample is representative of the whole key space,and we continue to expire until the percentage of keys that are likelyto be expired is under 25%</blockquote>
<blockquote>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.</blockquote>
<h2><a name="Return value">Return value</a></h2><a href="ReplyTypes.html">Integer reply</a>, specifically:<br/><br/><pre class="codeblock python python" name="code">
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.
</pre><h2><a name="FAQ: Can you explain better why Redis deletes keys with an EXPIRE on write operations?">FAQ: Can you explain better why Redis deletes keys with an EXPIRE on write operations?</a></h2>
Ok let's start with the problem:
<pre class="codeblock python python python" name="code">
redis&gt; set a 100
OK
redis&gt; expire a 360
(integer) 1
redis&gt; incr a
(integer) 1
</pre>
I set a key to the value of 100, then set an expire of 360 seconds, and then incremented the key (before the 360 timeout expired of course). The obvious result would be: 101, instead the key is set to the value of 1. Why?
There is a very important reason involving the Append Only File and Replication. Let's rework a bit hour example adding the notion of time to the mix:
<pre class="codeblock python python python python" name="code">
SET a 100
EXPIRE a 5
... wait 10 seconds ...
INCR a
</pre>
Imagine a Redis version that does not implement the &quot;Delete keys with an expire set on write operation&quot; 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.<br/><br/>Instead if we drop the 10 seconds pause, the result is that 'a' is set to 101.<br/><br/>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.<br/><br/>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.<br/><br/>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.<br/><br/>After all Redis is one of the rare fully persistent databases that will give you EXPIRE. This comes to a cost :)
</div>
</div>
</div>
</body>
</html>
This diff is collapsed.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<link type="text/css" rel="stylesheet" href="style.css" />
</head>
<body>
<div id="page">
<div id='header'>
<a href="index.html">
<img style="border:none" alt="Redis Documentation" src="redis.png">
</a>
</div>
<div id="pagecontent">
<div class="index">
<!-- This is a (PRE) block. Make sure it's left aligned or your toc title will be off. -->
<b>Features: Contents</b><br>&nbsp;&nbsp;<a href="#Features (DRAFT)">Features (DRAFT)</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Speed">Speed</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Persistence">Persistence</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Support for Data Structures">Support for Data Structures</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Atomic Operations">Atomic Operations</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Variety of Supported Languages">Variety of Supported Languages</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Master/Slave Replication">Master/Slave Replication</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Sharding">Sharding</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Hot Backups">Hot Backups</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Simple to Install, Setup and Manage">Simple to Install, Setup and Manage</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Portable">Portable</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Liberal Licensing">Liberal Licensing</a><br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#What's next?">What's next?</a>
</div>
<h1 class="wikiname">Features</h1>
<div class="summary">
</div>
<div class="narrow">
&iuml;&raquo;&iquest;#sidebar <a href="SideBar.html">SideBar</a>
<h1><a name="Features (DRAFT)">Features (DRAFT)</a></h1>Checking Redis for the first time? Here your will find the most important features, and pointers to a lot more information.<h2><a name="Speed">Speed</a></h2>Redis is written in ANSI C, and loads the whole dataset in memory, so it is wicked <i><b>fast</b>!</i> Up to 110,000 <a href="SETs.html">SETs</a>/second, 81,000 GETs/second can be achieved in an entry level Linux box. Read more about Redis <a href="Speed.html">Speed</a>.<br/><br/>Also Redis supports <a href="Pipelining.html">Pipelining</a> of commands and <a href="MultiBulkCommands.html">getting and setting m&Atilde;&ordm;ltiple values in a single command</a> to speed up communication with the client libraries.<h2><a name="Persistence">Persistence</a></h2>While all the data lives in memory, changes are <i>asynchronously</i> saved on disk using flexible policies based on elapsed time and/or number of updates since last save. <br/><br/>If you can't afford losing some data, starting on version 1.1 (currently in beta but you can download it from the Git repository) Redis supports an append-only file persistence mode. Check more on <a href="Persistence.html">Persistence</a>, or read the <a href="AppendOnlyFileHowto.html">AppendOnlyFileHowto</a> for more information.<h2><a name="Support for Data Structures">Support for Data Structures</a></h2>Values in Redis can be <a href="Strings.html">Strings</a> as in a conventional key-value store, but also <a href="Lists.html">Lists</a>, <a href="Sets.html">Sets</a>, and <a href="SortedSets.html">SortedSets</a> (to be support in <a href="RoadMap.html">version 1.1</a>). This data types allow pushing/poping elements, or adding/removing them, also perform server side union, intersection, difference between sets, and so forth depending on the types. Redis supports different kind of sorting abilities for <a href="Sets.html">Sets</a> and <a href="Lists.html">Lists</a>.<br/><br/>You can think in Redis as a <b>Data Structures Server</b>, that allows you to model non trivial problems. Read <a href="DataTypes.html">Data Types</a> to learn more about the way Redis handle <a href="Strings.html">Strings</a>, and the <a href="Commands.html">Commands</a> supported by <a href="Lists.html">Lists</a>, <a href="Sets.html">Sets</a> and <a href="SortedSets.html">SortedSets</a><h2><a name="Atomic Operations">Atomic Operations</a></h2>Redis operations working on the different Data Types are <b>atomic</b>, so setting or increasing a key, adding and removing elements from a set, increasing a counter will all be accomplished safely.<h2><a name="Variety of Supported Languages">Variety of Supported Languages</a></h2>Ruby, Python, Twisted Python, PHP, Erlang, Tcl, Perl, Lua, Java, Scala, Clojure, choose your poison. Check the list of <a href="SupportedLanguages.html">Supported Languages</a> for all the details.<br/><br/>If your favorite language is not supported yet, you can write your own client library, as the <a href="ProtocolSpecification.html">Protocol</a> is pretty simple.<h2><a name="Master/Slave Replication">Master/Slave Replication</a></h2>Redis supports a very simple and fast Master/Slave replication. Is so simple it takes only one line in the <a href="Configuration.html">configuration file</a> to set it up, and 21 seconds for a Slave to complete the initial sync of 10 MM key set in a Amazon EC2 instance.<br/><br/>Read more about Master/Slave <a href="Replication.html">Replication</a>. <h2><a name="Sharding">Sharding</a></h2>Distributing the dataset across multiple Redis instances is easy in Redis, as in any other key-value store. And this depends basically on the <a href="Supported.html">Languages</a> client libraries being able to do so. <br/><br/>Read more about <a href="Sharding.html">Sharding</a> if you want to know more abour distributing data and workload in Redis.<h2><a name="Hot Backups">Hot Backups</a></h2>TODO<h2><a name="Simple to Install, Setup and Manage">Simple to Install, Setup and Manage</a></h2>Installing Redis requires little more than downloading it, uncompressing it and running make. Management is near zero, so you can start using Redis in a matter of minutes.<br/><br/>Go on and read about Redis <a href="Installation.html">installation</a>, its <a href="Setup.html">Setup</a> and <a href="Management.html">Management</a>.<h2><a name="Portable">Portable</a></h2>Redis is written in ANSI C and works in most POSIX systems like Linux, BSD, Mac OS X, Solaris, and so on. Redis is reported to compile and work under WIN32 if compiled with Cygwin, but there is no official support for Windows currently.<h2><a name="Liberal Licensing">Liberal Licensing</a></h2>Redis is free software released under the very liberal BSD license.<h2><a name="What's next?">What's next?</a></h2>Want to get started with Redis? Try the <a href="QuickStart.html">Quick Start</a> you will be up and running in just a matter of minutes. <br/><br/>Check the <a href="CodeSamples.html">Code Samples</a> and find how you can use Redis with your favorite programming language.<br/><br/><a href="Comparisons.html">Compare</a> Redis with other key-value stores, like Tokyo Cabinet or Memcached.
</div>
</div>
</div>
</body>
</html>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment