added imported docs

This commit is contained in:
Kenneth Reitz
2011-04-06 13:25:13 -04:00
parent 097845a07a
commit f12ed3eb06
148 changed files with 10533 additions and 0 deletions
+38
View File
@@ -0,0 +1,38 @@
`|Redis Documentation| <index.html>`_
**AppendCommand: Contents**
  `APPEND \_key\_ \_value\_ <#APPEND%20_key_%20_value_>`_
    `Return value <#Return%20value>`_
    `Examples <#Examples>`_
AppendCommand
=============
#sidebar `StringCommandsSidebar <StringCommandsSidebar.html>`_
APPEND \_key\_ \_value\_
========================
*Time complexity: O(1). The amortized time complexity is O(1) assuming the appended value is small and the already present value is of any size, since the dynamic string library used by Redis will double the free space available on every reallocation.*
If the *key* already exists and is a string, this command appends
theprovided value at the end of the string.If the *key* does not
exist it is created and set as an empty string, soAPPEND will be
very similar to SET in this special case.
Return value
------------
`Integer reply <ReplyTypes.html>`_, specifically the total length
of the string after the append operation.
Examples
--------
::
redis> exists mykey
(integer) 0
redis> append mykey "Hello "
(integer) 6
redis> append mykey "World"
(integer) 11
redis> get mykey
"Hello World"
.. |Redis Documentation| image:: redis.png
+116
View File
@@ -0,0 +1,116 @@
`|Redis Documentation| <index.html>`_
**AppendOnlyFileHowto: Contents**
  `Append Only File HOWTO <#Append%20Only%20File%20HOWTO>`_
    `General Information <#General%20Information>`_
    `Log rewriting <#Log%20rewriting>`_
    `Wait... but how does this work? <#Wait...%20but%20how%20does%20this%20work?>`_
    `How durable is the append only file? <#How%20durable%20is%20the%20append%20only%20file?>`_
    `What should I do if my Append Only File gets corrupted? <#What%20should%20I%20do%20if%20my%20Append%20Only%20File%20gets%20corrupted?>`_
AppendOnlyFileHowto
===================
#sidebar `RedisGuides <RedisGuides.html>`_
Append Only File HOWTO
======================
General Information
-------------------
Append only file is an alternative durability option for Redis.
What this mean? Let's start with some fact:
- 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
"Snapshotting".
- 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 **was** not an
option for this applications.
What is the solution? To use append only file as alternative to
snapshotting. How it works?
- It is an 1.1 only feature.
- You have to turn it on editing the configuration file. Just make
sure you have "appendonly yes" somewhere.
- 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 **re-play** the append only file to
rebuild the state.
Log rewriting
-------------
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 "mykey" to the values of "1", "2", "3",
... 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.
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
`BGREWRITEAOF <BGREWRITEAOF.html>`_. 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.
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!).
Wait... but how does this work?
-------------------------------
Basically it uses the same fork() copy-on-write trick that
snapshotting already uses. This is how the algorithm works:
- Redis forks, so now we have a child and a parent.
- The child starts writing the new append log file in a temporary
file.
- The parent accumulates all the new changes in an in-memory
buffer (but at the same time it writes the new changes in the
**old** append only file, so if the rewriting fails, we are safe).
- 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.
- Profit! Now Redis atomically renames the old file into the new
one, and starts appending new data into the new file.
How durable is the append only file?
------------------------------------
Check redis.conf, you can configure how many times Redis will
fsync() data on disk. There are three options:
- Fsync() every time a new command is appended to the append log
file. Very very slow, very safe.
- Fsync() one time every second. Fast enough, and you can lose 1
second of data if there is a disaster.
- Never fsync(), just put your data in the hands of the Operating
System. The faster and unsafer method.
The suggested (and default) policy is "everysec". It is both very
fast and pretty safe. The "always" policy is very slow in practice,
even if it was improved in Redis 2.0.0 there is no way to make
fsync() faster than it is.
What should I do if my Append Only File gets corrupted?
-------------------------------------------------------
It is possible that the server crashes while writing the AOF file
(this still should never lead to inconsistencies) corrupting the
file in a way that is no longer loadable by Redis. When this
happens you can fix this problem using the following procedure:
- Make a backup copy of your AOF file.
- Fix the original file with: ./redis-check-aof --fix
``<filename>``
- Optionally use diff -u to check what is the difference between
two files.
- Restart the server with the fixed file.
.. |Redis Documentation| image:: redis.png
+30
View File
@@ -0,0 +1,30 @@
`|Redis Documentation| <index.html>`_
**AuthCommand: Contents**
  `AUTH \_password\_ <#AUTH%20_password_>`_
    `Return value <#Return%20value>`_
AuthCommand
===========
#sidebar
`ConnectionHandlingSidebar <ConnectionHandlingSidebar.html>`_
AUTH \_password\_
=================
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
*requirepass* directive in theRedis configuration file.
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.
Return value
------------
`Status code reply <ReplyTypes.html>`_
.. |Redis Documentation| image:: redis.png
+137
View File
@@ -0,0 +1,137 @@
`|Redis Documentation| <index.html>`_
**Benchmarks: Contents**
  `How Fast is Redis? <#How%20Fast%20is%20Redis?>`_
  `Latency percentiles <#Latency%20percentiles>`_
Benchmarks
==========
How Fast is Redis?
==================
Redis includes the ``redis-benchmark`` utility that simulates
`SETs <SETs.html>`_/GETs done by N clients at the same time sending
M total queries (it is similar to the Apache's ``ab`` utility).
Below you'll find the full output of the benchmark executed against
a Linux box.
- The test was done with 50 simultaneous clients performing 100000
requests.
- The value SET and GET is a 256 bytes string.
- The Linux box is running **Linux 2.6**, it's
**Xeon X3320 2.5Ghz**.
- Text executed using the loopback interface (127.0.0.1).
Results:
**about 110000 `SETs <SETs.html>`_ per second, about 81000 GETs per second.**
Latency percentiles
===================
::
./redis-benchmark -n 100000
====== SET ======
100007 requests completed in 0.88 seconds
50 parallel clients
3 bytes payload
keep alive: 1
58.50% <= 0 milliseconds
99.17% <= 1 milliseconds
99.58% <= 2 milliseconds
99.85% <= 3 milliseconds
99.90% <= 6 milliseconds
100.00% <= 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% <= 0 milliseconds
96.82% <= 1 milliseconds
98.62% <= 2 milliseconds
100.00% <= 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% <= 0 milliseconds
96.67% <= 1 milliseconds
99.14% <= 2 milliseconds
99.83% <= 3 milliseconds
99.88% <= 4 milliseconds
99.89% <= 5 milliseconds
99.96% <= 9 milliseconds
100.00% <= 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% <= 0 milliseconds
99.74% <= 1 milliseconds
99.85% <= 2 milliseconds
99.86% <= 3 milliseconds
99.89% <= 5 milliseconds
99.93% <= 7 milliseconds
99.96% <= 9 milliseconds
100.00% <= 22 milliseconds
100.00% <= 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% <= 0 milliseconds
97.34% <= 1 milliseconds
99.95% <= 2 milliseconds
99.96% <= 3 milliseconds
99.96% <= 4 milliseconds
100.00% <= 9 milliseconds
100.00% <= 208 milliseconds
71994.96 requests per second
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.
You can expect different results from different boxes. For example
a low profile box like
**Intel core duo T5500 clocked at 1.66Ghz running Linux 2.6** will
output the following:
::
./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
Another one using a 64 bit box, a Xeon L5420 clocked at 2.5 Ghz:
::
./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
.. |Redis Documentation| image:: redis.png
+31
View File
@@ -0,0 +1,31 @@
`|Redis Documentation| <index.html>`_
**BgrewriteaofCommand: Contents**
      `BGREWRITEAOF <#BGREWRITEAOF>`_
    `Return value <#Return%20value>`_
BgrewriteaofCommand
===================
#sidebar `ControlCommandsSidebar <ControlCommandsSidebar.html>`_
BGREWRITEAOF
~~~~~~~~~~~~
Please for detailed information about the Redis Append Only File
check`the Append Only File Howto <AppendOnlyFileHowto.html>`_.
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.
The `Append Only File Howto <AppendOnlyFileHowto.html>`_ contains
further details.
Return value
------------
`Status code reply <ReplyTypes.html>`_
.. |Redis Documentation| image:: redis.png
+22
View File
@@ -0,0 +1,22 @@
`|Redis Documentation| <index.html>`_
**BgsaveCommand: Contents**
  `BGSAVE <#BGSAVE>`_
    `Return value <#Return%20value>`_
BgsaveCommand
=============
#sidebar `ControlCommandsSidebar <ControlCommandsSidebar.html>`_
BGSAVE
======
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
`LASTSAVE <LastsaveCommand.html>`_ command.
Return value
------------
`Status code reply <ReplyTypes.html>`_
.. |Redis Documentation| image:: redis.png
+100
View File
@@ -0,0 +1,100 @@
`|Redis Documentation| <index.html>`_
**BlpopCommand: Contents**
  `BLPOP \_key1\_ \_key2\_ ... \_keyN\_ \_timeout\_ (Redis > <#BLPOP%20_key1_%20_key2_%20...%20_keyN_%20_timeout_%20(Redis%20%3E>`_
  `BRPOP \_key1\_ \_key2\_ ... \_keyN\_ \_timeout\_ (Redis > <#BRPOP%20_key1_%20_key2_%20...%20_keyN_%20_timeout_%20(Redis%20%3E>`_
    `Non blocking behavior <#Non%20blocking%20behavior>`_
    `Blocking behavior <#Blocking%20behavior>`_
    `Multiple clients blocking for the same keys <#Multiple%20clients%20blocking%20for%20the%20same%20keys>`_
    `blocking POP inside a MULTI/EXEC transaction <#blocking%20POP%20inside%20a%20MULTI/EXEC%20transaction>`_
    `Return value <#Return%20value>`_
BlpopCommand
============
#sidebar `ListCommandsSidebar <ListCommandsSidebar.html>`_
BLPOP \_key1\_ \_key2\_ ... \_keyN\_ \_timeout\_ (Redis >
=========================================================
1.3.1) =
BRPOP \_key1\_ \_key2\_ ... \_keyN\_ \_timeout\_ (Redis >
=========================================================
1.3.1) = *Time complexity: O(1)*
BLPOP (and BRPOP) is a blocking list pop primitive. You can see
this commandsas blocking versions of `LPOP <LpopCommand.html>`_ and
`RPOP <LpopCommand.html>`_ able toblock if the specified keys don't
exist or contain empty lists.
The following is a description of the exact semantic. We describe
BLPOP butthe two commands are identical, the only difference is
that BLPOP pops theelement from the left (head) of the list, and
BRPOP pops from the right (tail).
Non blocking behavior
---------------------
When BLPOP is called, if at least one of the specified keys contain
a nonempty list, an element is popped from the head of the list and
returned tothe caller together with the name of the key (BLPOP
returns a two elementsarray, the first element is the key, the
second the popped value).
Keys are scanned from left to right, so for instance if youissue
**BLPOP list1 list2 list3 0** against a dataset where **list1**
does notexist but **list2** and **list3** contain non empty lists,
BLPOP guaranteesto return an element from the list stored at
**list2** (since it is the firstnon empty list starting from the
left).
Blocking behavior
-----------------
If none of the specified keys exist or contain non empty lists,
BLPOPblocks until some other client performs a
`LPUSH <RpushCommand.html>`_ oran `RPUSH <RpushCommand.html>`_
operation against one of the lists.
Once new data is present on one of the lists, the client finally
returnswith the name of the key unblocking it and the popped
value.
When blocking, if a non-zero timeout is specified, the client will
unblockreturning a nil special value if the specified amount of
seconds passedwithout a push operation against at least one of the
specified keys.
The timeout argument is interpreted as an integer value. A timeout
of zero means instead to block forever.
Multiple clients blocking for the same keys
-------------------------------------------
Multiple clients can block for the same key. They are put intoa
queue, so the first to be served will be the one that started to
waitearlier, in a first-blpopping first-served fashion.
blocking POP inside a MULTI/EXEC transaction
--------------------------------------------
BLPOP and BRPOP can be used with pipelining (sending multiple
commands and reading the replies in batch), but it does not make
sense to use BLPOP or BRPOP inside a MULTI/EXEC block (a Redis
transaction).
The behavior of BLPOP inside MULTI/EXEC when the list is empty is
to return a multi-bulk nil reply, exactly what happens when the
timeout is reached. If you like science fiction, think at it like
if inside MULTI/EXEC the time will flow at infinite speed :)
Return value
------------
BLPOP returns a two-elements array via a multi bulk reply in order
to returnboth the unblocking key and the popped value.
When a non-zero timeout is specified, and the BLPOP operation timed
out,the return value is a nil multi bulk reply. Most client values
will returnfalse or nil accordingly to the programming language
used.
`Multi bulk reply <ReplyTypes.html>`_
.. |Redis Documentation| image:: redis.png
+38
View File
@@ -0,0 +1,38 @@
`|Redis Documentation| <index.html>`_
**BrpoplpushCommand: Contents**
  `BRPOPLPUSH \_srckey\_ \_dstkey\_ \_timeout\_ (Redis > <#BRPOPLPUSH%20_srckey_%20_dstkey_%20_timeout_%20(Redis%20%3E>`_
    `Return value <#Return%20value>`_
BrpoplpushCommand
=================
BRPOPLPUSH \_srckey\_ \_dstkey\_ \_timeout\_ (Redis >
=====================================================
2.1.8) = *Time complexity: O(1)*
Blocking version of the `RPOPLPUSH <RpoplpushCommand.html>`_
command. Atomically removes and returnsthe last element (tail) of
the source list at *srckey*, and as a side effect pushes the
returned element in the head of the list at *dstkey*.
If the source list is empty, the client blocks until another client
pushes against the source list. Of course in such a case the push
operation against the destination list will be performed after the
command unblocks detecting a push against the source list.
Note that the command returns an error if the target key already
exists but is not a list. The error is delayed at the time the push
operation is attempted, that is, immediately if the source list is
not empty, or when the first push against the source list happens
in the case the command would block.
The timeout value can be 0 or a positive integer value. When it is
zero the command will block forever, until something is pushed
against *srckey*. Otherwise the command will wait the specified
number of seconds at max, returning an nil value when the timeout
expires.
The source and destination of the list can be the same, having the
effect of rotating the list. Please check
`RPOPLPUSH <RpoplpushCommand.html>`_ for more information.
Return value
------------
`Bulk reply <ReplyTypes.html>`_
.. |Redis Documentation| image:: redis.png
+420
View File
@@ -0,0 +1,420 @@
`|Redis Documentation| <index.html>`_
**CommandReference: Contents**
    `Categorized Command List <#Categorized%20Command%20List>`_
    `Connection handling <#Connection%20handling>`_
    `Commands operating on all value types <#Commands%20operating%20on%20all%20value%20types>`_
    `Commands operating on string values <#Commands%20operating%20on%20string%20values>`_
    `Commands operating on lists <#Commands%20operating%20on%20lists>`_
    `Commands operating on sets <#Commands%20operating%20on%20sets>`_
    `Commands operating on sorted zsets (sorted sets) <#Commands%20operating%20on%20sorted%20zsets%20(sorted%20sets)>`_
    `Commands operating on hashes <#Commands%20operating%20on%20hashes>`_
    `Sorting <#Sorting>`_
    `Transactions <#Transactions>`_
    `Publish/Subscribe <#Publish/Subscribe>`_
    `Persistence control commands <#Persistence%20control%20commands>`_
    `Remote server control commands <#Remote%20server%20control%20commands>`_
CommandReference
================
= Redis Command Reference =
Every command name links to a specific wiki page describing the
behavior of the command.
Categorized Command List
------------------------
Connection handling
-------------------
**Command**
**Parameters**
**Description**
`QUIT <QuitCommand.html>`_
-
close the connection
`AUTH <AuthCommand.html>`_
*password*
simple password authentication if enabled
Commands operating on all value types
-------------------------------------
**Command**
**Parameters**
**Description**
`EXISTS <ExistsCommand.html>`_
*key*
test if a key exists
`DEL <DelCommand.html>`_
*key*
delete a key
`TYPE <TypeCommand.html>`_
*key*
return the type of the value stored at key
`KEYS <KeysCommand.html>`_
*pattern*
return all the keys matching a given pattern
`RANDOMKEY <RandomkeyCommand.html>`_
-
return a random key from the key space
`RENAME <RenameCommand.html>`_
*oldname* *newname*
rename the old key in the new one, destroying the newname key if it
already exists
`RENAMENX <RenamenxCommand.html>`_
*oldname* *newname*
rename the *oldname* key to *newname*, if the *newname* key does
not already exist
`DBSIZE <DbsizeCommand.html>`_
-
return the number of keys in the current db
`EXPIRE <ExpireCommand.html>`_
-
set a time to live in seconds on a key
`PERSIST <ExpireCommand.html>`_
-
remove the expire from a key
`TTL <TtlCommand.html>`_
-
get the time to live in seconds of a key
`SELECT <SelectCommand.html>`_
*index*
Select the DB with the specified index
`MOVE <MoveCommand.html>`_
*key* *dbindex*
Move the key from the currently selected DB to the *dbindex* DB
`FLUSHDB <FlushdbCommand.html>`_
-
Remove all the keys from the currently selected DB
`FLUSHALL <FlushallCommand.html>`_
-
Remove all the keys from all the databases
Commands operating on string values
-----------------------------------
**Command**
**Parameters**
**Description**
`SET <SetCommand.html>`_
*key* *value*
Set a *key* to a string *value*
`GET <GetCommand.html>`_
*key*
Return the string value of the *key*
`GETSET <GetsetCommand.html>`_
*key* *value*
Set a key to a string returning the old value of the key
`SETNX <SetnxCommand.html>`_
*key* *value*
Set a key to a string value if the key does not exist
`SETEX <SetexCommand.html>`_
*key* *time* *value*
Set+Expire combo command
`SETBIT <SetbitCommand.html>`_
*key* *offset* *value*
Set bit at *offset* to *value*
`GETBIT <GetbitCommand.html>`_
*key* *offset*
Return bit value at *offset*
`MSET <MsetCommand.html>`_
*key1* *value1* *key2* *value2* ... *keyN* *valueN*
Set multiple keys to multiple values in a single atomic operation
`MSETNX <MsetCommand.html>`_
*key1* *value1* *key2* *value2* ... *keyN* *valueN*
Set multiple keys to multiple values in a single atomic operation
if none of the keys already exist
`MGET <MgetCommand.html>`_
*key1* *key2* ... *keyN*
Multi-get, return the strings values of the keys
`INCR <IncrCommand.html>`_
*key*
Increment the integer value of key
`INCRBY <IncrCommand.html>`_
*key* *integer*
Increment the integer value of *key* by *integer*
`DECR <IncrCommand.html>`_
*key*
Decrement the integer value of key
`DECRBY <IncrCommand.html>`_
*key* *integer*
Decrement the integer value of *key* by *integer*
`APPEND <AppendCommand.html>`_
*key* *value*
Append the specified string to the string stored at key
`SUBSTR <SubstrCommand.html>`_
*key* *start* *end*
Return a substring of a larger string
Commands operating on lists
---------------------------
**Command**
**Parameters**
**Description**
`RPUSH <RpushCommand.html>`_
*key* *value*
Append an element to the tail of the List value at key
`LPUSH <RpushCommand.html>`_
*key* *value*
Append an element to the head of the List value at key
`LLEN <LlenCommand.html>`_
*key*
Return the length of the List value at key
`LRANGE <LrangeCommand.html>`_
*key* *start* *end*
Return a range of elements from the List at key
`LTRIM <LtrimCommand.html>`_
*key* *start* *end*
Trim the list at key to the specified range of elements
`LINDEX <LindexCommand.html>`_
*key* *index*
Return the element at index position from the List at key
`LSET <LsetCommand.html>`_
*key* *index* *value*
Set a new value as the element at index position of the List at key
`LREM <LremCommand.html>`_
*key* *count* *value*
Remove the first-N, last-N, or all the elements matching value from
the List at key
`LPOP <LpopCommand.html>`_
*key*
Return and remove (atomically) the first element of the List at key
`RPOP <LpopCommand.html>`_
*key*
Return and remove (atomically) the last element of the List at key
`BLPOP <BlpopCommand.html>`_
*key1* *key2* ... *keyN* *timeout*
Blocking LPOP
`BRPOP <BlpopCommand.html>`_
*key1* *key2* ... *keyN* *timeout*
Blocking RPOP
`RPOPLPUSH <RpoplpushCommand.html>`_
*srckey* *dstkey*
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*
`BRPOPLPUSH <BrpoplpushCommand.html>`_
*srckey* *dstkey*
Like RPOPLPUSH but blocking of source key is empty
Commands operating on sets
--------------------------
**Command**
**Parameters**
**Description**
`SADD <SaddCommand.html>`_
*key* *member*
Add the specified member to the Set value at key
`SREM <SremCommand.html>`_
*key* *member*
Remove the specified member from the Set value at key
`SPOP <SpopCommand.html>`_
*key*
Remove and return (pop) a random element from the Set value at key
`SMOVE <SmoveCommand.html>`_
*srckey* *dstkey* *member*
Move the specified member from one Set to another atomically
`SCARD <ScardCommand.html>`_
*key*
Return the number of elements (the cardinality) of the Set at key
`SISMEMBER <SismemberCommand.html>`_
*key* *member*
Test if the specified value is a member of the Set at key
`SINTER <SinterCommand.html>`_
*key1* *key2* ... *keyN*
Return the intersection between the Sets stored at key1, key2, ...,
keyN
`SINTERSTORE <SinterstoreCommand.html>`_
*dstkey* *key1* *key2* ... *keyN*
Compute the intersection between the Sets stored at key1, key2,
..., keyN, and store the resulting Set at dstkey
`SUNION <SunionCommand.html>`_
*key1* *key2* ... *keyN*
Return the union between the Sets stored at key1, key2, ..., keyN
`SUNIONSTORE <SunionstoreCommand.html>`_
*dstkey* *key1* *key2* ... *keyN*
Compute the union between the Sets stored at key1, key2, ..., keyN,
and store the resulting Set at dstkey
`SDIFF <SdiffCommand.html>`_
*key1* *key2* ... *keyN*
Return the difference between the Set stored at key1 and all the
Sets key2, ..., keyN
`SDIFFSTORE <SdiffstoreCommand.html>`_
*dstkey* *key1* *key2* ... *keyN*
Compute the difference between the Set key1 and all the Sets key2,
..., keyN, and store the resulting Set at dstkey
`SMEMBERS <SmembersCommand.html>`_
*key*
Return all the members of the Set value at key
`SRANDMEMBER <SrandmemberCommand.html>`_
*key*
Return a random member of the Set value at key
Commands operating on sorted zsets (sorted sets)
------------------------------------------------
**Command**
**Parameters**
**Description**
`ZADD <ZaddCommand.html>`_
*key* *score* *member*
Add the specified member to the Sorted Set value at key or update
the score if it already exist
`ZREM <ZremCommand.html>`_
*key* *member*
Remove the specified member from the Sorted Set value at key
`ZINCRBY <ZincrbyCommand.html>`_
*key* *increment* *member*
If the member already exists increment its score by *increment*,
otherwise add the member setting *increment* as score
`ZRANK <ZrankCommand.html>`_
*key* *member*
Return the rank (or index) or *member* in the sorted set at *key*,
with scores being ordered from low to high
`ZREVRANK <ZrankCommand.html>`_
*key* *member*
Return the rank (or index) or *member* in the sorted set at *key*,
with scores being ordered from high to low
`ZRANGE <ZrangeCommand.html>`_
*key* *start* *end*
Return a range of elements from the sorted set at key
`ZREVRANGE <ZrangeCommand.html>`_
*key* *start* *end*
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
`ZRANGEBYSCORE <ZrangebyscoreCommand.html>`_
*key* *min* *max*
Return all the elements with score >= min and score <= max (a range
query) from the sorted set
`ZCOUNT <ZrangebyscoreCommand.html>`_
*key* *min* *max*
Return the number of elements with score >= min and score <= max in
the sorted set
`ZCARD <ZcardCommand.html>`_
*key*
Return the cardinality (number of elements) of the sorted set at
key
`ZSCORE <ZscoreCommand.html>`_
*key* *element*
Return the score associated with the specified element of the
sorted set at key
`ZREMRANGEBYRANK <ZremrangebyrankCommand.html>`_
*key* *min* *max*
Remove all the elements with rank >= min and rank <= max from the
sorted set
`ZREMRANGEBYSCORE <ZremrangebyscoreCommand.html>`_
*key* *min* *max*
Remove all the elements with score >= min and score <= max from the
sorted set
`ZUNIONSTORE / ZINTERSTORE <ZunionstoreCommand.html>`_
*dstkey* *N* *key1* ... *keyN* WEIGHTS *w1* ... *wN* AGGREGATE
SUM\|MIN\|MAX
Perform a union or intersection over a number of sorted sets with
optional weight and aggregate
Commands operating on hashes
----------------------------
**Command**
**Parameters**
**Description**
`HSET <HsetCommand.html>`_
*key* *field* *value*
Set the hash field to the specified value. Creates the hash if
needed.
`HGET <HgetCommand.html>`_
*key* *field*
Retrieve the value of the specified hash field.
`HMGET <HmgetCommand.html>`_
*key* *field1* ... *fieldN*
Get the hash values associated to the specified fields.
`HMSET <HmsetCommand.html>`_
*key* *field1* *value1* ... *fieldN* *valueN*
Set the hash fields to their respective values.
`HINCRBY <HincrbyCommand.html>`_
*key* *field* *integer*
Increment the integer value of the hash at *key* on *field* with
*integer*.
`HEXISTS <HexistsCommand.html>`_
*key* *field*
Test for existence of a specified field in a hash
`HDEL <HdelCommand.html>`_
*key* *field*
Remove the specified field from a hash
`HLEN <HlenCommand.html>`_
*key*
Return the number of items in a hash.
`HKEYS <HgetallCommand.html>`_
*key*
Return all the fields in a hash.
`HVALS <HgetallCommand.html>`_
*key*
Return all the values in a hash.
`HGETALL <HgetallCommand.html>`_
*key*
Return all the fields and associated values in a hash.
Sorting
-------
**Command**
**Parameters**
**Description**
`SORT <SortCommand.html>`_
*key* BY *pattern* LIMIT *start* *end* GET *pattern* ASC\|DESC
ALPHA
Sort a Set or a List accordingly to the specified parameters
Transactions
------------
**Command**
**Parameters**
**Description**
`MULTI/EXEC/DISCARD/WATCH/UNWATCH <MultiExecCommand.html>`_
-
Redis atomic transactions
Publish/Subscribe
-----------------
**Command**
**Parameters**
**Description**
`SUBSCRIBE/UNSUBSCRIBE/PUBLISH <PublishSubscribe.html>`_
-
Redis Public/Subscribe messaging paradigm implementation
Persistence control commands
----------------------------
**Command**
**Parameters**
**Description**
`SAVE <SaveCommand.html>`_
-
Synchronously save the DB on disk
`BGSAVE <BgsaveCommand.html>`_
-
Asynchronously save the DB on disk
`LASTSAVE <LastsaveCommand.html>`_
-
Return the UNIX time stamp of the last successfully saving of the
dataset on disk
`SHUTDOWN <ShutdownCommand.html>`_
-
Synchronously save the DB on disk, then shutdown the server
`BGREWRITEAOF <BgrewriteaofCommand.html>`_
-
Rewrite the append only file in background when it gets too big
Remote server control commands
------------------------------
**Command**
**Parameters**
**Description**
`INFO <InfoCommand.html>`_
-
Provide information and statistics about the server
`MONITOR <MonitorCommand.html>`_
-
Dump all the received requests in real time
`SLAVEOF <SlaveofCommand.html>`_
-
Change the replication settings
`CONFIG <ConfigCommand.html>`_
-
Configure a Redis server at runtime
.. |Redis Documentation| image:: redis.png
+80
View File
@@ -0,0 +1,80 @@
`|Redis Documentation| <index.html>`_
**Comparisons: Contents**
    `Memcached <#Memcached>`_
    `Tokyo Cabinet / Toyo Tyrant <#Tokyo%20Cabinet%20/%20Toyo%20Tyrant>`_
Comparisons
===========
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.
Memcached
---------
- 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 `persistent <Persistence.html>`_.
- Like memcached Redis uses a key-value model, but while keys can
just be strings, values in Redis can be `Lists <Lists.html>`_,
`Sets <Sets.html>`_ or `SortedSets <SortedSets.html>`_ and complex
operations like intersections, set/get n-th element of lists,
pop/push of elements, can be performed against sets and lists.
Tokyo Cabinet / Toyo Tyrant
---------------------------
Redis and Tokyo Cabinet can be used for the same applications, but
actually they are *very 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.
- 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).
- 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.
- 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.
- 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.
- 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.
.. |Redis Documentation| image:: redis.png
+115
View File
@@ -0,0 +1,115 @@
`|Redis Documentation| <index.html>`_
**ConfigCommand: Contents**
  `CONFIG GET \_pattern\_ (Redis > <#CONFIG%20GET%20_pattern_%20(Redis%20%3E>`_
  `CONFIG SET \_parameter\_ \_value\_ (Redis > <#CONFIG%20SET%20_parameter_%20_value_%20(Redis%20%3E>`_
    `CONFIG GET \_pattern\_ <#CONFIG%20GET%20_pattern_>`_
    `CONFIG SET \_parameter\_ \_value\_ <#CONFIG%20SET%20_parameter_%20_value_>`_
    `Parameters value format <#Parameters%20value%20format>`_
    `See Also <#See%20Also>`_
ConfigCommand
=============
#sidebar `ControlCommandsSidebar <ControlCommandsSidebar.html>`_
CONFIG GET \_pattern\_ (Redis >
===============================
2.0)=
CONFIG SET \_parameter\_ \_value\_ (Redis >
===========================================
2.0)=
The CONFIG command is able to retrieve or alter the configuration
of a runningRedis server. Not all the configuration parameters are
supported.
CONFIG has two sub commands, GET and SET. The GET command is used
to readthe configuration, while the SET command is used to alter
the configuration.
CONFIG GET \_pattern\_
----------------------
CONFIG GET returns the current configuration parameters. This sub
commandonly accepts a single argument, that is glob style pattern.
All theconfiguration parameters matching this parameter are
reported as alist of key-value pairs. Example:
::
$ redis-cli config get '*'
1. "dbfilename"
2. "dump.rdb"
3. "requirepass"
4. (nil)
5. "masterauth"
6. (nil)
7. "maxmemory"
8. "0\n"
9. "appendfsync"
10. "everysec"
11. "save"
12. "3600 1 300 100 60 10000"
$ redis-cli config get 'm*'
1. "masterauth"
2. (nil)
3. "maxmemory"
4. "0\n"
The return type of the command is a
`bulk reply <ReplyTypes.html>`_.
CONFIG SET \_parameter\_ \_value\_
----------------------------------
CONFIG SET is used in order to reconfigure the server, setting a
specificconfiguration parameter to a new value.
The list of configuration parameters supported by CONFIG SET can
beobtained issuing a ``CONFIG GET *`` command.
The configuration set using CONFIG SET is immediately loaded by the
Redisserver that will start acting as specified starting from the
next command.
Example:
::
$ ./redis-cli
redis> set x 10
OK
redis> config set maxmemory 200
OK
redis> set y 20
(error) ERR command not allowed when used memory > 'maxmemory'
redis> config set maxmemory 0
OK
redis> set y 20
OK
Parameters value format
-----------------------
The value of the configuration parameter is the same as the one of
thesame parameter in the Redis configuration file, with the
following exceptions:
- The ``save`` paramter is a list of space-separated integers.
Every pair of integers specify the time and number of changes limit
to trigger a save. For instance the command
``CONFIG SET save "3600 10 60 10000"`` will configure the server to
issue a background saving of the RDB file every 3600 seconds if
there are at least 10 changes in the dataset, and every 60 seconds
if there are at least 10000 changes. To completely disable
automatic snapshots just set the parameter as an empty string.
- All the integer parameters representing memory are returned and
accepted only using bytes as unit.
See Also
--------
The `INFO <InfoCommand.html>`_ command can be used in order to read
configuriaton parameters that are not available in the CONFIG
command.
.. |Redis Documentation| image:: redis.png
+16
View File
@@ -0,0 +1,16 @@
`|Redis Documentation| <index.html>`_
**Configuration: Contents**
Configuration
=============
The ``redis.conf`` 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.
In order to start Redis using a configuration file just pass the
file name as the sole argument when starting the server:
::
$ ./redis-server redis.conf
.. |Redis Documentation| image:: redis.png
@@ -0,0 +1,11 @@
`|Redis Documentation| <index.html>`_
**ConnectionHandlingSidebar: Contents**
ConnectionHandlingSidebar
=========================
== Connection handling ==
- `QUIT <QuitCommand.html>`_
- `AUTH <AuthCommand.html>`_
.. |Redis Documentation| image:: redis.png
+17
View File
@@ -0,0 +1,17 @@
`|Redis Documentation| <index.html>`_
**ControlCommandsSidebar: Contents**
ControlCommandsSidebar
======================
== Control Commands ==
- `SAVE <SaveCommand.html>`_
- `BGSAVE <BgsaveCommand.html>`_
- `BGREWRITEAOF <BgrewriteaofCommand.html>`_
- `LASTSAVE <LastsaveCommand.html>`_
- `SHUTDOWN <ShutdownCommand.html>`_
- `INFO <InfoCommand.html>`_
- `MONITOR <MonitorCommand.html>`_
- `SLAVEOF <SlaveofCommand.html>`_
.. |Redis Documentation| image:: redis.png
+40
View File
@@ -0,0 +1,40 @@
`|Redis Documentation| <index.html>`_
**Credits: Contents**
  `Credits <#Credits>`_
Credits
=======
Credits
=======
- The Redis server was designed and written by
`Salvatore Sanfilippo (aka antirez) <http://invece.org>`_
- `Ezra Zygmuntowicz (aka ezmobius) <http://brainspl.at/>`_ - Ruby
client lib initial version and hacking
- `Ludovico Magnocavallo (aka ludo) <http://qix.it>`_ - Python
clinet lib
- `Valentino Volonghi of Adroll <http://www.adroll.com/>`_ -
Erlang client lib
- **brettbender** - 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.
- `Dobrica Pavlinusic <http://www.rot13.org/~dpavlin>`_ - Perl
client lib
- Brian Hammond - AUTH command implementation, C++ client lib
- `Daniele Alessandri <http://www.clorophilla.net/>`_ - Lua client
lib
- Corey Stup - C99 cleanups
- Taylor Weibley - Ruby client improvements
- Bob Potter - Rearrange redisObject struct to reduce memory usage
in 64bit environments
- Luca Guidi and Brian McKinney - Ruby client improvements
- Aman Gupta - SDIFF / SDIFFSTORE, other Set operations
improvements, ability to disable clients timeout.
- Diego Rosario Brogna - Code and ideas about dumping backtrace on
sigsegv and similar error conditions.
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!
.. |Redis Documentation| image:: redis.png
+18
View File
@@ -0,0 +1,18 @@
`|Redis Documentation| <index.html>`_
**DbsizeCommand: Contents**
  `DBSIZE <#DBSIZE>`_
    `Return value <#Return%20value>`_
DbsizeCommand
=============
#sidebar `GenericCommandsSidebar <GenericCommandsSidebar.html>`_
DBSIZE
======
Return the number of keys in the currently selected database.
Return value
------------
`Integer reply <ReplyTypes.html>`_
.. |Redis Documentation| image:: redis.png
+26
View File
@@ -0,0 +1,26 @@
`|Redis Documentation| <index.html>`_
**DelCommand: Contents**
  `DEL \_key1\_ \_key2\_ ... \_keyN\_ <#DEL%20_key1_%20_key2_%20...%20_keyN_>`_
    `Return value <#Return%20value>`_
DelCommand
==========
#sidebar `GenericCommandsSidebar <GenericCommandsSidebar.html>`_
DEL \_key1\_ \_key2\_ ... \_keyN\_
==================================
*Time complexity: O(1)*
Remove the specified keys. If a given key does not existno
operation is performed for this key. The command returns the number
ofkeys removed.
Return value
------------
`Integer reply <ReplyTypes.html>`_, specifically:
::
an integer greater than 0 if one or more keys were removed
0 if none of the specified key existed
.. |Redis Documentation| image:: redis.png
+9
View File
@@ -0,0 +1,9 @@
`|Redis Documentation| <index.html>`_
**DesignPatterns: Contents**
DesignPatterns
==============
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.
.. |Redis Documentation| image:: redis.png
+39
View File
@@ -0,0 +1,39 @@
`|Redis Documentation| <index.html>`_
**EventLibray: Contents**
  `Event Library <#Event%20Library>`_
    `Why is an Event Library needed at all? <#Why%20is%20an%20Event%20Library%20needed%20at%20all?>`_
EventLibray
===========
Event Library
=============
Why is an Event Library needed at all?
--------------------------------------
Let us figure it out through a series of Q&As.
Q: What do you expect a network server to be doing all the time?
<br/> A: Watch for inbound connections on the port its listening
and accept them.
Q: Calling `accept <http://man.cx/accept(2)>`_ yields a descriptor.
What do I do with it?<br/> A: Save the descriptor and do a
non-blocking read/write operation on it.
Q: Why does the read/write have to be non-blocking?<br/> A: If the
file operation ( even a socket in Unix is a file ) is blocking how
could the server for example accept other connection requests when
its blocked in a file I/O operation.
Q: I guess I have to do many such non-blocking operations on the
socket to see when it's ready. Am I right?<br/> A: Yes. That is
what an event library does for you. Now you get it.
Q: How do Event Libraries do what they do?<br/> A: They use the
operating system's
`polling <http://www.devshed.com/c/a/BrainDump/Linux-Files-and-the-Event-Poll-Interface/>`_
facility along with timers.
Q: So are there any open source event libraries that do what you
just described? <br/> A: Yes. Libevent and Libev are two such event
libraries that I can recall off the top of my head.
Q: Does Redis use such open source event libraries for handling
socket I/O?<br/> A: No. For various
`reasons <http://groups.google.com/group/redis-db/browse_thread/thread/b52814e9ef15b8d0/>`_
Redis uses its own event library.
.. |Redis Documentation| image:: redis.png
+26
View File
@@ -0,0 +1,26 @@
`|Redis Documentation| <index.html>`_
**ExistsCommand: Contents**
  `EXISTS \_key\_ <#EXISTS%20_key_>`_
    `Return value <#Return%20value>`_
ExistsCommand
=============
#sidebar `GenericCommandsSidebar <GenericCommandsSidebar.html>`_
EXISTS \_key\_
==============
*Time complexity: O(1)*
Test if the specified key exists. The command returns"0" if the key
exists, otherwise "1" is returned.Note that even keys set with an
empty string as value willreturn "1".
Return value
------------
`Integer reply <ReplyTypes.html>`_, specifically:
::
1 if the key exists.
0 if the key does not exist.
.. |Redis Documentation| image:: redis.png
+238
View File
@@ -0,0 +1,238 @@
`|Redis Documentation| <index.html>`_
**ExpireCommand: Contents**
  `EXPIRE \_key\_ \_seconds\_ <#EXPIRE%20_key_%20_seconds_>`_
  `EXPIREAT \_key\_ \_unixtime\_ (Redis > <#EXPIREAT%20_key_%20_unixtime_%20(Redis%20%3E>`_
  `PERSIST \_key\_ (Redis > <#PERSIST%20_key_%20(Redis%20%3E>`_
    `How the expire is removed from a key <#How%20the%20expire%20is%20removed%20from%20a%20key>`_
    `Restrictions with write operations against volatile keys <#Restrictions%20with%20write%20operations%20against%20volatile%20keys>`_
    `Restrictions for write operations with volatile keys as sources <#Restrictions%20for%20write%20operations%20with%20volatile%20keys%20as%20sources>`_
    `Setting the timeout again on already volatile keys <#Setting%20the%20timeout%20again%20on%20already%20volatile%20keys>`_
    `Enhanced Lazy Expiration algorithm <#Enhanced%20Lazy%20Expiration%20algorithm>`_
      `Version 1.0 <#Version%201.0>`_
      `Version 1.1 <#Version%201.1>`_
    `Return value <#Return%20value>`_
    `FAQ: Can you explain better why Redis < 2.1.3 deletes keys with an EXPIRE on write operations? <#FAQ:%20Can%20you%20explain%20better%20why%20Redis%20%3C%202.1.3%20deletes%20keys%20with%20an%20EXPIRE%20on%20write%20operations?>`_
    `FAQ: How this limitations were solved in Redis versions > 2.1.3? <#FAQ:%20How%20this%20limitations%20were%20solved%20in%20Redis%20versions%20%3E%202.1.3?>`_
ExpireCommand
=============
#sidebar `GenericCommandsSidebar <GenericCommandsSidebar.html>`_
EXPIRE \_key\_ \_seconds\_
==========================
EXPIREAT \_key\_ \_unixtime\_ (Redis >
======================================
1.1)=
PERSIST \_key\_ (Redis >
========================
2.1.3) = *Time complexity: O(1)*
Set a timeout on the specified key. After the timeout the key will
beautomatically deleted by the server. A key with an associated
timeout issaid to be *volatile* in Redis terminology.
Voltile keys are stored on disk like the other keys, the timeout is
persistenttoo like all the other aspects of the dataset. Saving a
dataset containingexpires and stopping the server does not stop the
flow of time as Redisstores on disk the time when the key will no
longer be available as Unixtime, and not the remaining seconds.
EXPIREAT works exctly like EXPIRE but instead to get the number of
secondsrepresenting the Time To Live of the key as a second
argument (that is arelative way of specifing the TTL), it takes an
absolute one in the form ofa UNIX timestamp (Number of seconds
elapsed since 1 Gen 1970).
EXPIREAT was introduced in order to implement
`the Append Only File persistence mode <AppendOnlyFileHowto.html>`_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.
Since Redis 2.1.3 you can update the value of the timeout of a key
alreadyhaving an expire set. It is also possible to undo the expire
at allturning the key into a normal key using the PERSIST command.
How the expire is removed from a key
------------------------------------
When the key is set to a new value using the SET command, or when a
keyis destroied via DEL, the timeout is removed from the key.
Restrictions with write operations against volatile keys
--------------------------------------------------------
IMPORTANT: Since Redis 2.1.3 or greater, there are no restrictions
aboutthe operations you can perform against volatile keys, however
older versionsof Redis, including the current stable version 2.0.0,
has the followinglimitations:
Write operations like LPUSH, LSET and every other command that has
theeffect of modifying the value stored at a volatile key have a
special semantic:basically a volatile key is destroyed when it is
target of a write operation.See for example the following usage
pattern:
::
% ./redis-cli lpush mylist foobar /Users/antirez/hack/redis
OK
% ./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
What happened here is that LPUSH against the key with a timeout set
deletedthe key before to perform the operation. There is so a
simple rule, writeoperations against volatile keys will destroy the
key before to perform theoperation. Why Redis uses this behavior?
In order to retain an importantproperty: a server that receives a
given number of commands in the samesequence will end with the same
dataset in memory. Without the delete-on-writesemantic what happens
is that the state of the server depends on the timethe commands
were issued. This is not a desirable property in a distributed
databasethat supports replication.
Restrictions for write operations with volatile keys as sources
---------------------------------------------------------------
Even when the volatile key is not modified as part of a write
operation, if it is read in a composite write operation (such as
SINTERSTORE) it will be cleared at the start of the operation. This
is done to avoid concurrency issues in replication. Imagine a key
that is about to expire and the composite operation is run against
it. On a slave node, this key might already be expired, which
leaves you with a desync in your dataset.
Setting the timeout again on already volatile keys
--------------------------------------------------
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.
Enhanced Lazy Expiration algorithm
----------------------------------
Redis does not constantly monitor keys that are going to be
expired.Keys are expired simply when some client tries to access a
key, andthe key is found to be timed out.
Of course this is not enough as there are expired keys that will
neverbe accessed again. This keys should be expired anyway, so once
everysecond Redis test a few keys at random among keys with an
expire set.All the keys that are already expired are deleted from
the keyspace.
Version 1.0
~~~~~~~~~~~
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.
Version 1.1
~~~~~~~~~~~
Each time Redis:
#. Tests 100 random keys from expired keys set.
#. Deletes all the keys found expired.
#. If more than 25 keys were expired, it start again from 1.
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%
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.
Return value
------------
`Integer reply <ReplyTypes.html>`_, specifically:
::
1: the timeout was set.
0: the timeout was not set since the key already has an associated timeout
(this may happen only in Redis versions < 2.1.3, Redis >= 2.1.3 will
happily update the timeout), or the key does not exist.
FAQ: Can you explain better why Redis < 2.1.3 deletes keys with an EXPIRE on write operations?
----------------------------------------------------------------------------------------------
Ok let's start with the problem:
::
redis> set a 100
OK
redis> expire a 360
(integer) 1
redis> incr a
(integer) 1
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 our
example adding the notion of time to the mix:
::
SET a 100
EXPIRE a 5
... wait 10 seconds ...
INCR a
Imagine a Redis version that does not implement the "Delete keys
with an expire set on write operation" semantic. Running the above
example with the 10 seconds pause will lead to 'a' being set to the
value of 1, as it no longer exists when INCR is called 10 seconds
later.
Instead if we drop the 10 seconds pause, the result is that 'a' is
set to 101.
And in the practice timing changes! For instance the client may
wait 10 seconds before INCR, but the sequence written in the Append
Only File (and later replayed-back as fast as possible when Redis
is restarted) will not have the pause. Even if we add a timestamp
in the AOF, when the time difference is smaller than our timer
resolution, we have a race condition.
The same happens with master-slave replication. Again, consider the
example above: the client will use the same sequence of commands
without the 10 seconds pause, but the replication link will slow
down for a few seconds due to a network problem. Result? The master
will contain 'a' set to 101, the slave 'a' set to 1.
The only way to avoid this but at the same time have reliable non
time dependent timeouts on keys is to destroy volatile keys when a
write operation is attempted against it.
After all Redis is one of the rare fully persistent databases that
will give you EXPIRE. This comes to a cost :)
FAQ: How this limitations were solved in Redis versions > 2.1.3?
----------------------------------------------------------------
Since Redis 2.1.3 there are no longer restrictions in the use you
can do of write commands against volatile keys, still the
replication and AOF file are guaranteed to be fully consistent.
In order to obtain a correct behavior without sacrificing
consistency now when a key expires, a DEL operation is synthesized
in both the AOF file and against all the attached slaves. This way
the expiration process is centralized in the master instance, and
there is no longer a chance of consistency errors.
However while the slaves while connected to a master will not
expire keys independently, they'll still take the full state of the
expires existing in the dataset, so when a slave is elected to a
master it will be able to expire the keys independently, fully
acting as a master.
.. |Redis Documentation| image:: redis.png
+364
View File
@@ -0,0 +1,364 @@
`|Redis Documentation| <index.html>`_
**FAQ: Contents**
  `Isn't this key-value thing just hype? <#Isn't%20this%20key-value%20thing%20just%20hype?>`_
  `Can I backup a Redis DB while the server is working? <#Can%20I%20backup%20a%20Redis%20DB%20while%20the%20server%20is%20working?>`_
  `What's the Redis memory footprint? <#What's%20the%20Redis%20memory%20footprint?>`_
  `I like Redis high level operations and features, but I don't like it takes everything in memory and I can't have a dataset larger the memory. Plans to change this? <#I%20like%20Redis%20high%20level%20operations%20and%20features,%20but%20I%20don't%20like%20it%20takes%20everything%20in%20memory%20and%20I%20can't%20have%20a%20dataset%20larger%20the%20memory.%20Plans%20to%20change%20this?>`_
  `Why Redis takes the whole dataset in RAM? <#Why%20Redis%20takes%20the%20whole%20dataset%20in%20RAM?>`_
  `If my dataset is too big for RAM and I don't want to use consistent hashing or other ways to distribute the dataset across different nodes, what I can do to use Redis anyway? <#If%20my%20dataset%20is%20too%20big%20for%20RAM%20and%20I%20don't%20want%20to%20use%20consistent%20hashing%20or%20other%20ways%20to%20distribute%20the%20dataset%20across%20different%20nodes,%20what%20I%20can%20do%20to%20use%20Redis%20anyway?>`_
  `Do you plan to implement Virtual Memory in Redis? Why don't just let the Operating System handle it for you? <#Do%20you%20plan%20to%20implement%20Virtual%20Memory%20in%20Redis?%20Why%20don't%20just%20let%20the%20Operating%20System%20handle%20it%20for%20you?>`_
  `Is there something I can do to lower the Redis memory usage? <#Is%20there%20something%20I%20can%20do%20to%20lower%20the%20Redis%20memory%20usage?>`_
  `I have an empty Redis server but INFO and logs are reporting megabytes of memory in use! <#I%20have%20an%20empty%20Redis%20server%20but%20INFO%20and%20logs%20are%20reporting%20megabytes%20of%20memory%20in%20use!>`_
  `What happens if Redis runs out of memory? <#What%20happens%20if%20Redis%20runs%20out%20of%20memory?>`_
  `Does Redis use more memory running in 64 bit boxes? Can I use 32 bit Redis in 64 bit systems? <#Does%20Redis%20use%20more%20memory%20running%20in%2064%20bit%20boxes?%20Can%20I%20use%2032%20bit%20Redis%20in%2064%20bit%20systems?>`_
  `How much time it takes to load a big database at server startup? <#How%20much%20time%20it%20takes%20to%20load%20a%20big%20database%20at%20server%20startup?>`_
  `Background saving is failing with a fork() error under Linux even if I've a lot of free RAM! <#Background%20saving%20is%20failing%20with%20a%20fork()%20error%20under%20Linux%20even%20if%20I've%20a%20lot%20of%20free%20RAM!>`_
  `Are Redis on disk snapshots atomic? <#Are%20Redis%20on%20disk%20snapshots%20atomic?>`_
  `Redis is single threaded, how can I exploit multiple CPU / cores? <#Redis%20is%20single%20threaded,%20how%20can%20I%20exploit%20multiple%20CPU%20/%20cores?>`_
  `I'm using some form of key hashing for partitioning, but what about SORT BY? <#I'm%20using%20some%20form%20of%20key%20hashing%20for%20partitioning,%20but%20what%20about%20SORT%20BY?>`_
  `What is the maximum number of keys a single Redis instance can hold? and what the max number of elements in a List, Set, Ordered Set? <#What%20is%20the%20maximum%20number%20of%20keys%20a%20single%20Redis%20instance%20can%20hold?%20and%20what%20the%20max%20number%20of%20elements%20in%20a%20List,%20Set,%20Ordered%20Set?>`_
  `What Redis means actually? <#What%20Redis%20means%20actually?>`_
  `Why did you started the Redis project? <#Why%20did%20you%20started%20the%20Redis%20project?>`_
FAQ
===
= Why I need Redis if there is already memcachedb, Tokyo
Cabinet, ...? =
Memcachedb is basically memcached done persistent. Redis is a
different evolution path in the key-value DBs, the idea is that the
main advantages of key-value DBs are retained even without a so
severe loss of comfort of plain key-value DBs. So Redis offers more
features:
- Keys can store different data types, not just strings. Notably
Lists and Sets. For example if you want to use Redis as a log
storage system for different computers every computer can just
``RPUSH data to the computer_ID key``. Don't want to save more than
1000 log lines per computer? Just issue a
``LTRIM computer_ID 0 999`` command to trim the list after every
push.
- Another example is about Sets. Imagine to build a social news
site like `Reddit <http://reddit.com>`_. Every time a user upvote a
given news you can just add to the news\_ID\_upmods key holding a
value of type SET the id of the user that did the upmodding. Sets
can also be used to index things. Every key can be a tag holding a
SET with the IDs of all the objects associated to this tag. Using
Redis set intersection you obtain the list of IDs having all this
tags at the same time.
- We wrote a `simple Twitter Clone <http://retwis.antirez.com>`_
using just Redis as database. Download the source code from the
download section and imagine to write it with a plain key-value DB
without support for lists and sets... it's **much** harder.
- Multiple DBs. Using the SELECT command the client can select
different datasets. This is useful because Redis provides a MOVE
atomic primitive that moves a key form a DB to another one, if the
target DB already contains such a key it returns an error: this
basically means a way to perform locking in distributed
processing.
- **So what is Redis really about?** The User interface with the
programmer. Redis aims to export to the programmer the right tools
to model a wide range of problems.
**Sets, Lists with O(1) push operation, lrange and ltrim, server-side fast intersection between sets, are primitives that allow to model complex problems with a key value database**.
Isn't this key-value thing just hype?
=====================================
I imagine key-value DBs, in the short term future, to be used like
you use memory in a program, with lists, hashes, and so on. With
Redis it's like this, but this special kind of memory containing
your data structures is shared, atomic, persistent.
When we write code it is obvious, when we take data in memory, to
use the most sensible data structure for the work, right?
Incredibly when data is put inside a relational DB this is no
longer true, and we create an absurd data model even if our need is
to put data and get this data back in the same order we put it
inside (an ORDER BY is required when the data should be already
sorted. Strange, dont' you think?).
Key-value DBs bring this back at home, to create sensible data
models and use the right data structures for the problem we are
trying to solve.
Can I backup a Redis DB while the server is working?
====================================================
Yes you can. When Redis saves the DB it actually creates a temp
file, then rename(2) that temp file name to the destination file
name. So even while the server is working it is safe to save the
database file just with the *cp* unix command. Note that you can
use master-slave replication in order to have redundancy of data,
but if all you need is backups, cp or scp will do the work pretty
well.
What's the Redis memory footprint?
==================================
Worst case scenario: 1 Million keys with the key being the natural
numbers from 0 to 999999 and the string "Hello World" as value use
100MB on my Intel macbook (32bit). Note that the same data stored
linearly in an unique string takes something like 16MB, this is the
norm because with small keys and values there is a lot of overhead.
Memcached will perform similarly.
With large keys/values the ratio is much better of course.
64 bit systems will use much more memory than 32 bit systems to
store the same keys, especially if the keys and values are small,
this is because pointers takes 8 bytes in 64 bit systems. But of
course the advantage is that you can have a lot of memory in 64 bit
systems, so to run large Redis servers a 64 bit system is more or
less required.
I like Redis high level operations and features, but I don't like it takes everything in memory and I can't have a dataset larger the memory. Plans to change this?
===================================================================================================================================================================
Short answer: If you are using a Redis client that supports
consistent hashing you can distribute the dataset across different
nodes. For instance the Ruby clients supports this feature. There
are plans to develop redis-cluster that basically is a dummy Redis
server that is only used in order to distribute the requests among
N different nodes using consistent hashing.
Why Redis takes the whole dataset in RAM?
=========================================
Redis takes the whole dataset in memory and writes asynchronously
on disk in order to be very fast, you have the best of both worlds:
hyper-speed and persistence of data, but the price to pay is
exactly this, that the dataset must fit on your computers RAM.
If the data is larger then memory, and this data is stored on disk,
what happens is that the bottleneck of the disk I/O speed will
start to ruin the performances. Maybe not in benchmarks, but once
you have real load from multiple clients with distributed key
accesses the data must come from disk, and the disk is damn slow.
Not only, but Redis supports higher level data structures than the
plain values. To implement this things on disk is even slower.
Redis will always continue to hold the whole dataset in memory
because this days scalability requires to use RAM as storage media,
and RAM is getting cheaper and cheaper. Today it is common for an
entry level server to have 16 GB of RAM! And in the 64-bit era
there are no longer limits to the amount of RAM you can have in
theory.
Amazon EC2 now provides instances with 32 or 64 GB of RAM.
If my dataset is too big for RAM and I don't want to use consistent hashing or other ways to distribute the dataset across different nodes, what I can do to use Redis anyway?
==============================================================================================================================================================================
You may try to load a dataset larger than your memory in Redis and
see what happens, basically if you are using a modern Operating
System, and you have a lot of data in the DB that is rarely
accessed, the OS's virtual memory implementation will try to swap
rarely used pages of memory on the disk, to only recall this pages
when they are needed. If you have many large values rarely used
this will work. If your DB is big because you have tons of little
values accessed at random without a specific pattern this will not
work (at low level a page is usually 4096 bytes, and you can have
different keys/values stored at a single page. The OS can't swap
this page on disk if there are even few keys used frequently).
Another possible solution is to use both MySQL and Redis at the
same time, basically take the state on Redis, and all the things
that get accessed very frequently: user auth tokens, Redis Lists
with chronologically ordered IDs of the last N-comments, N-posts,
and so on. Then use MySQL as a simple storage engine for larger
data, that is just create a table with an auto-incrementing ID as
primary key and a large BLOB field as data field. Access MySQL data
only by primary key (the ID). The application will run the high
traffic queries against Redis but when there is to take the big
data will ask MySQL for specific resources IDs.
Update: it could be interesting to test how Redis performs with
datasets larger than memory if the OS swap partition is in one of
this very fast Intel SSD disks.
Do you plan to implement Virtual Memory in Redis? Why don't just let the Operating System handle it for you?
============================================================================================================
Yes, in order to support datasets bigger than RAM there is the plan
to implement transparent Virtual Memory in Redis, that is, the
ability to transfer large values associated to keys rarely used on
Disk, and reload them transparently in memory when this values are
requested in some way.
So you may ask why don't let the operating system VM do the work
for us. There are two main reasons: in Redis even a large value
stored at a given key, for instance a 1 million elements list, is
not allocated in a contiguous piece of memory. It's actually
**very** fragmented since Redis uses quite aggressive object
sharing and allocated Redis Objects structures reuse.
So you can imagine the memory layout composed of 4096 bytes pages
that actually contain different parts of different large values.
Not only, but a lot of values that are large enough for us to swap
out to disk, like a 1024k value, is just one quarter the size of a
memory page, and likely in the same page there are other values
that are not rarely used. So this value wil never be swapped out by
the operating system. This is the first reason for implementing
application-level virtual memory in Redis.
There is another one, as important as the first. A complex object
in memory like a list or a set is something **10 times bigger**
than the same object serialized on disk. Probably you already
noticed how Redis snapshots on disk are damn smaller compared to
the memory usage of Redis for the same objects. This happens
because when data is in memory is full of pointers, reference
counters and other metadata. Add to this malloc fragmentation and
need to return word-aligned chunks of memory and you have a clear
picture of what happens. So this means to have 10 times the I/O
between memory and disk than otherwise needed.
Is there something I can do to lower the Redis memory usage?
============================================================
Yes, try to compile it with 32 bit target if you are using a 64 bit
box.
If you are using Redis >= 1.3, try using the Hash data type, it can
save a lot of memory.
If you are using hashes or any other type with values bigger than
128 bytes try also this to lower the RSS usage (Resident Set Size):
EXPORT MMAP\_THRESHOLD=4096
I have an empty Redis server but INFO and logs are reporting megabytes of memory in use!
========================================================================================
This may happen and it's prefectly ok. Redis objects are small C
structures allocated and freed a lot of times. This costs a lot of
CPU so instead of being freed, released objects are taken into a
free list and reused when needed. This memory is taken exactly by
this free objects ready to be reused.
What happens if Redis runs out of memory?
=========================================
With modern operating systems malloc() returning NULL is not
common, usually the server will start swapping and Redis
performances will be disastrous so you'll know it's time to use
more Redis servers or get more RAM.
The INFO command (work in progress in this days) will report the
amount of memory Redis is using so you can write scripts that
monitor your Redis servers checking for critical conditions.
You can also use the "maxmemory" option in the config file to put a
limit to the memory Redis can use. If this limit is reached Redis
will start to reply with an error to write commands (but will
continue to accept read-only commands).
Does Redis use more memory running in 64 bit boxes? Can I use 32 bit Redis in 64 bit systems?
=============================================================================================
Redis uses a lot more memory when compiled for 64 bit target,
especially if the dataset is composed of many small keys and
values. Such a database will, for instance, consume 50 MB of RAM
when compiled for the 32 bit target, and 80 MB for 64 bit! That's a
big difference.
You can run 32 bit Redis binaries in a 64 bit Linux and Mac OS X
system without problems. For OS X just use **make 32bit**. For
Linux instead, make sure you have **libc6-dev-i386** installed,
then use **make 32bit** if you are using the latest Git version.
Instead for Redis <= 1.2.2 you have to edit the Makefile and
replace "-arch i386" with "-m32".
If your application is already able to perform application-level
sharding, it is very advisable to run N instances of Redis 32bit
against a big 64 bit Redis box (with more than 4GB of RAM) instead
than a single 64 bit instance, as this is much more memory
efficient.
How much time it takes to load a big database at server startup?
================================================================
Just an example on normal hardware: It takes about 45 seconds to
restore a 2 GB database on a fairly standard system, no RAID. This
can give you some kind of feeling about the order of magnitude of
the time needed to load data when you restart the server.
Background saving is failing with a fork() error under Linux even if I've a lot of free RAM!
============================================================================================
Short answer: ``echo 1 > /proc/sys/vm/overcommit_memory`` :)
And now the long one:
Redis background saving schema relies on the copy-on-write semantic
of fork in modern operating systems: Redis forks (creates a child
process) that is an exact copy of the parent. The child process
dumps the DB on disk and finally exits. In theory the child should
use as much memory as the parent being a copy, but actually thanks
to the copy-on-write semantic implemented by most modern operating
systems the parent and child process will *share* the common memory
pages. A page will be duplicated only when it changes in the child
or in the parent. Since in theory all the pages may change while
the child process is saving, Linux can't tell in advance how much
memory the child will take, so if the ``overcommit_memory`` setting
is set to zero fork will fail unless there is as much free RAM as
required to really duplicate all the parent memory pages, with the
result that if you have a Redis dataset of 3 GB and just 2 GB of
free memory it will fail.
Setting ``overcommit_memory`` to 1 says Linux to relax and perform
the fork in a more optimistic allocation fashion, and this is
indeed what you want for Redis.
A good source to understand how Linux Virtual Memory work and other
alternatives for ``overcommit_memory`` and ``overcommit_ratio`` is
this classic from Red Hat Magaize, "Understanding Virtual Memory":
`http://www.redhat.com/magazine/001nov04/features/vm/ <http://www.redhat.com/magazine/001nov04/features/vm/>`_
Are Redis on disk snapshots atomic?
===================================
Yes, redis background saving process is always fork(2)ed when the
server is outside of the execution of a command, so every command
reported to be atomic in RAM is also atomic from the point of view
of the disk snapshot.
Redis is single threaded, how can I exploit multiple CPU / cores?
=================================================================
Simply start multiple instances of Redis in different ports in the
same box and threat them as different servers! Given that Redis is
a distributed database anyway in order to scale you need to think
in terms of multiple computational units. At some point a single
box may not be enough anyway.
In general key-value databases are very scalable because of the
property that different keys can stay on different servers
independently.
In Redis there are client libraries such Redis-rb (the Ruby client)
that are able to handle multiple servers automatically using
*consistent hashing*. We are going to implement consistent hashing
in all the other major client libraries. If you use a different
language you can implement it yourself otherwise just hash the key
before to SET / GET it from a given server. For example imagine to
have N Redis servers, server-0, server-1, ..., server-N. You want
to store the key "foo", what's the right server where to put "foo"
in order to distribute keys evenly among different servers? Just
perform the *crc* = CRC32("foo"), then *servernum* = *crc* % N (the
rest of the division for N). This will give a number between 0 and
N-1 for every key. Connect to this server and store the key. The
same for gets.
This is a basic way of performing key partitioning, consistent
hashing is much better and this is why after Redis 1.0 will be
released we'll try to implement this in every widely used client
library starting from Python and PHP (Ruby already implements this
support).
I'm using some form of key hashing for partitioning, but what about SORT BY?
============================================================================
With `SORT <SortCommand.html>`_ BY you need that all the
*weight keys* are in the same Redis instance of the list/set you
are trying to sort. In order to make this possible we developed a
concept called *key tags*. A key tag is a special pattern inside a
key that, if preset, is the only part of the key hashed in order to
select the server for this key. For example in order to hash the
key "foo" I simply perform the CRC32 checksum of the whole string,
but if this key has a pattern in the form of the characters {...} I
only hash this substring. So for example for the key "foo{bared}"
the key hashing code will simply perform the CRC32 of "bared". This
way using key tags you can ensure that related keys will be stored
on the same Redis instance just using the same key tag for all this
keys. Redis-rb already implements key tags.
What is the maximum number of keys a single Redis instance can hold? and what the max number of elements in a List, Set, Ordered Set?
=====================================================================================================================================
In theory Redis can handle up to
2\ :sup:`32 keys, and was tested in practice to handle at least 150 million of keys per instance. We are working in order to experiment with larger values.Every list, set, and ordered set, can hold 2`\ 32
elements.
Actually Redis internals are ready to allow up to
2\ :sup:`64 elements but the current disk dump format don't support this, and there is a lot time to fix this issues in the future as currently even with 128 GB of RAM it's impossible to reach 2`\ 32
elements.
What Redis means actually?
==========================
Redis means two things:
- it's a joke on the word Redistribute (instead to use just a
Relational DB redistribute your workload among Redis servers)
- it means REmote DIctionary Server
Why did you started the Redis project?
======================================
In order to scale `LLOOGG <http://lloogg.com>`_. But after I got
the basic server working I liked the idea to share the work with
other guys, and Redis was turned into an open source project.
.. |Redis Documentation| image:: redis.png
+134
View File
@@ -0,0 +1,134 @@
`|Redis Documentation| <index.html>`_
**Features: Contents**
  `Features (DRAFT) <#Features%20(DRAFT)>`_
    `Speed <#Speed>`_
    `Persistence <#Persistence>`_
    `Support for Data Structures <#Support%20for%20Data%20Structures>`_
    `Atomic Operations <#Atomic%20Operations>`_
    `Variety of Supported Languages <#Variety%20of%20Supported%20Languages>`_
    `Master/Slave Replication <#Master/Slave%20Replication>`_
    `Sharding <#Sharding>`_
    `Hot Backups <#Hot%20Backups>`_
    `Simple to Install, Setup and Manage <#Simple%20to%20Install,%20Setup%20and%20Manage>`_
    `Portable <#Portable>`_
    `Liberal Licensing <#Liberal%20Licensing>`_
    `What's next? <#What's%20next?>`_
Features
========
#sidebar `SideBar <SideBar.html>`_
Features (DRAFT)
================
Checking Redis for the first time? Here your will find the most
important features, and pointers to a lot more information.
Speed
-----
Redis is written in ANSI C, and loads the whole dataset in memory,
so it is wicked ***fast**!* Up to 110,000
`SETs <SETs.html>`_/second, 81,000 GETs/second can be achieved in
an entry level Linux box. Read more about Redis
`Speed <Speed.html>`_.
Also Redis supports `Pipelining <Pipelining.html>`_ of commands and
`getting and setting múltiple values in a single command <MultiBulkCommands.html>`_
to speed up communication with the client libraries.
Persistence
-----------
While all the data lives in memory, changes are *asynchronously*
saved on disk using flexible policies based on elapsed time and/or
number of updates since last save.
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
`Persistence <Persistence.html>`_, or read the
`AppendOnlyFileHowto <AppendOnlyFileHowto.html>`_ for more
information.
Support for Data Structures
---------------------------
Values in Redis can be `Strings <Strings.html>`_ as in a
conventional key-value store, but also `Lists <Lists.html>`_,
`Sets <Sets.html>`_, and `SortedSets <SortedSets.html>`_ (to be
support in `version 1.1 <RoadMap.html>`_). 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 `Sets <Sets.html>`_ and
`Lists <Lists.html>`_.
You can think in Redis as a **Data Structures Server**, that allows
you to model non trivial problems. Read
`Data Types <DataTypes.html>`_ to learn more about the way Redis
handle `Strings <Strings.html>`_, and the
`Commands <Commands.html>`_ supported by `Lists <Lists.html>`_,
`Sets <Sets.html>`_ and `SortedSets <SortedSets.html>`_
Atomic Operations
-----------------
Redis operations working on the different Data Types are
**atomic**, so setting or increasing a key, adding and removing
elements from a set, increasing a counter will all be accomplished
safely.
Variety of Supported Languages
------------------------------
Ruby, Python, Twisted Python, PHP, Erlang, Tcl, Perl, Lua, Java,
Scala, Clojure, choose your poison. Check the list of
`Supported Languages <SupportedLanguages.html>`_ for all the
details.
If your favorite language is not supported yet, you can write your
own client library, as the `Protocol <ProtocolSpecification.html>`_
is pretty simple.
Master/Slave Replication
------------------------
Redis supports a very simple and fast Master/Slave replication. Is
so simple it takes only one line in the
`configuration file <Configuration.html>`_ 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.
Read more about Master/Slave `Replication <Replication.html>`_.
Sharding
--------
Distributing the dataset across multiple Redis instances is easy in
Redis, as in any other key-value store. And this depends basically
on the `Languages <Supported.html>`_ client libraries being able to
do so.
Read more about `Sharding <Sharding.html>`_ if you want to know
more abour distributing data and workload in Redis.
Hot Backups
-----------
TODO
Simple to Install, Setup and Manage
-----------------------------------
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.
Go on and read about Redis `installation <Installation.html>`_, its
`Setup <Setup.html>`_ and `Management <Management.html>`_.
Portable
--------
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.
Liberal Licensing
-----------------
Redis is free software released under the very liberal BSD license.
What's next?
------------
Want to get started with Redis? Try the
`Quick Start <QuickStart.html>`_ you will be up and running in just
a matter of minutes.
Check the `Code Samples <CodeSamples.html>`_ and find how you can
use Redis with your favorite programming language.
`Compare <Comparisons.html>`_ Redis with other key-value stores,
like Tokyo Cabinet or Memcached.
.. |Redis Documentation| image:: redis.png
+19
View File
@@ -0,0 +1,19 @@
`|Redis Documentation| <index.html>`_
**FlushallCommand: Contents**
  `FLUSHALL <#FLUSHALL>`_
    `Return value <#Return%20value>`_
FlushallCommand
===============
#sidebar `GenericCommandsSidebar <GenericCommandsSidebar.html>`_
FLUSHALL
========
Delete all the keys of all the existing databases, not just the
currently selected one. This command never fails.
Return value
------------
`Status code reply <ReplyTypes.html>`_
.. |Redis Documentation| image:: redis.png
+19
View File
@@ -0,0 +1,19 @@
`|Redis Documentation| <index.html>`_
**FlushdbCommand: Contents**
  `FLUSHDB <#FLUSHDB>`_
    `Return value <#Return%20value>`_
FlushdbCommand
==============
#sidebar `GenericCommandsSidebar <GenericCommandsSidebar.html>`_
FLUSHDB
=======
Delete all the keys of the currently selected DB. This command
never fails.
Return value
------------
`Status code reply <ReplyTypes.html>`_
.. |Redis Documentation| image:: redis.png
+63
View File
@@ -0,0 +1,63 @@
`|Redis Documentation| <index.html>`_
**FromSqlToDataStructures: Contents**
  `Introduction (IDEA MORE THAN A DRAFT) <#Introduction%20(IDEA%20MORE%20THAN%20A%20DRAFT)>`_
    `Data Structures <#Data%20Structures>`_
    `Dude where is my SELECT statement? <#Dude%20where%20is%20my%20SELECT%20statement?>`_
    `LISTs <#LISTs>`_
    `SETs <#SETs>`_
    `SORT to the rescue <#SORT%20to%20the%20rescue>`_
      `SORT BY <#SORT%20BY>`_
    `HASHEs <#HASHEs>`_
FromSqlToDataStructures
=======================
Introduction (IDEA MORE THAN A DRAFT)
=====================================
**¿Coming from SQLand?** *¿Who doesn't?* Redis is simple,
*primitive* when comapred to the world you are used to in the world
of Relational Database Managers (RDBMS) and Structure Query
Language (SQL), here you will find insight to build bridges between
both worlds to model real life problems.
Data Structures
---------------
When I was young, happy and single ;) I studied **Data Structures**
at the university, actually I learnt Data Structures and Algorithms
*before* learning anything about Databases, and particularly RDBMS
and SQL. This is natural because you need to know about Data
Structures and Algorithms to understand a Database.
Redis can be seen as a **Data Structures Server**, a very simple
interface to a extremly fast and efficient
Dude where is my SELECT statement?
----------------------------------
LISTs
-----
In SQL there is no such thing as a "natural" order, a SELECT
statement without a ORDER BY clause will return data in a undefined
order. In Redis `LISTs <LISTs.html>`_ address the problem of
natural ordering, ...
SETs
----
So you have a bunch of unordered data,
SORT to the rescue
------------------
But sometimes we *need* to actually sort a LIST in a order
different from its natural or take a SET and have it ordered, there
is where the *fast* SORT commands comes handy...
SORT BY
~~~~~~~
Just SORTing keys would be kind of boring, sometimes useless right?
Well, you can SORT...
HASHEs
------
Umm, sorry you will have to wait for a
`upcoming version of Redis <RoadMap.html>`_ to have Hashes, but
here are Idioms you should house to manage Dictionary like data...
.. |Redis Documentation| image:: redis.png
+25
View File
@@ -0,0 +1,25 @@
`|Redis Documentation| <index.html>`_
**GenericCommandsSidebar: Contents**
GenericCommandsSidebar
======================
== Generic Commands ==
- `EXISTS <ExistsCommand.html>`_
- `DEL <DelCommand.html>`_
- `TYPE <TypeCommand.html>`_
- `KEYS <KeysCommand.html>`_
- `RANDOMKEY <RandomkeyCommand.html>`_
- `RENAME <RenameCommand.html>`_
- `RENAMENX <RenamenxCommand.html>`_
- `DBSIZE <DbsizeCommand.html>`_
- `EXPIRE <ExpireCommand.html>`_
- `PERSIST <ExpireCommand.html>`_
- `TTL <TtlCommand.html>`_
- `SELECT <SelectCommand.html>`_
- `MOVE <MoveCommand.html>`_
- `FLUSHDB <FlushdbCommand.html>`_
- `FLUSHALL <FlushallCommand.html>`_
- `Redis Transactions <MultiExecCommand.html>`_
.. |Redis Documentation| image:: redis.png
+22
View File
@@ -0,0 +1,22 @@
`|Redis Documentation| <index.html>`_
**GetCommand: Contents**
  `GET \_key\_ <#GET%20_key_>`_
    `Return value <#Return%20value>`_
GetCommand
==========
#sidebar `StringCommandsSidebar <StringCommandsSidebar.html>`_
GET \_key\_
===========
*Time complexity: O(1)*
Get the value of the specified key. If the keydoes not exist the
special value 'nil' is returned.If the value stored at *key* is not
a string an erroris returned because GET can only handle string
values.
Return value
------------
`Bulk reply <ReplyTypes.html>`_
.. |Redis Documentation| image:: redis.png
+24
View File
@@ -0,0 +1,24 @@
`|Redis Documentation| <index.html>`_
**GetbitCommand: Contents**
  `GETBIT \_key\_ \_offset\_ (Redis > <#GETBIT%20_key_%20_offset_%20(Redis%20%3E>`_
    `Return value <#Return%20value>`_
GetbitCommand
=============
GETBIT \_key\_ \_offset\_ (Redis >
==================================
2.1.8) = *Time complexity: O(1)*
Returns the bit value at *offset* in the string value stored at
*key*.
When *offset* is beyond the string length, the string is assumed to
be a contiguous space with 0 bits. When *key* does not exist it is
assumed to be an empty string, so *offset* is always out of range
and the value is also assumed to be a contiguous space with 0 bits.
Return value
------------
`Integer reply <ReplyTypes.html>`_, specifically: the bit value
stored at *offset*.
.. |Redis Documentation| image:: redis.png
+32
View File
@@ -0,0 +1,32 @@
`|Redis Documentation| <index.html>`_
**GetsetCommand: Contents**
  `GETSET \_key\_ \_value\_ <#GETSET%20_key_%20_value_>`_
    `Return value <#Return%20value>`_
    `Design patterns <#Design%20patterns>`_
GetsetCommand
=============
#sidebar `StringCommandsSidebar <StringCommandsSidebar.html>`_
GETSET \_key\_ \_value\_
========================
*Time complexity: O(1)*
GETSET is an atomic *set this value and return the old value*
command.Set *key* to the string *value* and return the old value
stored at *key*.The string can't be longer than 1073741824 bytes (1
GB).
Return value
------------
`Bulk reply <ReplyTypes.html>`_
Design patterns
---------------
GETSET can be used together with INCR for counting with atomic
reset whena given condition arises. For example a process may call
INCR against thekey *mycounter* every time some event occurred, but
from time totime we need to get the value of the counter and reset
it to zero atomicallyusing ``GETSET mycounter 0``.
.. |Redis Documentation| image:: redis.png
+111
View File
@@ -0,0 +1,111 @@
`|Redis Documentation| <index.html>`_
**HackingStrings: Contents**
  `Hacking Strings <#Hacking%20Strings>`_
    `Creating Redis Strings <#Creating%20Redis%20Strings>`_
HackingStrings
==============
Hacking Strings
===============
The implementation of Redis strings is contained in ****sds.c**** (
sds stands for Simple Dynamic Strings ).
The C structure *sdshdr* declared in **sds.h** represents a Redis
string:
::
struct sdshdr {
long len;
long free;
char buf[];
};
The *buf* character array stores the actual string.
The *len* field stores the length of *buf*. This makes obtaining
the length of a Redis string an O(1) operation.
The *free* field stores the number of additional bytes available
for use.
Together the *len* and *free* field can be thought of as holding
the metadata of the *buf* character array.
Creating Redis Strings
----------------------
A new data type named ``sds`` is defined in **sds.h** to be a
synonymn for a character pointer:
::
typedef char *sds;
``sdsnewlen`` function defined in **sds.c** creates a new Redis
String:
::
sds sdsnewlen(const void *init, size_t initlen) {
struct sdshdr *sh;
sh = zmalloc(sizeof(struct sdshdr)+initlen+1);
#ifdef SDS_ABORT_ON_OOM
if (sh == NULL) sdsOomAbort();
#else
if (sh == NULL) return NULL;
#endif
sh->len = initlen;
sh->free = 0;
if (initlen) {
if (init) memcpy(sh->buf, init, initlen);
else memset(sh->buf,0,initlen);
}
sh->buf[initlen] = '\0';
return (char*)sh->buf;
}
Remember a Redis string is a variable of type ``struct sdshdr``.
But ``sdsnewlen`` returns a character pointer!!
That's a trick and needs some explanation.
Suppose I create a Redis string using ``sdsnewlen`` like below:
::
sdsnewlen("redis", 5);
This creates a new variable of type ``struct sdshdr`` allocating
memory for *len* and *free* fields as well as for the *buf*
character array.
::
sh = zmalloc(sizeof(struct sdshdr)+initlen+1); // initlen is length of init argument.
After ``sdsnewlen`` succesfully creates a Redis string the result
is something like:
::
-----------
|5|0|redis|
-----------
^ ^
sh sh->buf
``sdsnewlen`` returns sh->buf to the caller.
What do you do if you need to free the Redis string pointed by
``sh``?
You want the pointer ``sh`` but you only have the pointer
``sh->buf``.
Can you get the pointer ``sh`` from ``sh->buf``?
Yes. Pointer arithmetic. Notice from the above ASCII art that if
you subtract the size of two longs from ``sh->buf`` you get the
pointer ``sh``.
The sizeof two longs happens to be the size of ``struct sdshdr``.
Look at ``sdslen`` function and see this trick at work:
::
size_t sdslen(const sds s) {
struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));
return sh->len;
}
Knowing this trick you could easily go through the rest of the
functions in **sds.c**.
The Redis string implementation is hidden behind an interface that
accepts only character pointers. The users of Redis strings need
not care about how its implemented and treat Redis strings as a
character pointer.
.. |Redis Documentation| image:: redis.png
+21
View File
@@ -0,0 +1,21 @@
`|Redis Documentation| <index.html>`_
**HashCommandsSidebar: Contents**
HashCommandsSidebar
===================
== Hash Commands ==
- `HSET <HsetCommand.html>`_
- `HGET <HgetCommand.html>`_
- `HSETNX <HsetnxCommand.html>`_
- `HMSET <HmsetCommand.html>`_
- `HMGET <HmgetCommand.html>`_
- `HINCRBY <HincrbyCommand.html>`_
- `HEXISTS <HexistsCommand.html>`_
- `HDEL <HdelCommand.html>`_
- `HLEN <HlenCommand.html>`_
- `HKEYS <HgetallCommand.html>`_
- `HVALS <HgetallCommand.html>`_
- `HGETALL <HgetallCommand.html>`_
.. |Redis Documentation| image:: redis.png
+61
View File
@@ -0,0 +1,61 @@
`|Redis Documentation| <index.html>`_
**Hashes: Contents**
  `Redis Hash Type <#Redis%20Hash%20Type>`_
  `Implementation details <#Implementation%20details>`_
Hashes
======
#sidebar `HashCommandsSidebar <HashCommandsSidebar.html>`_
Redis Hash Type
===============
Redis Hashes are unordered maps of `Redis Strings <String.html>`_
between fields and values. It is possible to add, remove, test for
existence of fields in O(1) amortized time. It is also possible to
enumerate all the keys, values, or both, in O(N) (where N is the
number of fields inside the hash).
Redis Hashes are interesting because they are very well suited to
represent objects. For instance web applications users can be
represented by a Redis Hash containing fields such username,
encrpypted\_password, lastlogin, and so forth.
Another very important property of Redis Hashes is that they use
very little memory for hashes composed of a small number of fields
(configurable, check redis.conf for details), compared to storing
every field as a top level Redis key. This is obtained using a
different specialized representation for small hashes. See the
implementation details paragraph below for more information.
Commands operating on hashes try to make a good use of the return
value in order to signal the application about previous existence
of fields. For instance the `HSET <HsetCommand.html>`_ command will
return 1 if the field set was not already present in the hash,
otherwise will return 0 (and the user knows this was just an update
operation).
The max number of fields in a set is 232-1 (4294967295, more than 4
billion of members per hash).
Implementation details
======================
The obvious internal representation of hashes is indeed an hash
table, as the name of the data structure itself suggests. Still the
drawback of this representation is that there is a lot of space
overhead for hash table metadata.
Because one of the most interesting uses of Hashes is object
encoding, and objects are often composed of a few fields each,
Redis uses a different internal representation for small hashes
(for Redis to consider a hash small, this must be composed a
limited number of fields, and each field and value can't exceed a
given number of bytes. All this is user-configurable).
Small hashes are thus encoded using a data structure called zipmap
(is not something you can find in a CS book, the name is a Redis
invention), that is a very memory efficient data structure to
represent string to string maps, at the cost of being O(N) instead
of O(1) for most operations. Since the constant times of this data
structure are very small, and the zipmaps are converted into real
hash tables once they are big enough, the amortized time of Redis
hashes is still O(1), and in the practice small zipmaps are not
slower than small hash tables because they are designed for good
cache locality and fast access.
The result is that small hashes are both memory efficient and fast,
while bigger hashes are fast but not as memory efficient than small
hashes.
.. |Redis Documentation| image:: redis.png
+22
View File
@@ -0,0 +1,22 @@
`|Redis Documentation| <index.html>`_
**HdelCommand: Contents**
  `HDEL \_key\_ \_field\_ (Redis > <#HDEL%20_key_%20_field_%20(Redis%20%3E>`_
    `Return value <#Return%20value>`_
HdelCommand
===========
#sidebar `HashCommandsSidebar <HashCommandsSidebar.html>`_
HDEL \_key\_ \_field\_ (Redis >
===============================
1.3.10)= *Time complexity: O(1)*
Remove the specified *field* from an hash stored at *key*.
If the *field* was present in the hash it is deleted and 1 is
returned, otherwise 0 is returned and no operation is performed.
Return value
------------
`Integer reply <ReplyTypes.html>`_
.. |Redis Documentation| image:: redis.png
+22
View File
@@ -0,0 +1,22 @@
`|Redis Documentation| <index.html>`_
**HexistsCommand: Contents**
  `HEXISTS \_key\_ \_field\_ (Redis > <#HEXISTS%20_key_%20_field_%20(Redis%20%3E>`_
    `Return value <#Return%20value>`_
HexistsCommand
==============
#sidebar `HashCommandsSidebar <HashCommandsSidebar.html>`_
HEXISTS \_key\_ \_field\_ (Redis >
==================================
1.3.10)= *Time complexity: O(1)*
Return 1 if the hash stored at *key* contains the specified
*field*.
Return 0 if the *key* is not found or the *field* is not present.
Return value
------------
`Integer reply <ReplyTypes.html>`_
.. |Redis Documentation| image:: redis.png
+23
View File
@@ -0,0 +1,23 @@
`|Redis Documentation| <index.html>`_
**HgetCommand: Contents**
  `HGET \_key\_ \_field\_ (Redis > <#HGET%20_key_%20_field_%20(Redis%20%3E>`_
    `Return value <#Return%20value>`_
HgetCommand
===========
#sidebar `HashCommandsSidebar <HashCommandsSidebar.html>`_
HGET \_key\_ \_field\_ (Redis >
===============================
1.3.10)= *Time complexity: O(1)*
If *key* holds a hash, retrieve the value associated to the
specified *field*.
If the *field* is not found or the *key* does not exist, a special
'nil' value is returned.
Return value
------------
`Bulk reply <ReplyTypes.html>`_
.. |Redis Documentation| image:: redis.png
+33
View File
@@ -0,0 +1,33 @@
`|Redis Documentation| <index.html>`_
**HgetallCommand: Contents**
  `HKEYS \_key\_ (Redis > <#HKEYS%20_key_%20(Redis%20%3E>`_
  `HVALS \_key\_ (Redis > <#HVALS%20_key_%20(Redis%20%3E>`_
  `HGETALL \_key\_ (Redis > <#HGETALL%20_key_%20(Redis%20%3E>`_
    `Return value <#Return%20value>`_
HgetallCommand
==============
#sidebar `HashCommandsSidebar <HashCommandsSidebar.html>`_
HKEYS \_key\_ (Redis >
======================
1.3.10)=
HVALS \_key\_ (Redis >
======================
1.3.10)=
HGETALL \_key\_ (Redis >
========================
1.3.10)=
*Time complexity: O(N), where N is the total number of fields in the hash*
HKEYS returns all the fields names contained into a hash, HVALS all
the associated values, while HGETALL returns both the fields and
values in the form of *field1*, *value1*, *field2*, *value2*, ...,
*fieldN*, *valueN*.
Return value
------------
`Multi Bulk Reply <ReplyTypes.html>`_
.. |Redis Documentation| image:: redis.png
+37
View File
@@ -0,0 +1,37 @@
`|Redis Documentation| <index.html>`_
**HincrbyCommand: Contents**
  `HINCRBY \_key\_ \_field\_ \_value\_ (Redis > <#HINCRBY%20_key_%20_field_%20_value_%20(Redis%20%3E>`_
    `Examples <#Examples>`_
    `Return value <#Return%20value>`_
HincrbyCommand
==============
HINCRBY \_key\_ \_field\_ \_value\_ (Redis >
============================================
1.3.10)= *Time complexity: O(1)*
Increment the number stored at *field* in the hash at *key* by
*value*. If *key* does not exist, a new key holding a hash is
created. If *field* does not exist or holds a string, the value is
set to 0 before applying the operation.
The range of values supported by HINCRBY is limited to 64 bit
signed integers.
Examples
--------
Since the *value* argument is signed you can use this command to
perform both increments and decrements:
::
HINCRBY key field 1 (increment by one)
HINCRBY key field -1 (decrement by one, just like the DECR command)
HINCRBY key field -10 (decrement by 10)
Return value
------------
`Integer reply <ReplyTypes.html>`_ The new value at *field* after
the increment operation.
.. |Redis Documentation| image:: redis.png
+21
View File
@@ -0,0 +1,21 @@
`|Redis Documentation| <index.html>`_
**HlenCommand: Contents**
  `HLEN \_key\_ (Redis > <#HLEN%20_key_%20(Redis%20%3E>`_
    `Return value <#Return%20value>`_
HlenCommand
===========
#sidebar `HashCommandsSidebar <HashCommandsSidebar.html>`_
HLEN \_key\_ (Redis >
=====================
1.3.10)= *Time complexity: O(1)*
Return the number of entries (fields) contained in the hash stored
at *key*. If the specified *key* does not exist, 0 is returned
assuming an empty hash.
Return value
------------
`Integer reply <ReplyTypes.html>`_
.. |Redis Documentation| image:: redis.png
+25
View File
@@ -0,0 +1,25 @@
`|Redis Documentation| <index.html>`_
**HmgetCommand: Contents**
  `HMGET \_key\_ \_field1\_ ... \_fieldN\_ (Redis > <#HMGET%20_key_%20_field1_%20...%20_fieldN_%20(Redis%20%3E>`_
    `Return value <#Return%20value>`_
HmgetCommand
============
#sidebar `HashCommandsSidebar <HashCommandsSidebar.html>`_
HMGET \_key\_ \_field1\_ ... \_fieldN\_ (Redis >
================================================
1.3.10) =
*Time complexity: O(N) (with N being the number of fields)*
Retrieve the values associated to the specified *fields*.
If some of the specified *fields* do not exist, nil values are
returned.Non existing keys are considered like empty hashes.
Return value
------------
`Multi Bulk Reply <ReplyTypes.html>`_ specifically a list of all
the values associated with the specified fields, in the same order
of the request.
.. |Redis Documentation| image:: redis.png
+23
View File
@@ -0,0 +1,23 @@
`|Redis Documentation| <index.html>`_
**HmsetCommand: Contents**
  `HMSET \_key\_ \_field1\_ \_value1\_ ... \_fieldN\_ \_valueN\_ (Redis > <#HMSET%20_key_%20_field1_%20_value1_%20...%20_fieldN_%20_valueN_%20(Redis%20%3E>`_
    `Return value <#Return%20value>`_
HmsetCommand
============
HMSET \_key\_ \_field1\_ \_value1\_ ... \_fieldN\_ \_valueN\_ (Redis >
======================================================================
1.3.10) =
*Time complexity: O(N) (with N being the number of fields)*
Set the respective fields to the respective values. HMSET replaces
old values with new values.
If *key* does not exist, a new key holding a hash is created.
Return value
------------
`Status code reply <ReplyTypes.html>`_ Always +OK because HMSET
can't fail
.. |Redis Documentation| image:: redis.png
+25
View File
@@ -0,0 +1,25 @@
`|Redis Documentation| <index.html>`_
**HsetCommand: Contents**
  `HSET \_key\_ \_field\_ \_value\_ (Redis > <#HSET%20_key_%20_field_%20_value_%20(Redis%20%3E>`_
    `Return value <#Return%20value>`_
HsetCommand
===========
#sidebar `HashCommandsSidebar <HashCommandsSidebar.html>`_
HSET \_key\_ \_field\_ \_value\_ (Redis >
=========================================
1.3.10)= *Time complexity: O(1)*
Set the specified hash *field* to the specified *value*.
If *key* does not exist, a new key holding a hash is created.
If the field already exists, and the HSET just produced an update
of thevalue, 0 is returned, otherwise if a new field is created 1
is returned.
Return value
------------
`Integer reply <ReplyTypes.html>`_
.. |Redis Documentation| image:: redis.png
+25
View File
@@ -0,0 +1,25 @@
`|Redis Documentation| <index.html>`_
**HsetnxCommand: Contents**
  `HSETNX \_key\_ \_field\_ \_value\_ (Redis > <#HSETNX%20_key_%20_field_%20_value_%20(Redis%20%3E>`_
    `Return value <#Return%20value>`_
HsetnxCommand
=============
HSETNX \_key\_ \_field\_ \_value\_ (Redis >
===========================================
1.3.10)= *Time complexity: O(1)*
Set the specified hash *field* to the specified *value*, if *field*
does not exist yet.
If *key* does not exist, a new key holding a hash is created.
If the field already exists, this operation has no effect and
returns 0.Otherwise, the field is set to *value* and the operation
returns 1.
Return value
------------
`Integer reply <ReplyTypes.html>`_
.. |Redis Documentation| image:: redis.png
+44
View File
@@ -0,0 +1,44 @@
`|Redis Documentation| <index.html>`_
**IncrCommand: Contents**
  `INCR \_key\_ <#INCR%20_key_>`_
  `INCRBY \_key\_ \_integer\_ <#INCRBY%20_key_%20_integer_>`_
  `DECR \_key\_ \_integer\_ <#DECR%20_key_%20_integer_>`_
  `DECRBY \_key\_ \_integer\_ <#DECRBY%20_key_%20_integer_>`_
    `Return value <#Return%20value>`_
IncrCommand
===========
#sidebar `StringCommandsSidebar <StringCommandsSidebar.html>`_
INCR \_key\_
============
INCRBY \_key\_ \_integer\_
==========================
DECR \_key\_ \_integer\_
========================
DECRBY \_key\_ \_integer\_
==========================
*Time complexity: O(1)*
Increment or decrement the number stored at *key* by one. If the
key doesnot exist or contains a value of a wrong type, set the key
to thevalue of "0" before to perform the increment or decrement
operation.
INCRBY and DECRBY work just like INCR and DECR but instead
toincrement/decrement by 1 the increment/decrement is *integer*.
INCR commands are limited to 64 bit signed integers.
Note: this is actually a string operation, that is, in Redis there
are not "integer" types. Simply the string stored at the key is
parsed as a base 10 64 bit signed integer, incremented, and then
converted back as a string.
Return value
------------
`Integer reply <ReplyTypes.html>`_, this commands will reply with
the new value of *key* after the increment or decrement.
.. |Redis Documentation| image:: redis.png
+49
View File
@@ -0,0 +1,49 @@
`|Redis Documentation| <index.html>`_
**InfoCommand: Contents**
  `INFO <#INFO>`_
    `Return value <#Return%20value>`_
    `Notes <#Notes>`_
InfoCommand
===========
#sidebar `ControlCommandsSidebar <ControlCommandsSidebar.html>`_
INFO
====
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.
Return value
------------
`Bulk reply <ReplyTypes.html>`_, specifically in the following
format:
::
edis_version:0.07
connected_clients:1
connected_slaves:0
used_memory:3187
changes_since_last_save:0
last_save_time:1237655729
total_connections_received:1
total_commands_processed:1
uptime_in_seconds:25
uptime_in_days:0
All the fields are in the form ``field:value``
Notes
-----
- ``used_memory`` is returned in bytes, and is the total number of
bytes allocated by the program using ``malloc``.
- ``uptime_in_days`` is redundant since the uptime in seconds
contains already the full uptime information, this field is only
mainly present for humans.
- ``changes_since_last_save`` does not refer to the number of key
changes, but to the number of operations that produced some kind of
change in the dataset.
.. |Redis Documentation| image:: redis.png
@@ -0,0 +1,493 @@
`|Redis Documentation| <index.html>`_
**IntroductionToRedisDataTypes: Contents**
  `A fifteen minutes introduction to Redis data types <#A%20fifteen%20minutes%20introduction%20to%20Redis%20data%20types>`_
    `Redis keys <#Redis%20keys>`_
    `The string type <#The%20string%20type>`_
    `The List type <#The%20List%20type>`_
      `First steps with Redis lists <#First%20steps%20with%20Redis%20lists>`_
      `Pushing IDs instead of the actual data in Redis lists <#Pushing%20IDs%20instead%20of%20the%20actual%20data%20in%20Redis%20lists>`_
    `Redis Sets <#Redis%20Sets>`_
    `A digression. How to get unique identifiers for strings <#A%20digression.%20How%20to%20get%20unique%20identifiers%20for%20strings>`_
    `Sorted sets <#Sorted%20sets>`_
      `Operating on ranges <#Operating%20on%20ranges>`_
      `Back to the reddit example <#Back%20to%20the%20reddit%20example>`_
      `Updating the scores of a sorted set <#Updating%20the%20scores%20of%20a%20sorted%20set>`_
IntroductionToRedisDataTypes
============================
#sidebar `RedisGuides <RedisGuides.html>`_
A fifteen minutes introduction to Redis data types
==================================================
As you already probably know Redis is not a plain key-value store,
actually it is a **data structures server**, supporting different
kind of values. That is, you can't just set strings as values of
keys. All the following data types are supported as values:
- Binary-safe strings.
- Lists of binary-safe strings.
- Sets of binary-safe strings, that are collection of unique
unsorted elements. You can think at this as a Ruby hash where all
the keys are set to the 'true' value.
- Sorted sets, similar to Sets but where every element is
associated to a floating number score. The elements are taken
sorted by score. You can think at this as Ruby hashes where the key
is the element and the value is the score, but where elements are
always taken in order without requiring a sorting operation.
It's not always trivial to grasp how this data types work and what
to use in order to solve a given problem from the
`Redis command reference <CommandReference.html>`_, so this
document is a crash course to Redis data types and their most used
patterns.
For all the examples we'll use the **redis-cli** utility, that's a
simple but handy command line utility to issue commands against the
Redis server.
Redis keys
----------
Before to start talking about the different kind of values
supported by Redis it is better to start saying that keys are not
binary safe strings in Redis, but just strings not containing a
space or a newline character. For instance "foo" or "123456789" or
"foo\_bar" are valid keys, while "hello world" or "hello\\n" are
not.
Actually there is nothing inside the Redis internals preventing the
use of binary keys, it's just a matter of protocol, and actually
the new protocol introduced with Redis 1.2 (1.2 betas are 1.1.x) in
order to implement commands like MSET, is totally binary safe.
Still for now consider this as an hard limit as the database is
only tested with "normal" keys.
A few other rules about keys:
- Too long keys are not a good idea, for instance a key of 1024
bytes is not a good idea not only memory-wise, but also because the
lookup of the key in the dataset may require several costly
key-comparisons.
- Too short keys are not a good idea. There is no point in writing
"u:1000:pwd" as key if you can write instead "user:1000:password",
the latter is more readable and the added space is very little
compared to the space used by the key object itself.
- Try to stick with a schema. For instance "object-type:id:field"
can be a nice idea, like in "user:1000:password". I like to use
dots for multi-words fields, like in "comment:1234:reply.to".
The string type
---------------
This is the simplest Redis type. If you use only this type, Redis
will be something like a memcached server with persistence.
Let's play a bit with the string type:
::
$ ./redis-cli set mykey "my binary safe value"
OK
$ ./redis-cli get mykey
my binary safe value
As you can see using the `Set command <SetCommand.html>`_ and the
`Get command <GetCommand.html>`_ is trivial to set values to
strings and have this strings returned back.
Values can be strings (including binary data) of every kind, for
instance you can store a jpeg image inside a key. A value can't be
bigger than 1 Gigabyte.
Even if strings are the basic values of Redis, there are
interesting operations you can perform against them. For instance
one is atomic increment:
::
$ ./redis-cli set counter 100
OK
$ ./redis-cli incr counter
(integer) 101
$ ./redis-cli incr counter
(integer) 102
$ ./redis-cli incrby counter 10
(integer) 112
The `INCR <IncrCommand.html>`_ command parses the string value as
an integer, increments it by one, and finally sets the obtained
value as the new string value. There are other similar commands
like `INCRBY <IncrCommand.html>`_, `DECR <IncrCommand.html>`_ and
`DECRBY <IncrCommand.html>`_. Actually internally it's always the
same command, acting in a slightly different way.
What means that INCR is atomic? That even multiple clients issuing
INCR against the same key will never incur into a race condition.
For instance it can't never happen that client 1 read "10", client
2 read "10" at the same time, both increment to 11, and set the new
value of 11. The final value will always be of 12 ad the
read-increment-set operation is performed while all the other
clients are not executing a command at the same time.
Another interesting operation on string is the
`GETSET <GetsetCommand.html>`_ command, that does just what its
name suggests: Set a key to a new value, returning the old value,
as result. Why this is useful? Example: you have a system that
increments a Redis key using the `INCR <IncrCommand.html>`_ command
every time your web site receives a new visit. You want to collect
this information one time every hour, without loosing a single key.
You can GETSET the key assigning it the new value of "0" and
reading the old value back.
The List type
-------------
To explain the List data type it's better to start with a little of
theory, as the term **List** is often used in an improper way by
information technology folks. For instance "Python Lists" are not
what the name may suggest (Linked Lists), but them are actually
Arrays (the same data type is called Array in Ruby actually).
From a very general point of view a List is just a sequence of
ordered elements: 10,20,1,2,3 is a list, but when a list of items
is implemented using an Array and when instead a **Linked List** is
used for the implementation, the properties change a lot.
Redis lists are implemented via Linked Lists, this means that even
if you have million of elements inside a list, the operation of
adding a new element in the head or in the tail of the list is
performed **in constant time**. Adding a new element with the
`LPUSH <LpushCommand.html>`_ command to the head of a ten elements
list is the same speed as adding an element to the head of a 10
million elements list.
What's the downside? That accessing an element **by index** is very
fast in lists implemented with an Array and not so fast in lists
implemented by linked lists.
Redis Lists are implemented with linked lists because for a
database system is crucial to be able to add elements to a very
long list in a very fast way. Another strong advantage is, as
you'll see in a moment, that Redis Lists can be taken at constant
length in constant time.
First steps with Redis lists
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The `LPUSH <RpushCommand.html>`_ command add a new element into a
list, on the left (on head), while the `RPUSH <RpushCommand.html>`_
command add a new element into alist, ot the right (on tail).
Finally the `LRANGE <LrangeCommand.html>`_ command extract ranges
of elements from lists:
::
$ ./redis-cli rpush messages "Hello how are you?"
OK
$ ./redis-cli rpush messages "Fine thanks. I'm having fun with Redis"
OK
$ ./redis-cli rpush messages "I should look into this NOSQL thing ASAP"
OK
$ ./redis-cli lrange messages 0 2
1. Hello how are you?
2. Fine thanks. I'm having fun with Redis
3. I should look into this NOSQL thing ASAP
Note that `LRANGE <LrangeCommand.html>`_ takes two indexes, the
first and the last element of the range to return. Both the indexes
can be negative to tell Redis to start to count for the end, so -1
is the last element, -2 is the penultimate element of the list, and
so forth.
As you can guess from the example above, lists can be used, for
instance, in order to implement a chat system. Another use is as
queues in order to route messages between different processes. But
the key point is that
**you can use Redis lists every time you require to access data in the same order they are added**.
This will not require any SQL ORDER BY operation, will be very
fast, and will scale to millions of elements even with a toy Linux
box.
For instance in ranking systems like the social news reddit.com you
can add every new submitted link into a List, and with
`LRANGE <LrangeCommand.html>`_ it's possible to paginate results in
a trivial way.
In a blog engine implementation you can have a list for every post,
where to push blog comments, and so forth.
Pushing IDs instead of the actual data in Redis lists
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In the above example we pushed our "objects" (simply messages in
the example) directly inside the Redis list, but this is often not
the way to go, as objects can be referenced in multiple times: in a
list to preserve their chronological order, in a Set to remember
they are about a specific category, in another list but only if
this object matches some kind of requisite, and so forth.
Let's return back to the reddit.com example. A more credible
pattern for adding submitted links (news) to the list is the
following:
::
$ ./redis-cli incr next.news.id
(integer) 1
$ ./redis-cli set news:1:title "Redis is simple"
OK
$ ./redis-cli set news:1:url "http://code.google.com/p/redis"
OK
$ ./redis-cli lpush submitted.news 1
OK
We obtained an unique incremental ID for our news object just
incrementing a key, then used this ID to create the object setting
a key for every field in the object. Finally the ID of the new
object was pushed on the **submitted.news** list.
This is just the start. Check the
`Command Reference <CommandReference.html>`_ and read about all the
other list related commands. You can remove elements, rotate lists,
get and set elements by index, and of course retrieve the length of
the list with `LLEN <LLenCommand.html>`_.
Redis Sets
----------
Redis Sets are unordered collection of binary-safe strings. The
`SADD <SaddCommand.html>`_ command adds a new element to a set.
It's also possible to do a number of other operations against sets
like testing if a given element already exists, performing the
intersection, union or difference between multiple sets and so
forth. An example is worth 1000 words:
::
$ ./redis-cli sadd myset 1
(integer) 1
$ ./redis-cli sadd myset 2
(integer) 1
$ ./redis-cli sadd myset 3
(integer) 1
$ ./redis-cli smembers myset
1. 3
2. 1
3. 2
I added three elements to my set and told Redis to return back all
the elements. As you can see they are not sorted.
Now let's check if a given element exists:
::
$ ./redis-cli sismember myset 3
(integer) 1
$ ./redis-cli sismember myset 30
(integer) 0
"3" is a member of the set, while "30" is not. Sets are very good
in order to express relations between objects. For instance we can
easily use Redis Sets in order to implement tags.
A simple way to model this is to have, for every object you want to
tag, a Set with all the IDs of the tags associated with the object,
and for every tag that exists, a Set of of all the objects tagged
with this tag.
For instance if our news ID 1000 is tagged with tag 1,2,5 and 77,
we can specify the following two Sets:
::
$ ./redis-cli sadd news:1000:tags 1
(integer) 1
$ ./redis-cli sadd news:1000:tags 2
(integer) 1
$ ./redis-cli sadd news:1000:tags 5
(integer) 1
$ ./redis-cli sadd news:1000:tags 77
(integer) 1
$ ./redis-cli sadd tag:1:objects 1000
(integer) 1
$ ./redis-cli sadd tag:2:objects 1000
(integer) 1
$ ./redis-cli sadd tag:5:objects 1000
(integer) 1
$ ./redis-cli sadd tag:77:objects 1000
(integer) 1
To get all the tags for a given object is trivial:
$ ./redis-cli smembers `news:1000:tags <news:1000:tags>`_ 1. 5 2. 1
3. 77 4. 2
But there are other non trivial operations that are still easy to
implement using the right Redis commands. For instance we may want
the list of all the objects having as tags 1, 2, 10, and 27 at the
same time. We can do this using the
`SinterCommand <SinterCommand.html>`_ that performs the
intersection between different sets. So in order to reach our goal
we can just use:
::
$ ./redis-cli sinter tag:1:objects tag:2:objects tag:10:objects tag:27:objects
... no result in our dataset composed of just one object ;) ...
Look at the `Command Reference <CommandReference.html>`_ to
discover other Set related commands, there are a bunch of
interesting one. Also make sure to check the
`SORT <SortCommand.html>`_ command as both Redis Sets and Lists are
sortable.
A digression. How to get unique identifiers for strings
-------------------------------------------------------
In our tags example we showed tag IDs without to mention how this
IDs can be obtained. Basically for every tag added to the system,
you need an unique identifier. You also want to be sure that there
are no race conditions if multiple clients are trying to add the
same tag at the same time. Also, if a tag already exists, you want
its ID returned, otherwise a new unique ID should be created and
associated to the tag.
Redis 1.4 will add the Hash type. With it it will be trivial to
associate strings with unique IDs, but how to do this today with
the current commands exported by Redis in a reliable way?
Our first attempt (that is broken) can be the following. Let's
suppose we want to get an unique ID for the tag "redis":
- In order to make this algorithm binary safe (they are just tags
but think to utf8, spaces and so forth) we start performing the
SHA1 sum of the tag. SHA1(redis) =
b840fc02d524045429941cc15f59e41cb7be6c52.
- Let's check if this tag is already associated with an unique ID
with the command
**GET tag:b840fc02d524045429941cc15f59e41cb7be6c52:id**.
- If the above GET returns an ID, return it back to the user. We
already have the unique ID.
- Otherwise... create a new unique ID with **INCR next.tag.id**
(assume it returned 123456).
- Finally associate this new ID to our tag with
**SET tag:b840fc02d524045429941cc15f59e41cb7be6c52:id 123456** and
return the new ID to the caller.
Nice. Or better.. broken! What about if two clients perform this
commands at the same time trying to get the unique ID for the tag
"redis"? If the timing is right they'll both get **nil** from the
GET operation, will both increment the **next.tag.id** key and will
set two times the key. One of the two clients will return the wrong
ID to the caller. To fix the algorithm is not hard fortunately, and
this is the sane version:
- In order to make this algorithm binary safe (they are just tags
but think to utf8, spaces and so forth) we start performing the
SHA1 sum of the tag. SHA1(redis) =
b840fc02d524045429941cc15f59e41cb7be6c52.
- Let's check if this tag is already associated with an unique ID
with the command
**GET tag:b840fc02d524045429941cc15f59e41cb7be6c52:id**.
- If the above GET returns an ID, return it back to the user. We
already have the unique ID.
- Otherwise... create a new unique ID with **INCR next.tag.id**
(assume it returned 123456).
- Finally associate this new ID to our tag with
**SETNX tag:b840fc02d524045429941cc15f59e41cb7be6c52:id 123456**.
By using SETNX if a different client was faster than this one the
key wil not be setted. Not only, SETNX returns 1 if the key is set,
0 otherwise. So... let's add a final step to our computation.
- If SETNX returned 1 (We set the key) return 123456 to the
caller, it's our tag ID, otherwise perform
**GET tag:b840fc02d524045429941cc15f59e41cb7be6c52:id** and return
the value to the caller.
Sorted sets
-----------
Sets are a very handy data type, but... they are a bit too unsorted
in order to fit well for a number of problems ;) This is why Redis
1.2 introduced Sorted Sets. They are very similar to Sets,
collections of binary-safe strings, but this time with an
associated score, and an operation similar to the List LRANGE
operation to return items in order, but working against Sorted
Sets, that is, the `ZRANGE <ZrangeCommand.html>`_ command.
Basically Sorted Sets are in some way the Redis equivalent of
Indexes in the SQL world. For instance in our reddit.com example
above there was no mention about how to generate the actual home
page with news raked by user votes and time. We'll see how sorted
sets can fix this problem, but it's better to start with something
simpler, illustrating the basic working of this advanced data type.
Let's add a few selected hackers with their year of birth as
"score".
::
$ ./redis-cli zadd hackers 1940 "Alan Kay"
(integer) 1
$ ./redis-cli zadd hackers 1953 "Richard Stallman"
(integer) 1
$ ./redis-cli zadd hackers 1965 "Yukihiro Matsumoto"
(integer) 1
$ ./redis-cli zadd hackers 1916 "Claude Shannon"
(integer) 1
$ ./redis-cli zadd hackers 1969 "Linus Torvalds"
(integer) 1
$ ./redis-cli zadd hackers 1912 "Alan Turing"
(integer) 1
For sorted sets it's a joke to return these hackers sorted by their
birth year because actually **they are already sorted**. Sorted
sets are implemented via a dual-ported data structure containing
both a skip list and an hash table, so every time we add an element
Redis performs an O(log(N)) operation, that's good, but when we ask
for sorted elements Redis does not have to do any work at all, it's
already all sorted:
::
$ ./redis-cli zrange hackers 0 -1
1. Alan Turing
2. Claude Shannon
3. Alan Kay
4. Richard Stallman
5. Yukihiro Matsumoto
6. Linus Torvalds
Didn't know that Linus was younger than Yukihiro btw ;)
Anyway I want to order this elements the other way around, using
`ZrangeCommand <ZREVRANGE.html>`_ instead of
`ZrangeCommand <ZRANGE.html>`_ this time:
::
$ ./redis-cli zrevrange hackers 0 -1
1. Linus Torvalds
2. Yukihiro Matsumoto
3. Richard Stallman
4. Alan Kay
5. Claude Shannon
6. Alan Turing
A very important note, ZSets have just a "default" ordering but you
are still free to call the `SORT <SortCommand.html>`_ command
against sorted sets to get a different ordering (but this time the
server will waste CPU). An alternative for having multiple orders
is to add every element in multiple sorted sets at the same time.
Operating on ranges
~~~~~~~~~~~~~~~~~~~
Sorted sets are more powerful than this. They can operate on
ranges. For instance let's try to get all the individuals that born
up to the 1950. We use the
`ZRANGEBYSCORE <ZrangebyscoreCommand.html>`_ command to do it:
::
$ ./redis-cli zrangebyscore hackers -inf 1950
1. Alan Turing
2. Claude Shannon
3. Alan Kay
We asked Redis to return all the elements with a score between
negative infinite and 1950 (both extremes are included).
It's also possible to remove ranges of elements. For instance let's
remove all the hackers born between 1940 and 1960 from the sorted
set:
::
$ ./redis-cli zremrangebyscore hackers 1940 1960
(integer) 2
`ZREMRANGEBYSCORE <ZremrangebyscoreCommand.html>`_ is not the best
command name, but it can be very useful, and returns the number of
removed elements.
Back to the reddit example
~~~~~~~~~~~~~~~~~~~~~~~~~~
For the last time, back to the Reddit example. Now we have a decent
plan to populate a sorted set in order to generate the home page. A
sorted set can contain all the news that are not older than a few
days (we remove old entries from time to time using
ZREMRANGEBYSCORE). A background job gets all the elements from this
sorted set, get the user votes and the time of the news, and
compute the score to populate the **reddit.home.page** sorted set
with the news IDs and associated scores. To show the home page we
have just to perform a blazingly fast call to ZRANGE.
From time to time we'll remove too old news from the
**reddit.home.page** sorted set as well in order for our system to
work always against a limited set of news.
Updating the scores of a sorted set
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Just a final note before to finish this tutorial. Sorted sets
scores can be updated at any time. Just calling again ZADD against
an element already included in the sorted set will update its score
(and position) in O(log(N)), so sorted sets are suitable even when
there are tons of updates.
This tutorial is in no way complete, this is just the basics to get
started with Redis, read the
`Command Reference <CommandReference.html>`_ to discover a lot
more.
Thanks for reading. Salvatore.
.. |Redis Documentation| image:: redis.png
+42
View File
@@ -0,0 +1,42 @@
`|Redis Documentation| <index.html>`_
**KeysCommand: Contents**
  `KEYS \_pattern\_ <#KEYS%20_pattern_>`_
    `Return value <#Return%20value>`_
KeysCommand
===========
#sidebar `GenericCommandsSidebar <GenericCommandsSidebar.html>`_
KEYS \_pattern\_
================
*Time complexity: O(n) (with n being the number of keys in the DB, and assuming keys and pattern of limited length)*
Returns all the keys matching the glob-style *pattern* asspace
separated strings. For example if you have in thedatabase the keys
"foo" and "foobar" the command "KEYS foo``*``"will return "foo
foobar".
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 of**
the slow commands that may ruin the DB performance if not usedwith
care\*.
In other words this command is intended only for debugging and
\*special\* operations like creating a script to change the DB
schema. Don't use it in your normal code. Use Redis
`Sets <Sets.html>`_ in order to group together a subset of
objects.
Glob style patterns examples:
\* h?llo will match hello hallo hhllo\* h\*llo will match hllo
heeeello\* h``[``ae``]``llo will match hello and hallo, but not
hillo
Use \\ to escape special chars if you want to match them verbatim.
Return value
------------
`Multi bulk reply <ReplyTypes.html>`_
.. |Redis Documentation| image:: redis.png
+23
View File
@@ -0,0 +1,23 @@
`|Redis Documentation| <index.html>`_
**LastsaveCommand: Contents**
  `LASTSAVE <#LASTSAVE>`_
    `Return value <#Return%20value>`_
LastsaveCommand
===============
#sidebar `ControlCommandsSidebar <ControlCommandsSidebar.html>`_
LASTSAVE
========
Return the UNIX TIME of the last DB save executed with success.A
client may check if a `BGSAVE <BgsaveCommand.html>`_ command
succeeded reading the LASTSAVEvalue, then issuing a
`BGSAVE <BgsaveCommand.html>`_ command and checking at regular
intervalsevery N seconds if LASTSAVE changed.
Return value
------------
`Integer reply <ReplyTypes.html>`_, specifically an UNIX time
stamp.
.. |Redis Documentation| image:: redis.png
+29
View File
@@ -0,0 +1,29 @@
`|Redis Documentation| <index.html>`_
**LindexCommand: Contents**
  `LINDEX \_key\_ \_index\_ <#LINDEX%20_key_%20_index_>`_
    `Return value <#Return%20value>`_
LindexCommand
=============
#sidebar `ListCommandsSidebar <ListCommandsSidebar.html>`_
LINDEX \_key\_ \_index\_
========================
*Time complexity: O(n) (with n being the length of the list)*
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.
If the value stored at key is not of list type an error is
returned.If the index is out of range a 'nil' reply is returned.
Note that even if the average time complexity is O(n) asking forthe
first or the last element of the list is O(1).
Return value
------------
`Bulk reply <ReplyTypes.html>`_, specifically the requested
element.
.. |Redis Documentation| image:: redis.png
+24
View File
@@ -0,0 +1,24 @@
`|Redis Documentation| <index.html>`_
**ListCommandsSidebar: Contents**
ListCommandsSidebar
===================
== List Commands ==
- `RPUSH <RpushCommand.html>`_
- `LPUSH <RpushCommand.html>`_
- `LLEN <LlenCommand.html>`_
- `LRANGE <LrangeCommand.html>`_
- `LTRIM <LtrimCommand.html>`_
- `LINDEX <LindexCommand.html>`_
- `LSET <LsetCommand.html>`_
- `LREM <LremCommand.html>`_
- `LPOP <LpopCommand.html>`_
- `RPOP <LpopCommand.html>`_
- `BLPOP <BlpopCommand.html>`_
- `BRPOP <BlpopCommand.html>`_
- `RPOPLPUSH <RpoplpushCommand.html>`_
- `BRPOPLPUSH <BrpoplpushCommand.html>`_
- `SORT <SortCommand.html>`_
.. |Redis Documentation| image:: redis.png
+43
View File
@@ -0,0 +1,43 @@
`|Redis Documentation| <index.html>`_
**Lists: Contents**
  `Redis List Type <#Redis%20List%20Type>`_
  `Implementation details <#Implementation%20details>`_
Lists
=====
#sidebar `ListCommandsSidebar <ListCommandsSidebar.html>`_
Redis List Type
===============
Redis Lists are lists of `Redis Strings <Strings.html>`_, 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.
The `LPUSH <RpushCommand.html>`_ command inserts a new elmenet on
head, while `RPUSH <RpushCommand.html>`_ inserts a new element on
tail. A new list is created when one of this operations is
performed against an empty key.
For instance if perform the following operations:
::
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)
The resulting list stored at *mylist* will contain the elements
"b","a","c".
The max length of a list is 232-1 elements (4294967295, more than 4
billion of elements per list).
Implementation details
======================
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). `LRANGE <LrangeCommand.html>`_ and
`LINDEX <LindexCommand.html>`_ are examples of such commands.
The use of linked lists also guarantees that regardless of the
length of the list pushing and popping are O(1) operations.
Redis Lists cache length information so `LLEN <LlenCommand.html>`_
is O(1) as well.
.. |Redis Documentation| image:: redis.png
+26
View File
@@ -0,0 +1,26 @@
`|Redis Documentation| <index.html>`_
**LlenCommand: Contents**
  `LLEN \_key\_ <#LLEN%20_key_>`_
    `Return value <#Return%20value>`_
LlenCommand
===========
#sidebar `ListCommandsSidebar <ListCommandsSidebar.html>`_
LLEN \_key\_
============
*Time complexity: O(1)*
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 *key* is not a list an
error is returned.
Return value
------------
`Integer reply <ReplyTypes.html>`_, specifically:
::
The length of the list.
.. |Redis Documentation| image:: redis.png
+28
View File
@@ -0,0 +1,28 @@
`|Redis Documentation| <index.html>`_
**LpopCommand: Contents**
  `LPOP \_key\_ <#LPOP%20_key_>`_
  `RPOP \_key\_ <#RPOP%20_key_>`_
    `Return value <#Return%20value>`_
LpopCommand
===========
#sidebar `ListCommandsSidebar <ListCommandsSidebar.html>`_
LPOP \_key\_
============
RPOP \_key\_
============
*Time complexity: O(1)*
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".
If the *key* does not exist or the list is already empty the
specialvalue 'nil' is returned.
Return value
------------
`Bulk reply <ReplyTypes.html>`_
.. |Redis Documentation| image:: redis.png
+44
View File
@@ -0,0 +1,44 @@
`|Redis Documentation| <index.html>`_
**LrangeCommand: Contents**
  `LRANGE \_key\_ \_start\_ \_end\_ <#LRANGE%20_key_%20_start_%20_end_>`_
    `Consistency with range functions in various programming languages <#Consistency%20with%20range%20functions%20in%20various%20programming%20languages>`_
    `Out-of-range indexes <#Out-of-range%20indexes>`_
    `Return value <#Return%20value>`_
LrangeCommand
=============
#sidebar `ListCommandsSidebar <ListCommandsSidebar.html>`_
LRANGE \_key\_ \_start\_ \_end\_
================================
*Time complexity: O(start+n) (with n being the length of the range and start being the start offset)*Return
the specified elements of the list stored at the specified key.
Start and end are zero-based indexes. 0 is the first element of the
list (the list head), 1 the next element and so on.
For example LRANGE foobar 0 2 will return the first three elements
of the list.
*start* and *end* can also be negative numbers indicating offsets
from the end of the list. For example -1 is the last element of the
list, -2 the penultimate element and so on.
Consistency with range functions in various programming languages
-----------------------------------------------------------------
Note that if you have a list of numbers from 0 to 100, LRANGE 0 10
will return 11 elements, that is, rightmost item is included. This
**may or may not** be consistent with behavior of range-related
functions in your programming language of choice (think Ruby's
Range.new, Array#slice or Python's range() function).
LRANGE behavior is consistent with one of Tcl.
Out-of-range indexes
--------------------
Indexes out of range will not produce an error: if start is over
the end of the list, or start ``>`` end, an empty list is returned.
If end is over the end of the list Redis will threat it just like
the last element of the list.
Return value
------------
`Multi bulk reply <ReplyTypes.html>`_, specifically a list of
elements in the specified range.
.. |Redis Documentation| image:: redis.png
+32
View File
@@ -0,0 +1,32 @@
`|Redis Documentation| <index.html>`_
**LremCommand: Contents**
  `LREM \_key\_ \_count\_ \_value\_ <#LREM%20_key_%20_count_%20_value_>`_
    `Return value <#Return%20value>`_
LremCommand
===========
#sidebar `ListCommandsSidebar <ListCommandsSidebar.html>`_
LREM \_key\_ \_count\_ \_value\_
================================
*Time complexity: O(N) (with N being the length of the list)*
Remove the first *count* occurrences of the *value* element from
the list.If *count* is zero all the elements are removed. If
*count* 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.
Return value
------------
`Integer Reply <ReplyTypes.html>`_, specifically:
::
The number of removed elements if the operation succeeded
.. |Redis Documentation| image:: redis.png
+26
View File
@@ -0,0 +1,26 @@
`|Redis Documentation| <index.html>`_
**LsetCommand: Contents**
  `LSET \_key\_ \_index\_ \_value\_ <#LSET%20_key_%20_index_%20_value_>`_
    `Return value <#Return%20value>`_
LsetCommand
===========
#sidebar `ListCommandsSidebar <ListCommandsSidebar.html>`_
LSET \_key\_ \_index\_ \_value\_
================================
*Time complexity: O(N) (with N being the length of the list)*
Set the list element at *index* (see LINDEX for information about
the\_index\_ argument) with the new *value*. Out of range indexes
willgenerate an error. Note that setting the first or last elements
ofthe list is O(1).
Similarly to other list commands accepting indexes, the index can
be negative to access elements starting from the end of the list.
So -1 is the last element, -2 is the penultimate, and so forth.
Return value
------------
`Status code reply <ReplyTypes.html>`_
.. |Redis Documentation| image:: redis.png
+49
View File
@@ -0,0 +1,49 @@
`|Redis Documentation| <index.html>`_
**LtrimCommand: Contents**
  `LTRIM \_key\_ \_start\_ \_end\_ <#LTRIM%20_key_%20_start_%20_end_>`_
    `Return value <#Return%20value>`_
LtrimCommand
============
#sidebar `ListCommandsSidebar <ListCommandsSidebar.html>`_
LTRIM \_key\_ \_start\_ \_end\_
===============================
*Time complexity: O(n) (with n being len of list - len of range)*
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.
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.
\_start\_ and *end* 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.
Indexes out of range will not produce an error: if start is overthe
end of the list, or start > end, an empty list is left as value.If
end over the end of the list Redis will threat it just likethe last
element of the list.
Hint: the obvious use of LTRIM is together with LPUSH/RPUSH. For
example:
::
LPUSH mylist <someelement>
LTRIM mylist 0 99
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.
Return value
------------
`Status code reply <ReplyTypes.html>`_
.. |Redis Documentation| image:: redis.png
+40
View File
@@ -0,0 +1,40 @@
`|Redis Documentation| <index.html>`_
**MgetCommand: Contents**
  `MGET \_key1\_ \_key2\_ ... \_keyN\_ <#MGET%20_key1_%20_key2_%20...%20_keyN_>`_
    `Return value <#Return%20value>`_
    `Example <#Example>`_
MgetCommand
===========
#sidebar `StringCommandsSidebar <StringCommandsSidebar.html>`_
MGET \_key1\_ \_key2\_ ... \_keyN\_
===================================
*Time complexity: O(1) for every key*
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.
Return value
------------
`Multi bulk reply <ReplyTypes.html>`_
Example
-------
::
$ ./redis-cli set foo 1000
+OK
$ ./redis-cli set bar 2000
+OK
$ ./redis-cli mget foo bar
1. 1000
2. 2000
$ ./redis-cli mget foo bar nokey
1. 1000
2. 2000
3. (nil)
$
.. |Redis Documentation| image:: redis.png
+54
View File
@@ -0,0 +1,54 @@
`|Redis Documentation| <index.html>`_
**MonitorCommand: Contents**
  `MONITOR <#MONITOR>`_
    `Return value <#Return%20value>`_
MonitorCommand
==============
#sidebar `ControlCommandsSidebar <ControlCommandsSidebar.html>`_
MONITOR
=======
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.
::
% telnet 127.0.0.1 6379
Trying 127.0.0.1...
Connected to segnalo-local.com.
Escape character is '^]'.
MONITOR
+OK
monitor
keys *
dbsize
set x 6
foobar
get x
del x
get x
set key_x 5
hello
set key_y 5
hello
set key_z 5
hello
set foo_a 5
hello
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.
In order to end a monitoring session just issue a QUIT command by
hand.
Return value
------------
**Non standard return value**, just dumps the received commands in
an infinite flow.
.. |Redis Documentation| image:: redis.png
+27
View File
@@ -0,0 +1,27 @@
`|Redis Documentation| <index.html>`_
**MoveCommand: Contents**
  `MOVE \_key\_ \_dbindex\_ <#MOVE%20_key_%20_dbindex_>`_
    `Return value <#Return%20value>`_
MoveCommand
===========
#sidebar `GenericCommandsSidebar <GenericCommandsSidebar.html>`_
MOVE \_key\_ \_dbindex\_
========================
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.
Return value
------------
`Integer reply <ReplyTypes.html>`_, specifically:
::
1 if the key was moved
0 if the key was not moved because already present on the target DB or was not found in the current DB.
.. |Redis Documentation| image:: redis.png
+47
View File
@@ -0,0 +1,47 @@
`|Redis Documentation| <index.html>`_
**MsetCommand: Contents**
  `MSET \_key1\_ \_value1\_ \_key2\_ \_value2\_ ... \_keyN\_ \_valueN\_ (Redis > <#MSET%20_key1_%20_value1_%20_key2_%20_value2_%20...%20_keyN_%20_valueN_%20(Redis%20%3E>`_
  `MSETNX \_key1\_ \_value1\_ \_key2\_ \_value2\_ ... \_keyN\_ \_valueN\_ (Redis > <#MSETNX%20_key1_%20_value1_%20_key2_%20_value2_%20...%20_keyN_%20_valueN_%20(Redis%20%3E>`_
    `MSET Return value <#MSET%20Return%20value>`_
    `MSETNX Return value <#MSETNX%20Return%20value>`_
MsetCommand
===========
#sidebar `StringCommandsSidebar <StringCommandsSidebar.html>`_
MSET \_key1\_ \_value1\_ \_key2\_ \_value2\_ ... \_keyN\_ \_valueN\_ (Redis >
=============================================================================
1.1) =
MSETNX \_key1\_ \_value1\_ \_key2\_ \_value2\_ ... \_keyN\_ \_valueN\_ (Redis >
===============================================================================
1.1) = *Time complexity: O(1) to set every key*
Set the the respective keys to the respective values. MSET will
replace oldvalues with new values, while MSETNX will not perform
any operation at alleven if just a single key already exists.
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.
Both MSET and MSETNX are atomic operations. This means that for
instanceif the keys A and B are modified, another client talking to
Redis can eithersee the changes to both A and B at once, or no
modification at all.
MSET Return value
-----------------
`Status code reply <ReplyTypes.html>`_ Basically +OK as MSET can't
fail
MSETNX Return value
-------------------
`Integer reply <ReplyTypes.html>`_, specifically:
::
1 if the all the keys were set
0 if no key was set (at least one key already existed)
.. |Redis Documentation| image:: redis.png
+253
View File
@@ -0,0 +1,253 @@
`|Redis Documentation| <index.html>`_
**MultiExecCommand: Contents**
  `WATCH key1 key2 ... keyN (Redis > <#WATCH%20key1%20key2%20...%20keyN%20(Redis%20%3E>`_
  `UNWATCH <#UNWATCH>`_
  `MULTI <#MULTI>`_
  `COMMAND\_1 ... <#COMMAND_1%20...>`_
  `COMMAND\_2 ... <#COMMAND_2%20...>`_
  `COMMAND\_N ... <#COMMAND_N%20...>`_
  `EXEC or DISCARD <#EXEC%20or%20DISCARD>`_
    `Usage <#Usage>`_
    `The DISCARD command <#The%20DISCARD%20command>`_
    `Check and Set (CAS) transactions using WATCH <#Check%20and%20Set%20(CAS)%20transactions%20using%20WATCH>`_
    `WATCH explained <#WATCH%20explained>`_
    `WATCH used to implement ZPOP <#WATCH%20used%20to%20implement%20ZPOP>`_
    `Return value <#Return%20value>`_
MultiExecCommand
================
#sidebar `GenericCommandsSidebar <GenericCommandsSidebar.html>`_
WATCH key1 key2 ... keyN (Redis >
=================================
2.1.0)=
UNWATCH
=======
MULTI
=====
COMMAND\_1 ...
==============
COMMAND\_2 ...
==============
COMMAND\_N ...
==============
EXEC or DISCARD
===============
MULTI, EXEC, DISCARD and WATCH commands are the foundation of Redis
Transactions. A Redis Transaction allows the execution of a group
of Redis commands in a single step, with two important guarantees:
- All the commands in a transaction are serialized and executed
sequentially. It can never happen that a request issued by another
client is served **in the middle** of the execution of a Redis
transaction. This guarantees that the commands are executed as a
single atomic operation.
- Either all of the commands or none are processed. The EXEC
command triggers the execution of all the commands in the
transaction, so if a client loses the connection to the server in
the context of a transaction before calling the MULTI command none
of the operations are performed, instead if the EXEC command is
called, all the operations are performed. An exception to this rule
is when the Append Only File is enabled: every command that is part
of a Redis transaction will log in the AOF as long as the operation
is completed, so if the Redis server crashes or is killed by the
system administrator in some hard way it is possible that only a
partial number of operations are registered.
Since Redis 2.1.0, it's also possible to add a further guarantee to
the above two, in the form of optimistic locking of a set of keys
in a way very similar to a CAS (check and set) operation. This is
documented later in this manual page.
Usage
-----
A Redis transaction is entered using the MULTI command. The command
always replies with OK. At this point the user can issue multiple
commands. Instead of executing these commands, Redis will "queue"
them. All the commands are executed once EXEC is called.
Calling DISCARD instead will flush the transaction queue and will
exit the transaction.
The following is an example using the Ruby client:
::
?> r.multi
=> "OK"
>> r.incr "foo"
=> "QUEUED"
>> r.incr "bar"
=> "QUEUED"
>> r.incr "bar"
=> "QUEUED"
>> r.exec
=> [1, 1, 2]
As it is possible to see from the session above, MULTI returns an
"array" of replies, where every element is the reply of a single
command in the transaction, in the same order the commands were
queued.
When a Redis connection is in the context of a MULTI request, all
the commands will reply with a simple string "QUEUED" if they are
correct from the point of view of the syntax and arity (number of
arguments) of the commaand. Some commands are still allowed to fail
during execution time.
This is more clear on the protocol level; In the following example
one command will fail when executed even if the syntax is right:
::
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
MULTI
+OK
SET a 3
abc
+QUEUED
LPOP a
+QUEUED
EXEC
*2
+OK
-ERR Operation against a key holding the wrong kind of value
MULTI returned a two elements bulk reply where one is an +OK code
and one is a -ERR reply. It's up to the client lib to find a
sensible way to provide the error to the user.
IMPORTANT: even when a command will raise an error, all the other
commandsin the queue will be processed. Redis will NOT stop the
processing ofcommands once an error is found.
Another example, again using the write protocol with telnet, shows
how syntax errors are reported ASAP instead:
::
MULTI
+OK
INCR a b c
-ERR wrong number of arguments for 'incr' command
This time due to the syntax error the "bad" INCR command is not
queued at all.
The DISCARD command
-------------------
DISCARD can be used in order to abort a transaction. No command
will be executed, and the state of the client is again the normal
one, outside of a transaction. Example using the Ruby client:
::
?> r.set("foo",1)
=> true
>> r.multi
=> "OK"
>> r.incr("foo")
=> "QUEUED"
>> r.discard
=> "OK"
>> r.get("foo")
=> "1"
Check and Set (CAS) transactions using WATCH
--------------------------------------------
WATCH is used in order to provide a CAS (Check and Set) behavior to
Redis Transactions.
WATCHed keys are monitored in order to detect changes against this
keys. If at least a watched key will be modified before the EXEC
call, the whole transaction will abort, and EXEC will return a nil
object (A Null Multi Bulk reply) to notify that the transaction
failed.
For example imagine we have the need to atomically increment the
value of a key by 1 (I know we have INCR, let's suppose we don't
have it).
The first try may be the following:
::
val = GET mykey
val = val + 1
SET mykey $val
This will work reliably only if we have a single client performing
the operation in a given time. If multiple clients will try to
increment the key about at the same time there will be a race
condition. For instance client A and B will read the old value, for
instance, 10. The value will be incremented to 11 by both the
clients, and finally SET as the value of the key. So the final
value will be "11" instead of "12".
Thanks to WATCH we are able to model the problem very well:
::
WATCH mykey
val = GET mykey
val = val + 1
MULTI
SET mykey $val
EXEC
Using the above code, if there are race conditions and another
client modified the result of *val* in the time between our call to
WATCH and our call to EXEC, the transaction will fail.
We'll have just to re-iterate the operation hoping this time we'll
not get a new race. This form of locking is called
**optimistic locking** and is a very powerful form of locking as in
many problems there are multiple clients accessing a much bigger
number of keys, so it's very unlikely that there are collisions:
usually operations don't need to be performed multiple times.
WATCH explained
---------------
So what is WATCH really about? It is a command that will make the
EXEC conditional: we are asking Redis to perform the transaction
only if no other client modified any of the WATCHed keys. Otherwise
the transaction is not entered at all. (Note that if you WATCH a
volatile key and Redis expires the key after you WATCHed it, EXEC
will still work.
`More <http://code.google.com/p/redis/issues/detail?id=270>`_.)
WATCH can be called multiple times. Simply all the WATCH calls will
have the effects to watch for changes starting from the call, up to
the moment EXEC is called.
When EXEC is called, either if it will fail or succeed, all keys
are UNWATCHed. Also when a client connection is closed, everything
gets UNWATCHed.
It is also possible to use the UNWATCH command (without arguments)
in order to flush all the watched keys. Sometimes this is useful as
we optimistically lock a few keys, since possibly we need to
perform a transaction to alter those keys, but after reading the
current content of the keys we don't want to proceed. When this
happens we just call UNWATCH so that the connection can already be
used freely for new transactions.
WATCH used to implement ZPOP
----------------------------
A good example to illustrate how WATCH can be used to create new
atomic operations otherwise not supported by Redis is to implement
ZPOP, that is a command that pops the element with the lower score
from a sorted set in an atomic way. This is the simplest
implementation:
::
WATCH zset
ele = ZRANGE zset 0 0
MULTI
ZREM zset ele
EXEC
If EXEC fails (returns a nil value) we just re-iterate the
operation.
Return value
------------
`Multi bulk reply <ReplyTypes.html>`_, specifically:
::
The result of a MULTI/EXEC command is a multi bulk reply where every element is the return value of every command in the atomic transaction.
If a MULTI/EXEC transaction is aborted because of WATCH detected
modified keys, a `Null Multi Bulk reply <ReplyTypes.html>`_ is
returned.
.. |Redis Documentation| image:: redis.png
+48
View File
@@ -0,0 +1,48 @@
`|Redis Documentation| <index.html>`_
**NonexistentCommands: Contents**
  `HGETSET <#HGETSET>`_
  `SET with expire <#SET%20with%20expire>`_
  `ZADDNX <#ZADDNX>`_
NonexistentCommands
===================
A list of commands that don't exist in Redis, but can be
accomplished in a different way.
This is a list of commands that don't exist in Redis, but can be
accomplished in a different way, usually by means of
`WATCH/MULTI/EXEC <MultiExecCommand.html>`_.
For better performance, you can pipeline multiple commands.
HGETSET
=======
`GETSET <GetsetCommand.html>`_ for Hashes.
::
WATCH foo
old_value = HGET foo field
MULTI
HSET foo field new_value
EXEC
SET with expire
===============
See `SETEX <SetexCommand.html>`_.
ZADDNX
======
Add an element to a sorted set, only if the element doesn't already
exist (by default, `ZADD <ZaddCommand.html>`_ would update the
element's score if it already exists).
`See thread <http://groups.google.com/group/redis-db/browse_thread/thread/fc4c79d72e5bd346/6cdc07ecc36b81e7>`_.
::
WATCH foo
score = ZSCORE foo bar
IF score != NIL
MULTI
ZADD foo 1 bar
EXEC
ENDIF
.. |Redis Documentation| image:: redis.png
+59
View File
@@ -0,0 +1,59 @@
`|Redis Documentation| <index.html>`_
**ObjectHashMappers: Contents**
  `Object Hash Mappers <#Object%20Hash%20Mappers>`_
    `Ruby <#Ruby>`_
      `Ohm <#Ohm>`_
      `dm-redis-adapter <#dm-redis-adapter>`_
      `redis-models <#redis-models>`_
ObjectHashMappers
=================
Object Hash Mappers
===================
Looking for a higher level if abstraction for your Objects, their
Properties and Relationships?
There is not need to stick to the
`client libraries <SupportedLanguages.html>`_ exposing the raw
features of Redis, here you will find a list of
**Object Hash Mappers**, working in the same fashion a ORM does.
Ruby
----
Ohm
~~~
- Object-hash mapping library for Redis. It includes an extensible
list of validations and has very good performance.
- Authors: `Michel Martens <http://soveran.com/>`_,
`@soveran <http://twitter.com/soveran>`_; and Damian Janowski
`@djanowski <http://twitter.com/djanowski>`_.
- Repository:
`http://github.com/soveran/ohm <http://github.com/soveran/ohm>`_
- Group:
`http://groups.google.com/group/ohm-ruby <http://groups.google.com/group/ohm-ruby>`_
dm-redis-adapter
~~~~~~~~~~~~~~~~
- This is a DataMapper (ORM that is based on the IdentityMap
pattern) adapter for the Redis key-value database.
- Author: `Whoahbot <http://whoahbot.com/>`_,
`@whoahbot <http://twitter.com/whoahbot>`_.
- Repository:
`http://github.com/whoahbot/dm-redis-adapter/ <http://github.com/whoahbot/dm-redis-adapter/>`_
redis-models
~~~~~~~~~~~~
- Minimal model support for Redis. Directly maps Ruby properties
to model\_name:id:field\_name keys in redis. Scalar, List and Set
properties are supported. Values can be marshaled to/from Integer,
Float, DateTime, JSON.
- Repository:
`http://github.com/voloko/redis-model <http://github.com/voloko/redis-model>`_
.. |Redis Documentation| image:: redis.png
+28
View File
@@ -0,0 +1,28 @@
`|Redis Documentation| <index.html>`_
**Pipelining: Contents**
  `Pipelining (DRAFT) <#Pipelining%20(DRAFT)>`_
Pipelining
==========
Pipelining (DRAFT)
==================
A client library can use the same connection in order to issue
multiple commands. But Redis supports **pipelining**, so multiple
commands can be sent to the server with a single write operation by
the client, without need to read the server reply in order to issue
the next command. All the replies can be read at the end.
Usually Redis server and client will have a very fast link so this
is not very important to support this feature in a client
implementation, still if an application needs to issue a very large
number of commands in s short time, using pipelining can be much
faster.
Please read the
`ProtocolSpecification <ProtocolSpecification.html>`_ if you want
to learn more about the way Redis
`clients <SupportedLanguages.html>`_ and the server communicate.
Pipelining is one of the `Speed <Speed.html>`_
`Features <Features.html>`_ of Redis, you can also check the
support for
`send and receive multiple values in a single command <MultiBulkCommands.html>`_.
.. |Redis Documentation| image:: redis.png
+95
View File
@@ -0,0 +1,95 @@
`|Redis Documentation| <index.html>`_
**ProgrammingExamples: Contents**
  `Programming Examples (DRAFT) <#Programming%20Examples%20(DRAFT)>`_
    `TODO <#TODO>`_
    `Java <#Java>`_
      `Twayis <#Twayis>`_
    `PHP <#PHP>`_
      `Retwis <#Retwis>`_
    `Ruby <#Ruby>`_
      `twatcher-lite <#twatcher-lite>`_
      `Resque <#Resque>`_
      `Retwis-rb <#Retwis-rb>`_
      `scanty-redis <#scanty-redis>`_
      `Note Taking <#Note%20Taking>`_
ProgrammingExamples
===================
Programming Examples (DRAFT)
============================
TODO
----
- Add
`http://github.com/jodosha/redis-store <http://github.com/jodosha/redis-store>`_
Nothing speaks better than code examples, here you are:
Java
----
Twayis
~~~~~~
A Java clone of **Retwis** showcase integration between the
`Play! framework <http://www.playframework.org/>`_ and Redis
`Google Code Project Page <http://code.google.com/p/twayis/>`_
PHP
---
Retwis
~~~~~~
A PHP Twitter clone, the original example of Redis capabilities.
With a `live demo <http://retwis.antirez.com/>`_, and an
`article explaining it design <http://code.google.com/p/redis/wiki/TwitterAlikeExample>`_.
You can find the code in the Downloads tab.
Ruby
----
twatcher-lite
~~~~~~~~~~~~~
A simplied version of the application running
`http://twatcher.com/ <http://twatcher.com/>`_ from Mirko Froehlich
(`@digitalhobbit <http://twitter.com/digitalhobbit>`_) with a full
blog post explaining its development at
`Building a Twitter Filter With Sinatra, Redis, and TweetStream <http://www.digitalhobbit.com/2009/11/08/building-a-twitter-filter-with-sinatra-redis-and-tweetstream/>`_
Resque
~~~~~~
The "simple" Redis-based queue behind Github background jobs, that
replaced SQS, Starling, ActiveMessaging, BackgroundJob, DelayedJob,
and Beanstalkd. Developed by Chris Wanstrath
(`@defunkt <http://twitter.com/defunkt>`_) the code is at
`http://github.com/defunkt/resque <http://github.com/defunkt/resque>`_,
be sure to read
`the introduction <http://github.com/blog/542-introducing-resque>`_
Retwis-rb
~~~~~~~~~
A port of **Retwis** to Ruby and
`Sinatra <http://www.sinatrarb.com/>`_ written by Daniel Lucraft
(`@DanLucraft <http://twitter.com/DanLucraft>`_) Full source code
is available at
`http://github.com/danlucraft/retwis-rb <http://github.com/danlucraft/retwis-rb>`_
scanty-redis
~~~~~~~~~~~~
Scanty is *minimal* blogging software developed by Adam Wiggins
(`@hirodusk <http://twitter.com/hirodusk>`_) It is not a blogging
engine, but itâs small and easy to modify, so it could be the
starting point for your blog.
`This fork <http://github.com/adamwiggins/scanty-redis>`_ is
modified to use Redis, a full featured key-value database, instead
of SQL.
Note Taking
~~~~~~~~~~~
A *very simple* note taking example of Ruby and Redis application
using `Sinatra <http://www.sinatrarb.com/>`_. Developed by Pieter
Noordhuis `@pnoordhuis <http://twitter.com/pnoordhuis>`_, you can
check the code at
`http://gist.github.com/86714 <http://gist.github.com/86714>`_
.. |Redis Documentation| image:: redis.png
+298
View File
@@ -0,0 +1,298 @@
`|Redis Documentation| <index.html>`_
**ProtocolSpecification: Contents**
    `Networking layer <#Networking%20layer>`_
  `Requests <#Requests>`_
    `The new unified request protocol <#The%20new%20unified%20request%20protocol>`_
  `Replies <#Replies>`_
    `Single line reply <#Single%20line%20reply>`_
    `Error reply <#Error%20reply>`_
    `Integer reply <#Integer%20reply>`_
    `Bulk replies <#Bulk%20replies>`_
    `Multi-Bulk replies <#Multi-Bulk%20replies>`_
    `Nil elements in Multi-Bulk replies <#Nil%20elements%20in%20Multi-Bulk%20replies>`_
    `Multiple commands and pipelining <#Multiple%20commands%20and%20pipelining>`_
  `The old protocol for sending commands <#The%20old%20protocol%20for%20sending%20commands>`_
    `Inline Commands <#Inline%20Commands>`_
    `Bulk commands <#Bulk%20commands>`_
ProtocolSpecification
=====================
= Protocol Specification =
The Redis protocol is a compromise between the following things:
- Simple to implement.
- Fast to parse by a computer.
- Easy enough to parse by a human.
Networking layer
----------------
A client connects to a Redis server creating a TCP connection to
the port 6379. Every Redis command or data transmitted by the
client and the server is terminated by "\\r\\n" (CRLF).
Requests
========
Redis accepts commands composed of different arguments. Once a
command is received, it is processed and a reply is sent back to
the client.
The new unified request protocol
--------------------------------
The new unified protocol was introduced in Redis 1.2, but it became
the standard way for talking with the Redis server in Redis 2.0.
In the unified protocol all the arguments sent to the Redis server
are binary safe. This is the general form:
::
*<number of arguments> CR LF
$<number of bytes of argument 1> CR LF
<argument data> CR LF
...
$<number of bytes of argument N> CR LF
<argument data> CR LF
See the following example:
::
*3
$3
SET
$5
mykey
$7
myvalue
This is how the above command looks as a quoted string, so that it
is possible to see the exact value of every byte in the query:
::
"*3\r\n$3\r\nSET\r\n$5\r\nmykey\r\n$8\r\nmyvalue\r\n"
As you will see in a moment this format is also used in Redis
replies. The format used for every argument "$6\\r\\nmydata\\r\\n"
is called a Bulk Reply. While the actual unified request protocol
is what Redis uses to return list of items, and is called a Multi
Bulk Reply. It is just the sum of N different Bulk Replies prefixed
by a ``*<argc>\r\n`` string where ``<argc>`` is the number of
arguments (Bulk Replies) that will follow.
Replies
=======
Redis will reply to commands with different kinds of replies. It is
possible to check the kind of reply from the first byte sent by the
server:
- With a single line reply the first byte of the reply will be "+"
- With an error message the first byte of the reply will be "-"
- With an integer number the first byte of the reply will be ":"
- With bulk reply the first byte of the reply will be "$"
- With multi-bulk reply the first byte of the reply will be
"``*``"
Single line reply
-----------------
A single line reply is in the form of a single line string starting
with "+" terminated by "\\r\\n". For example:
::
+OK
The client library should return everything after the "+", that is,
the string "OK" in the example.
The following commands reply with a single line reply: PING, SET,
SELECT, SAVE, BGSAVE, SHUTDOWN, RENAME, LPUSH, RPUSH, LSET, LTRIM
Error reply
-----------
Errors are sent exactly like Single Line Replies. The only
difference is that the first byte is "-" instead of "+".
Error replies are only sent when something strange happened, for
instance if you try to perform an operation against the wrong data
type, or if the command does not exist and so forth. So an
exception should be raised by the library client when an Error
Reply is received.
Integer reply
-------------
This type of reply is just a CRLF terminated string representing an
integer, prefixed by a ":" byte. For example ":0\\r\\n", or
":1000\\r\\n" are integer replies.
With commands like INCR or LASTSAVE using the integer reply to
actually return a value there is no special meaning for the
returned integer. It is just an incremental number for INCR, a UNIX
time for LASTSAVE and so on.
Some commands like EXISTS will return 1 for true and 0 for false.
Other commands like SADD, SREM and SETNX will return 1 if the
operation was actually done, 0 otherwise.
The following commands will reply with an integer reply: SETNX,
DEL, EXISTS, INCR, INCRBY, DECR, DECRBY, DBSIZE, LASTSAVE,
RENAMENX, MOVE, LLEN, SADD, SREM, SISMEMBER, SCARD
Bulk replies
------------
Bulk replies are used by the server in order to return a single
binary safe string.
::
C: GET mykey
S: $6
S: foobar
The server sends as the first line a "$" byte followed by the
number of bytes of the actual reply, followed by CRLF, then the
actual data bytes are sent, followed by additional two bytes for
the final CRLF. The exact sequence sent by the server is:
::
"$6\r\nfoobar\r\n"
If the requested value does not exist the bulk reply will use the
special value -1 as data length, example:
::
C: GET nonexistingkey
S: $-1
The client library API should not return an empty string, but a nil
object, when the requested object does not exist. For example a
Ruby library should return 'nil' while a C library should return
NULL (or set a special flag in the reply object), and so forth.
Multi-Bulk replies
------------------
Commands like LRANGE need to return multiple values (every element
of the list is a value, and LRANGE needs to return more than a
single element). This is accomplished using multiple bulk writes,
prefixed by an initial line indicating how many bulk writes will
follow. The first byte of a multi bulk reply is always ``*``.
Example:
::
C: LRANGE mylist 0 3
S: *4
S: $3
S: foo
S: $3
S: bar
S: $5
S: Hello
S: $5
S: World
As you can see the multi bulk reply is exactly the same format used
in order to send commands to the Redis server unsing the unified
protocol.
The first line the server sent is
"**4\\r\\n" in order to specify that four bulk replies will follow. Then every bulk write is transmitted.If the specified key does not exist, instead of the number of elements in the list the special value -1 is sent as count. Example:**
::
C: LRANGE nokey 0 1
S: *-1
A client library API SHOULD return a nil object and not an empty
list when this happens. This makes possible to distinguish between
empty list and other error conditions (for instance a timeout
condition in the BLPOP command).
Nil elements in Multi-Bulk replies
----------------------------------
Single elements of a multi bulk reply may have -1 length, in order
to signal that this elements are missing and not empty strings.
This can happen with the SORT command when used with the GET
*pattern* option when the specified key is missing. Example of a
multi bulk reply containing an empty element:
::
S: *3
S: $3
S: foo
S: $-1
S: $3
S: bar
The second element is nul. The client library should return
something like this:
::
["foo",nil,"bar"]
Multiple commands and pipelining
--------------------------------
A client can use the same connection in order to issue multiple
commands. Pipelining is supported so multiple commands can be sent
with a single write operation by the client, it is not needed to
read the server reply in order to issue the next command. All the
replies can be read at the end.
Usually Redis server and client will have a very fast link so this
is not very important to support this feature in a client
implementation, still if an application needs to issue a very large
number of commands in short time to use pipelining can be much
faster.
The old protocol for sending commands
=====================================
Before of the Unified Request Protocol Redis used a different
protocol to send commands, that is still supported since it is
simpler to type by hand via telnet. In this protocol there are two
kind of commands:
\* Inline commands: simple commands where argumnets are just space
separated strings. No binary safeness is possible.\* Bulk commands:
bulk commands are exactly like inline commands, but the last
argument is handled in a special way in order to allow for a
binary-safe last argument.
Inline Commands
---------------
The simplest way to send Redis a command is via Inline Commands.
The following is an example of a server/client chat using an inline
command (the server chat starts with S:, the client chat with C:)
::
C: PING
S: +PONG
The following is another example of an INLINE command returning an
integer:
::
C: EXISTS somekey
S: :0
Since 'somekey' does not exist the server returned ':0'.
Note that the EXISTS command takes one argument. Arguments are
separated by spaces.
Bulk commands
-------------
Some commands when sent as inline commands require a special form
in order to support a binary safe last argument. This commands will
use the last argument for a "byte count", then the bulk data is
sent (that can be binary safe since the server knows how many bytes
to read).
See for instance the following example:
::
C: SET mykey 6
C: foobar
S: +OK
The last argument of the commnad is '6'. This specify the number of
DATA bytes that will follow, that is, the string "foobar". Note
that even this bytes are terminated by two additional bytes of
CRLF.
All the bulk commands are in this exact form: instead of the last
argument the number of bytes that will follow is specified,
followed by the bytes composing the argument itself, and CRLF. In
order to be more clear for the programmer this is the string sent
by the client in the above sample:
"SET mykey 6\\r\\nfoobar\\r\\n"
Redis has an internal list of what command is inline and what
command is bulk, so you have to send this commands accordingly. It
is strongly suggested to use the new Unified Request Protocol
instead.
.. |Redis Documentation| image:: redis.png
+240
View File
@@ -0,0 +1,240 @@
`|Redis Documentation| <index.html>`_
**PublishSubscribe: Contents**
  `UNSUBSCRIBE channel\_1 channel\_2 ... channel\_N <#UNSUBSCRIBE%20channel_1%20channel_2%20...%20channel_N>`_
  `UNSUBSCRIBE (unsubscribe from all channels) <#UNSUBSCRIBE%20(unsubscribe%20from%20all%20channels)>`_
  `PSUBSCRIBE pattern\_1 pattern\_2 ... pattern\_N <#PSUBSCRIBE%20pattern_1%20pattern_2%20...%20pattern_N>`_
  `PUNSUBSCRIBE pattern\_1 pattern\_2 ... pattern\_N <#PUNSUBSCRIBE%20pattern_1%20pattern_2%20...%20pattern_N>`_
  `PUNSUBSCRIBE (unsubscribe from all patterns) <#PUNSUBSCRIBE%20(unsubscribe%20from%20all%20patterns)>`_
  `PUBLISH channel message <#PUBLISH%20channel%20message>`_
    `Format of pushed messages <#Format%20of%20pushed%20messages>`_
    `Unsubscribing from all the channels at once <#Unsubscribing%20from%20all%20the%20channels%20at%20once>`_
    `Wire protocol example <#Wire%20protocol%20example>`_
    `PSUBSCRIBE and PUNSUBSCRIBE: pattern matching subscriptions <#PSUBSCRIBE%20and%20PUNSUBSCRIBE:%20pattern%20matching%20subscriptions>`_
    `Messages matching both a pattern and a channel subscription <#Messages%20matching%20both%20a%20pattern%20and%20a%20channel%20subscription>`_
    `The meaning of the count of subscriptions with pattern matching <#The%20meaning%20of%20the%20count%20of%20subscriptions%20with%20pattern%20matching>`_
    `More details on the PUBLISH command <#More%20details%20on%20the%20PUBLISH%20command>`_
    `Programming Example <#Programming%20Example>`_
    `Client library implementations hints <#Client%20library%20implementations%20hints>`_
PublishSubscribe
================
=SUBSCRIBE channel\_1 channel\_2 ... channel\_N=
UNSUBSCRIBE channel\_1 channel\_2 ... channel\_N
================================================
UNSUBSCRIBE (unsubscribe from all channels)
===========================================
PSUBSCRIBE pattern\_1 pattern\_2 ... pattern\_N
===============================================
PUNSUBSCRIBE pattern\_1 pattern\_2 ... pattern\_N
=================================================
PUNSUBSCRIBE (unsubscribe from all patterns)
============================================
PUBLISH channel message
=======================
Time complexity: subscribe is O(1), unsubscribe is O(N) where N is
the number of clients already subscribed to a channel, publish is
O(N+M) where N is the number of clients subscribed to the receiving
channel, and M is the total number of subscribed patterns (by any
client). Psubscribe is O(N) where N is the number of patterns the
Psubscribing client is already subscribed to. Punsubscribe is
O(N+M) where N is the number of patterns the Punsubscribing client
is already subscribed and M is the number of total patterns
subscribed in the system (by any client).
**Note**: this commands are available starting form Redis 2.0.0
SUBSCRIBE, UNSUBSCRIBE and PUBLISH commands implement
the`Publish/Subscribe messaging paradigm <http://en.wikipedia.org/wiki/Publish/subscribe>`_
where (citing Wikipedia) senders (publishers) are not programmed to
send their messages to specific receivers (subscribers). Rather,
published messages are characterized into channels, without
knowledge of what (if any) subscribers there may be. Subscribers
express interest in one or more channels, and only receive messages
that are of interest, without knowledge of what (if any) publishers
there are. This decoupling of publishers and subscribers can allow
for greater scalability and a more dynamic network topology.
For instance in order to subscribe to the channels foo and bar the
clientwill issue the SUBSCRIBE command followed by the names of the
channels.
::
SUBSCRIBE foo bar
All the messages sent by other clients to this channels will be
pushed bythe Redis server to all the subscribed clients, in the
form of a threeelements bulk reply, where the first element is the
message type, thesecond the originating channel, and the third
argument the message payload.
A client subscribed to 1 or more channels should NOT issue other
commandsother than SUBSCRIBE and UNSUBSCRIBE, but can subscribe or
unsubscribeto other channels dynamically.
The reply of the SUBSCRIBE and UNSUBSCRIBE operations are sent in
the formof messages, so that the client can just read a coherent
stream of messageswhere the first element indicates the kind of
message.
Format of pushed messages
-------------------------
Messages are in the form of multi bulk replies with three
elements.The first element is the kind of message:
- "subscribe": means that we successfully subscribed to the
channel given as second element of the multi bulk reply. The third
argument represents the number of channels we are currently
subscribed to.
- "unsubscribe": means that we successfully unsubscribed from the
channel given as second element of the multi bulk reply. The third
argument represents the number of channels we are currently
subscribed to. If this latest argument is zero, we are no longer
subscribed to any channel, and the client can issue any kind of
Redis command as we are outside the Pub/sub state.
- "message": it is a message received as result of a PUBLISH
command issued by another client. The second element is the name of
the originating channel, and the third the actual message payload.
Unsubscribing from all the channels at once
-------------------------------------------
If the UNSUBSCRIBE command is issued without additional arguments,
it is equivalent to unsubscribing to all the channels we are
currently subscribed. A message for every unsubscribed channel will
be received.
Wire protocol example
---------------------
::
SUBSCRIBE first second
*3
$9
subscribe
$5
first
:1
*3
$9
subscribe
$6
second
:2
at this point from another client we issue a PUBLISH operation
against the channel named "second". This is what the first client
receives:
::
*3
$7
message
$6
second
$5
Hello
Now the client unsubscribes itself from all the channels using the
UNSUBSCRIBE command without additional arguments:
::
UNSUBSCRIBE
*3
$11
unsubscribe
$6
second
:1
*3
$11
unsubscribe
$5
first
:0
PSUBSCRIBE and PUNSUBSCRIBE: pattern matching subscriptions
-----------------------------------------------------------
Redis Pub/Sub implementation supports pattern matching. Clients may
subscribe to glob style patterns in order to receive all the
messages sent to channel names matching a given pattern.
For instance the command:
::
PSUBSCRIBE news.*
Will receive all the messages sent to the channel
news.art.figurative and news.music.jazz and so forth. All the glob
style patterns as valid, so multiple wild cards are supported.
Messages received as a result of pattern matching are sent in a
different format:
- The type of the message is "pmessage": it is a message received
as result of a PUBLISH command issued by another client, matching a
pattern matching subscription. The second element is the original
pattern matched, the third element is the name of the originating
channel, and the last element the actual message payload.
Similarly to SUBSCRIBE and UNSUBSCRIBE, PSUBSCRIBE and PUNSUBSCRIBE
commands are acknowledged by the system sending a message of type
"psubscribe" and "punsubscribe" using the same format as the
"subscribe" and "unsubscribe" message format.
Messages matching both a pattern and a channel subscription
-----------------------------------------------------------
A client may receive a single message multiple time if it's
subscribed to multiple patterns matching a published message, or it
is subscribed to both patterns and channels matching the message.
Like in the following example:
::
SUBSCRIBE foo
PSUBSCRIBE f*
In the above example, if a message is sent to the **foo** channel,
the client will receive two messages, one of type "message" and one
of type "pmessage".
The meaning of the count of subscriptions with pattern matching
---------------------------------------------------------------
In **subscribe**, **unsubscribe**, **psubscribe** and
**punsubscribe** message types, the last argument is the count of
subscriptions still active. This number is actually the total
number of channels and patterns the client is still subscribed to.
So the client will exit the Pub/Sub state only when this count will
drop to zero as a result of unsubscription from all the channels
and patterns.
More details on the PUBLISH command
-----------------------------------
The Publish command is a bulk command where the first argument is
the target class, and the second argument the data to send. It
returns an Integer Reply representing the number of clients that
received the message (that is, the number of clients that were
listening for this class).
Programming Example
-------------------
Pieter Noordhuis provided a great example using Event-machine and
Redis to create
`a multi user high performance web chat <http://chat.redis-db.com>`_,
with source code included of course!
Client library implementations hints
------------------------------------
Because all the messages received contain the original subscription
causing the message delivery (the channel in the case of "message"
type, and the original pattern in the case of "pmessage" type)
clinet libraries may bind the original subscription to callbacks
(that can be anonymous functions, blocks, function pointers, and so
forth), using an hash table.
When a message is received an O(1) lookup can be done in order to
deliver the message to the registered callback.
.. |Redis Documentation| image:: redis.png
+108
View File
@@ -0,0 +1,108 @@
`|Redis Documentation| <index.html>`_
**QuickStart: Contents**
  `Quick Start <#Quick%20Start>`_
    `Obtain the latest version <#Obtain%20the%20latest%20version>`_
    `Compile <#Compile>`_
    `Run the server <#Run%20the%20server>`_
    `Play with the built in client <#Play%20with%20the%20built%20in%20client>`_
    `Further reading <#Further%20reading>`_
QuickStart
==========
#sidebar `RedisGuides <RedisGuides.html>`_
Quick Start
===========
This quickstart is a five minutes howto on how to get started with
Redis. For more information on Redis check
`Redis Documentation Index <http://code.google.com/p/redis/wiki/index>`_.
Obtain the latest version
-------------------------
The latest stable source distribution of Redis can be obtained
`at this location as a tarball <http://code.google.com/p/redis/downloads/list>`_.
::
$ wget http://redis.googlecode.com/files/redis-1.02.tar.gz
The unstable source code, with more features but not ready for
production, can be downloaded using git:
::
$ git clone git://github.com/antirez/redis.git
Compile
-------
Redis can be compiled in most
`POSIX systems <SupportedPlatforms.html>`_. To compile Redis just
untar the tar.gz, enter the directly and type 'make'.
::
$ tar xvzf redis-1.02.tar.gz
$ cd redis-1.02
$ make
In order to test if the Redis server is working well in your
computer make sure to run ``make test`` and check that all the
tests are passed.
Run the server
--------------
Redis can run just fine without a configuration file (when executed
without a config file a standard configuration is used). To run
Redis just type the following command:
::
$ ./redis-server
With the `default configuration <Configuration.html>`_ Redis will
log to the standard output so you can check what happens. Later,
you can `change the default settings <Configuration.html>`_.
Play with the built in client
-----------------------------
Redis ships with a command line client that is automatically
compiled when you ran ``make`` and it is called ``redis-cli``For
instance to set a key and read back the value use the following:
::
$ ./redis-cli set mykey somevalue
OK
$ ./redis-cli get mykey
somevalue
What about adding elements to a `list <Lists.html>`_:
::
$ ./redis-cli lpush mylist firstvalue
OK
$ ./redis-cli lpush mylist secondvalue
OK
$ ./redis-cli lpush mylist thirdvalue
OK
$ ./redis-cli lrange mylist 0 -1
1. thirdvalue
2. secondvalue
3. firstvalue
$ ./redis-cli rpop mylist
firstvalue
$ ./redis-cli lrange mylist 0 -1
1. thirdvalue
2. secondvalue
Further reading
---------------
- What to play more with Redis? Read
`Fifteen minutes introduction to Redis data types <IntroductionToRedisDataTypes.html>`_.
- Check all the `Features <Features.html>`_
- Read the full list of available commands in the
`Command Reference <CommandReference.html>`_.
- Start using Redis from your
`favorite language <SupportedLanguages.html>`_.
- Take a look at some
`Programming Examples <ProgrammingExamples.html>`_.
.. |Redis Documentation| image:: redis.png
+20
View File
@@ -0,0 +1,20 @@
`|Redis Documentation| <index.html>`_
**QuitCommand: Contents**
  `Quit <#Quit>`_
    `Return value <#Return%20value>`_
QuitCommand
===========
#sidebar
`ConnectionHandlingSidebar <ConnectionHandlingSidebar.html>`_
Quit
====
Ask the server to silently close the connection.
Return value
------------
None. The connection is closed as soon as the QUIT command is
received.
.. |Redis Documentation| image:: redis.png
+271
View File
@@ -0,0 +1,271 @@
`|Redis Documentation| <index.html>`_
**README: Contents**
  `All data in memory, but saved on disk <#All%20data%20in%20memory,%20but%20saved%20on%20disk>`_
  `Master-Slave replication made trivial <#Master-Slave%20replication%20made%20trivial>`_
  `It's persistent but supports expires <#It's%20persistent%20but%20supports%20expires>`_
  `Beyond key-value databases <#Beyond%20key-value%20databases>`_
  `Multiple databases support <#Multiple%20databases%20support>`_
  `Know more about Redis! <#Know%20more%20about%20Redis!>`_
  `Redis Tutorial <#Redis%20Tutorial>`_
  `License <#License>`_
  `Credits <#Credits>`_
README
======
= Introduction =
Redis is an extremely fast and powerful key-value store database
and server implemented in ANSI C. Redis offers many different ways
to do one straightforward thing: store a value ("antirez") to a key
("redis"). While the format of keys must always be simple strings,
the power is with the values, which support the following data
types:
- `Strings <Strings.html>`_
- `Lists <Lists.html>`_
- `Sets <Sets.html>`_
- `Sorted Sets (zsets) <SortedSets.html>`_
- `Hashes <Hashes.html>`_
Each value type has an associated list of commands which can
operate on them, and the
`The Redis Command Reference <CommandReference.html>`_ contains an
up to date list of these commands, organized primarily by data
type. The Redis source also includes a
`Redis command line interface <RedisCLI.html>`_ which allows you to
interact directly with the server, and is the means by which this
introduction will provide examples. Once you walk through the
`Redis Quick Start Guide <QuickStart.html>`_ to get your instance
of Redis running, you can follow along.
One of the most powerful aspects of Redis is the wide range of
commands which are optimized to work with specific data value types
and executed as atomic server-side operations. The
`List <Lists.html>`_ type is a great example - Redis implements
O(1) operations such as `LPUSH <RpushCommand.html>`_ or
`RPUSH <RpushCommand.html>`_, which have accompanying
`LPOP <LpopCommand.html>`_ and `RPOP <LpopCommand.html>`_ methods:
::
redis> lpush programming_languages C
OK
redis> lpush programming_languages Ruby
OK
redis> rpush programming_languages Python
OK
redis> rpop programming_languages
Python
redis> lpop programming_languages
Ruby
More complex operations are available for each data type as well.
Continuing with lists, you can get a range of elements with
`LRANGE <LrangeCommand.html>`_ (O(start+n)) or trim the list with
`LTRIM <LtrimCommand.html>`_ (O(n)):
::
redis> lpush cities NYC
OK
redis> lpush cities SF
OK
redis> lpush cities Tokyo
OK
redis> lpush cities London
OK
redis> lpush cities Paris
OK
redis> lrange cities 0 2
1. Paris
2. London
3. Tokyo
redis> ltrim cities 0 1
OK
redis> lpop cities
Paris
redis> lpop cities
London
redis> lpop cities
(nil)
You can also add and remove elements from a set, and perform
intersections, unions, and differences.
Redis can also be looked at as a data structures server. A Redis
user is virtually provided with an interface to
`Abstract Data Types <http://en.wikipedia.org/wiki/Abstract_data_type>`_,
saving them from the responsibility of implementing concrete data
structures and algorithms -- indeed both algorithms and data
structures in Redis are properly chosen in order to obtain the best
performance.
All data in memory, but saved on disk
=====================================
Redis loads and mantains the whole dataset into memory, but the
dataset is persistent, since at the same time it is saved on disk,
so that when the server is restarted data can be loaded back in
memory.
There are two kinds of persistence supported: the first one is
called snapshotting. In this mode Redis periodically writes to disk
asynchronously. The dataset is loaded from the dump every time the
server is (re)started.
Redis can be configured to save the dataset when a certain number
of changes is reached and after a given number of seconds elapses.
For example, you can configure Redis to save after 1000 changes and
at most 60 seconds since the last save. You can specify any
combination for these numbers.
Because data is written asynchronously, when a system crash occurs,
the last few queries can get lost (that is acceptable in many
applications but not in all). In order to make this a non issue
Redis supports another, safer persistence mode, called
`Append Only File <AppendOnlyFileHowto.html>`_, where every command
received altering the dataset (so not a read-only command, but a
write command) is written on an append only file ASAP. This
commands are *replayed* when the server is restarted in order to
rebuild the dataset in memory.
Redis Append Only File supports a very handy feature: the server is
able to safely rebuild the append only file in background in a
non-blocking fashion when it gets too long. You can find
`more details in the Append Only File HOWTO <AppendOnlyFileHowto.html>`_.
Master-Slave replication made trivial
=====================================
Whatever will be the persistence mode you'll use Redis supports
master-slave replications if you want to stay really safe or if you
need to scale to huge amounts of reads.
**Redis Replication is trivial to setup**. So trivial that all you
need to do in order to configure a Redis server to be a slave of
another one, with automatic synchronization if the link will go
down and so forth, is the following config line:
``slaveof 192.168.1.100 6379``.
`We provide a Replication Howto <ReplicationHowto.html>`_ if you
want to know more about this feature.
It's persistent but supports expires
====================================
Redis can be used as a **memcached on steroids** because is as fast
as memcached but with a number of features more. Like memcached,
Redis also supports setting timeouts to keys so that this key will
be automatically removed when a given amount of time passes.
Beyond key-value databases
==========================
All these features allow to use Redis as the sole DB for your
scalable application without the need of any relational database.
`We wrote a simple Twitter clone in PHP + Redis <TwitterAlikeExample.html>`_
to show a real world example, the link points to an article
explaining the design and internals in very simple words.
Multiple databases support
==========================
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.
Know more about Redis!
======================
To really get a feeling about what Redis is and how it works please
try reading
`A fifteen minutes introduction to Redis data types <IntroductionToRedisDataTypes.html>`_.
To know a bit more about how Redis works *internally* continue
reading.
Redis Tutorial
==============
(note, you can skip this section if you are only interested in
"formal" doc.)
Later in this document you can find detailed information about
Redis commands, the protocol specification, and so on. This kind of
documentation is useful but... if you are new to Redis it is also
BORING! The Redis protocol is designed so that is both pretty
efficient to be parsed by computers, but simple enough to be used
by humans just poking around with the 'telnet' command, so this
section will show to the reader how to play a bit with Redis to get
an initial feeling about it, and how it works.
To start just compile redis with 'make' and start it with
'./redis-server'. The server will start and log stuff on the
standard output, if you want it to log more edit redis.conf, set
the loglevel to debug, and restart it.
You can specify a configuration file as unique parameter:
./redis-server /etc/redis.conf
This is NOT required. The server will start even without a
configuration file using a default built-in configuration.
Now let's try to set a key to a given value:
::
$ telnet localhost 6379
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
SET foo 3
bar
+OK
The first line we sent to the server is "set foo 3". This means
"set the key foo with the following three bytes I'll send you". The
following line is the "bar" string, that is, the three bytes. So
the effect is to set the key "foo" to the value "bar". Very simple!
(note that you can send commands in lowercase and it will work
anyway, commands are not case sensitive)
Note that after the first and the second line we sent to the server
there is a newline at the end. The server expects commands
terminated by "\\r\\n" and sequence of bytes terminated by
"\\r\\n". This is a minimal overhead from the point of view of both
the server and client but allows us to play with Redis with the
telnet command easily.
The last line of the chat between server and client is "+OK". This
means our key was added without problems. Actually SET can never
fail but the "+OK" sent lets us know that the server received
everything and the command was actually executed.
Let's try to get the key content now:
::
GET foo
$3
bar
Ok that's very similar to 'set', just the other way around. We sent
"get foo", the server replied with a first line that is just the $
character follwed by the number of bytes the value stored at key
contained, followed by the actual bytes. Again "\\r\\n" are
appended both to the bytes count and the actual data. In Redis
slang this is called a bulk reply.
What about requesting a non existing key?
::
GET blabla
$-1
When the key does not exist instead of the length, just the "$-1"
string is sent. Since a -1 length of a bulk reply has no meaning it
is used in order to specifiy a 'nil' value and distinguish it from
a zero length value. Another way to check if a given key exists or
not is indeed the EXISTS command:
::
EXISTS nokey
:0
EXISTS foo
:1
As you can see the server replied ':0' the first time since 'nokey'
does not exist, and ':1' for 'foo', a key that actually exists.
Replies starting with the colon character are integer reply.
Ok... now you know the basics, read the
`REDIS COMMAND REFERENCE <CommandReference.html>`_ section to learn
all the commands supported by Redis and the
`PROTOCOL SPECIFICATION <ProtocolSpecification.html>`_ section for
more details about the protocol used if you plan to implement one
for a language missing a decent client implementation.
License
=======
Redis is released under the BSD license. See the COPYING file for
more information.
Credits
=======
Redis is written and maintained by Salvatore Sanfilippo, Aka
'antirez'.
.. |Redis Documentation| image:: redis.png
+20
View File
@@ -0,0 +1,20 @@
`|Redis Documentation| <index.html>`_
**RandomkeyCommand: Contents**
  `RANDOMKEY <#RANDOMKEY>`_
    `Return value <#Return%20value>`_
RandomkeyCommand
================
#sidebar `GenericCommandsSidebar <GenericCommandsSidebar.html>`_
RANDOMKEY
=========
*Time complexity: O(1)*
Return a randomly selected key from the currently selected DB.
Return value
------------
`Singe line reply <ReplyTypes.html>`_, specifically the randomly
selected key or an empty string is the database is empty.
.. |Redis Documentation| image:: redis.png
+42
View File
@@ -0,0 +1,42 @@
`|Redis Documentation| <index.html>`_
**Redis0100ChangeLog: Contents**
  `Redis 0.100 Changelog <#Redis%200.100%20Changelog>`_
Redis0100ChangeLog
==================
Redis 0.100 Changelog
=====================
::
- SUNION, SDIFF, SUNIONSTORE, SDIFFSTORE commands implemented. (Aman Gupta, antirez)
- Non blocking replication. Now while N slaves are synchronizing, the master will continue to ask to client queries. (antirez)
- PHP client ported to PHP5 (antirez)
- FLUSHALL/FLUSHDB no longer sync on disk. Just increment the dirty counter by the number of elements removed, that will probably trigger a background saving operation (antirez)
- INCRBY/DECRBY now support 64bit increments, with tests (antirez)
- New fields in INFO command, bgsave_in_progress and replication related (antirez)
- Ability to specify a different file name for the DB (... can't remember ...)
- GETSET command, atomic GET + SET (antirez)
- SMOVE command implemented, atomic move-element across sets operation (antirez)
- Ability to work with huge data sets, tested up to 350 million keys (antirez)
- Warns if /proc/sys/vm/overcommit_memory is set to 0 on Linux. Also make sure to don't resize the hash tables while the child process is saving in order to avoid copy-on-write of memory pages (antirez)
- Infinite number of arguments for MGET and all the other commands (antirez)
- CPP client (Brian Hammond)
- DEL is now a vararg, IMPORTANT: memory leak fixed in loading DB code (antirez)
- Benchmark utility now supports random keys (antirez)
- Timestamp in log lines (antirez)
- Fix SINTER/UNIONSTORE to allow for &=/|= style operations (i.e. SINTERSTORE set1 set1 set2) (Aman Gupta)
- Partial qsort implemented in SORT command, only when both BY and LIMIT is used (antirez)
- Allow timeout=0 config to disable client timeouts (Aman Gupta)
- Alternative (faster/simpler) ruby client API compatible with Redis-rb (antirez)
- S*STORE now return the cardinality of the resulting set (antirez)
- TTL command implemented (antirez)
- Critical bug about glueoutputbuffers=yes fixed. Under load and with pipelining and clients disconnecting on the middle of the chat with the server, Redis could block. (antirez)
- Different replication fixes (antirez)
- SLAVEOF command implemented for remote replication management (antirez)
- Issue with redis-client used in scripts solved, now to check if the latest argument must come from standard input we do not check that stdin is or not a tty but the command arity (antirez)
- Warns if using the default config (antirez)
- maxclients implemented, see redis.conf for details (antirez)
- max bytes of a received command enlarged from 1k to 32k (antirez)
.. |Redis Documentation| image:: redis.png
+32
View File
@@ -0,0 +1,32 @@
`|Redis Documentation| <index.html>`_
**Redis0900ChangeLog: Contents**
  `CHANGELOG for Redis 0.900 <#CHANGELOG%20for%20Redis%200.900>`_
Redis0900ChangeLog
==================
CHANGELOG for Redis 0.900
=========================
::
2009-06-16 client libraries updated (antirez)
2009-06-16 Better handling of background saving process killed or crashed (antirez)
2009-06-14 number of keys info in INFO command (Diego Rosario Brogna)
2009-06-14 SPOP documented (antirez)
2009-06-14 Clojure library (Ragnar Dahlén)
2009-06-10 It is now possible to specify - as config file name to read it from stdin (antirez)
2009-06-10 max bytes in an inline command raised to 1024*1024 bytes, in order to allow for very large MGETs and still protect from client crashes (antirez)
2009-06-08 SPOP implemented. Hash table resizing for Sets and Expires too. Changed the resize policy to play better with RANDOMKEY and SPOP. (antirez)
2009-06-07 some minor changes to the backtrace code (antirez)
2009-06-07 enable backtrace capabilities only for Linux and MacOSX (antirez)
2009-06-07 Dump a backtrace on sigsegv/sigbus, original coded (Diego Rosario Brogna)
2009-06-05 Avoid a busy loop while sending very large replies against very fast links, this allows to be more responsive with other clients even under a KEY * against the loopback interface (antirez)
2009-06-05 Kill the background saving process before performing SHUTDOWN to avoid races (antirez)
2009-06-05 LREM now returns :0 for non existing keys (antirez)
2009-06-05 added config.h for #ifdef business isolation, added fstat64 for Mac OS X (antirez)
2009-06-04 macosx specific zmalloc.c, uses malloc_size function in order to avoid to waste memory and time to put an additional header (antirez)
2009-06-04 DEBUG OBJECT implemented (antirez)
2009-06-03 shareobjectspoolsize implemented in reds.conf, in order to control the pool size when object sharing is on (antirez)
2009-05-27 maxmemory implemented (antirez)
.. |Redis Documentation| image:: redis.png
+51
View File
@@ -0,0 +1,51 @@
`|Redis Documentation| <index.html>`_
**RedisBigData: Contents**
    `BGSAVE and BGREWRITEAOF blocking fork() call <#BGSAVE%20and%20BGREWRITEAOF%20blocking%20fork()%20call>`_
    `Using multiple cores <#Using%20multiple%20cores>`_
    `Splitting data into multiple instances <#Splitting%20data%20into%20multiple%20instances>`_
    `BGSAVE / AOFSAVE memory usage, and copy on write <#BGSAVE%20/%20AOFSAVE%20memory%20usage,%20and%20copy%20on%20write>`_
    `BGSAVE / AOFSAVE time for big datasets <#BGSAVE%20/%20AOFSAVE%20time%20for%20big%20datasets>`_
    `Non blocking hash table <#Non%20blocking%20hash%20table>`_
RedisBigData
============
=Redis Big Data: facts and guidelines=
BGSAVE and BGREWRITEAOF blocking fork() call
--------------------------------------------
::
fork.c && ./a.out
allocated: 1 MB, fork() took 0.000
allocated: 10 MB, fork() took 0.001
allocated: 100 MB, fork() took 0.007
allocated: 1000 MB, fork() took 0.059
allocated: 10000 MB, fork() took 0.460
allocated: 20000 MB, fork() took 0.895
allocated: 30000 MB, fork() took 1.327
allocated: 40000 MB, fork() took 1.759
allocated: 50000 MB, fork() took 2.190
allocated: 60000 MB, fork() took 2.621
allocated: 70000 MB, fork() took 3.051
allocated: 80000 MB, fork() took 3.483
allocated: 90000 MB, fork() took 3.911
allocated: 100000 MB, fork() took 4.340
allocated: 110000 MB, fork() took 4.770
allocated: 120000 MB, fork() took 5.202
Using multiple cores
--------------------
Splitting data into multiple instances
--------------------------------------
BGSAVE / AOFSAVE memory usage, and copy on write
------------------------------------------------
BGSAVE / AOFSAVE time for big datasets
--------------------------------------
Non blocking hash table
-----------------------
.. |Redis Documentation| image:: redis.png
+11
View File
@@ -0,0 +1,11 @@
`|Redis Documentation| <index.html>`_
**RedisCLI: Contents**
  `Redis CLI <#Redis%20CLI>`_
RedisCLI
========
Redis Command Line Interface
Redis CLI
=========
.. |Redis Documentation| image:: redis.png
+181
View File
@@ -0,0 +1,181 @@
`|Redis Documentation| <index.html>`_
**RedisEventLibrary: Contents**
  `Redis Event Library <#Redis%20Event%20Library>`_
    `Event Loop Initialization <#Event%20Loop%20Initialization>`_
      `aeCreateEventLoop <#aeCreateEventLoop>`_
      `aeCreateTimeEvent <#aeCreateTimeEvent>`_
      `aeCreateFileEvent <#aeCreateFileEvent>`_
    `Event Loop Processing <#Event%20Loop%20Processing>`_
      `aeProcessEvents <#aeProcessEvents>`_
      `processTimeEvents <#processTimeEvents>`_
RedisEventLibrary
=================
#sidebar `RedisInternals <RedisInternals.html>`_
Redis Event Library
===================
Redis implements its own event library. The event library is
implemented in **ae.c**.
The best way to understand how the Redis event library works is to
understand how Redis uses it.
Event Loop Initialization
-------------------------
``initServer`` function defined in **redis.c** initializes the
numerous fields of the ``redisServer`` structure variable. One such
field is the Redis event loop ``el``:
::
aeEventLoop *el
``initServer`` initializes ``server.el`` field by calling
``aeCreateEventLoop`` defined in **ae.c**. The definition of
``aeEventLoop`` is below:
::
typedef struct aeEventLoop
{
int maxfd;
long long timeEventNextId;
aeFileEvent events[AE_SETSIZE]; /* Registered events */
aeFiredEvent fired[AE_SETSIZE]; /* Fired events */
aeTimeEvent *timeEventHead;
int stop;
void *apidata; /* This is used for polling API specific data */
aeBeforeSleepProc *beforesleep;
} aeEventLoop;
aeCreateEventLoop
~~~~~~~~~~~~~~~~~
``aeCreateEventLoop`` first mallocs aeEventLoop structure then
calls
ae\_epoll.c:aeApiCreate``.``aeApiCreate``mallocs``aeApiState``that has two fields -``epfd``that holds the epoll file descriptor returned by a call from [http://man.cx/epoll_create%282%29 epoll_create] and``events``that is of type``struct
epoll\_event``define by the Linux epoll library. The use of the``events``field will be described later. Next is 'ae.c:aeCreateTimeEvent``.
But before that ``initServer`` call ``anet.c:anetTcpServer`` that
creates and returns a *listening descriptor*. The descriptor is
listens to **port 6379** by default. The returned
*listening descriptor* is stored in ``server.fd`` field.
aeCreateTimeEvent
~~~~~~~~~~~~~~~~~
``aeCreateTimeEvent`` accepts the following as parameters:
- eventLoop: This is ``server.el`` in **redis.c**
- milliseconds: The number of milliseconds from the curent time
after which the timer expires.
- proc: Function pointer. Stores the address of the function that
has to be called after the timer expires.
- clientData: Mostly NULL.
- finalizerProc: Pointer to the function that has to be called
before the timed event is removed from the list of timed events.
``initServer`` calls ``aeCreateTimeEvent`` to add a timed event to
``timeEventHead`` field of ``server.el``. ``timeEventHead`` is a
pointer to a list of such timed events. The call to
``aeCreateTimeEvent`` from ``redis.c:initServer`` function is given
below:
::
aeCreateTimeEvent(server.el /*eventLoop*/, 1 /*milliseconds*/, serverCron /*proc*/, NULL /*clientData*/, NULL /*finalizerProc*/);
``redis.c:serverCron`` performs many operations that helps keep
Redis running properly.
aeCreateFileEvent
~~~~~~~~~~~~~~~~~
The essence of ``aeCreateFileEvent`` function is to execute
`epoll\_ctl <http://man.cx/epoll_ctl>`_ system call which adds a
watch for ``EPOLLIN`` event on the *listening descriptor* create by
``anetTcpServer`` and associate it with the epoll descriptor
created by a call to ``aeCreateEventLoop``.
Following is an explanation of what precisely ``aeCreateFileEvent``
does when called from ``redis.c:initServer``.
``initServer`` passes the following arguments to
``aeCreateFileEvent``:
- server.el: The event loop created by ``aeCreateEventLoop``. The
epoll descriptor is got from server.el.
- server.fd: The *listening descriptor* that also serves as an
index to access the relevant file event structure from the
``eventLoop->events`` table and store extra information like the
callback function.
- AE\_READABLE: Signifies that server.fd has to be watched for
EPOLLIN event.
- acceptHandler: The function that has to be executed when the
event being watched for is ready. This function pointer is stored
in ``eventLoop->events[server.fd]->rfileProc``.
This completes the initialization of Redis event loop.
Event Loop Processing
---------------------
``ae.c:aeMain`` called from ``redis.c:main`` does the job of
processing the event loop that is initialized in the previous
phase.
``ae.c:aeMain`` calls ``ae.c:aeProcessEvents`` in a while loop that
processes pending time and file events.
aeProcessEvents
~~~~~~~~~~~~~~~
``ae.c:aeProcessEvents`` looks for the time event that will be
pending in the smallest amount of time by calling
``ae.c:aeSearchNearestTimer`` on the event loop. In our case there
is only one timer event in the event loop that was created by
``ae.c:aeCreateTimeEvent``.
Remember, that timer event created by ``aeCreateTimeEvent`` has by
now probably elapsed because it had a expiry time of one
millisecond. Since, the timer has already expired the seconds and
microseconds fields of the ``tvp`` timeval structure variable is
initialized to zero.
The ``tvp`` structure variable along with the event loop variable
is passed to ``ae_epoll.c:aeApiPoll``.
``aeApiPoll`` functions does a
`epoll\_wait <http://man.cx/epoll_wait>`_ on the epoll descriptor
and populates the ``eventLoop->fired`` table with the details:
- fd: The descriptor that is now ready to do a read/write
operation depending on the mask value. The
- mask: The read/write event that can now be performed on the
corresponding descriptor.
``aeApiPoll`` returns the number of such file events ready for
operation. Now to put things in context, if any client has
requested for a connection then aeApiPoll would have noticed it and
populated the ``eventLoop->fired`` table with an entry of the
descriptor being the *listening descriptor* and mask being
``AE_READABLE``.
Now, ``aeProcessEvents`` calls the ``redis.c:acceptHandler``
registered as the callback. ``acceptHandler`` executes
[`http://man.cx/accept(2 <http://man.cx/accept(2>`_) accept] on the
*listening descriptor* returning a *connected descriptor* with the
client. ``redis.c:createClient`` adds a file event on the
*connected descriptor* through a call to ``ae.c:aeCreateFileEvent``
like below:
::
if (aeCreateFileEvent(server.el, c->fd, AE_READABLE,
readQueryFromClient, c) == AE_ERR) {
freeClient(c);
return NULL;
}
``c`` is the ``redisClient`` structure variable and ``c->fd`` is
the connected descriptor.
Next the ``ae.c:aeProcessEvent`` calls ``ae.c:processTimeEvents``
processTimeEvents
~~~~~~~~~~~~~~~~~
``ae.processTimeEvents`` iterates over list of time events starting
at ``eventLoop->timeEventHead``.
For every timed event that has elapsed ``processTimeEvents`` calls
the registered callback. In this case it calls the only timed event
callback registered, that is, ``redis.c:serverCron``. The callback
returns the time in milliseconds after which the callback must be
called again. This change is recorded via a call to
``ae.c:aeAddMilliSeconds`` and will be handled on the next
iteration of ``ae.c:aeMain`` while loop.
That's all.
.. |Redis Documentation| image:: redis.png
+14
View File
@@ -0,0 +1,14 @@
`|Redis Documentation| <index.html>`_
**RedisGuides: Contents**
RedisGuides
===========
= Redis Guides and Howtos=
- `Redis Quick Start <QuickStart.html>`_
- `Virutal Memory User Guide <VirtualMemoryUserGuide.html>`_
- `A Fifteen Minutes Introduction to the Redis Data Types <IntroductionToRedisDataTypes.html>`_
- `The Redis Replication HOWTO <ReplicationHowto.html>`_
- `The Append Only File HOWTO <AppendOnlyFileHowto.html>`_
.. |Redis Documentation| image:: redis.png
+38
View File
@@ -0,0 +1,38 @@
`|Redis Documentation| <index.html>`_
**RedisInternals: Contents**
  `Redis Internals <#Redis%20Internals>`_
    `Redis STRINGS <#Redis%20STRINGS>`_
    `Redis Virtual Memory <#Redis%20Virtual%20Memory>`_
    `Redis Event Library <#Redis%20Event%20Library>`_
RedisInternals
==============
Redis Internals
===============
This is a source code level documentation of Redis.
Redis STRINGS
-------------
String is the basic building block of Redis types.
Redis is a key-value store. All Redis keys are strings and its also
the simplest value type.
Lists, sets, sorted sets and hashes are other more complex value
types and even these are composed of strings.
`Hacking Strings <HackingStrings.html>`_ documents the Redis String
implementation details.
Redis Virtual Memory
--------------------
A technical specification full of details about the
`Redis Virtual Memory subsystem <VirtualMemorySpecification.html>`_
Redis Event Library
-------------------
Read `event library <EventLibray.html>`_ to understand what an
event library does and why its needed.
`Redis event library <RedisEventLibrary.html>`_ documents the
implementation details of the event library used by Redis
.. |Redis Documentation| image:: redis.png
+160
View File
@@ -0,0 +1,160 @@
`|Redis Documentation| <index.html>`_
**RedisPipelining: Contents**
  `Request/Response protocols and RTT <#Request/Response%20protocols%20and%20RTT>`_
  `Redis Pipelining <#Redis%20Pipelining>`_
  `Some benchmark <#Some%20benchmark>`_
  `Pipelining VS other multi-commands <#Pipelining%20VS%20other%20multi-commands>`_
RedisPipelining
===============
Request/Response protocols and RTT
==================================
Redis is a TCP server using the client-server model and what is
called a **Request/Response** protocol.
This means that usually a request is accomplished with the
following steps:
- The client sends a query to the server, and reads from the
socket, usually in a blocking way, for the server response.
- The server processes the command and sends the response back to
the server.
So for instance a four commands sequence is something like this:
- **Client:** INCR X
- **Server:** 1
- **Client:** INCR X
- **Server:** 2
- **Client:** INCR X
- **Server:** 3
- **Client:** INCR X
- **Server:** 4
Clients and Servers are connected via a networking link. Such a
link can be very fast (a loopback interface) or very slow (a
connection established over the internet with many hops between the
two hosts). Whatever the network latency is, there is a time for
the packets to travel from the client to the server, and back from
the server to the client to carry the reply.
This time is called RTT (Round Trip Time). It is very easy to see
how this can affect the performances when a client needs to perform
many requests in a row (for instance adding many elements to the
same list, or populating a database with many keys). For instance
if the RTT time is 250 milliseconds (in the case of a very slow
link over the internet), even if the server is able to process 100k
requests per second, we'll be able to process at max four requests
per second.
If the interface used is a loopback interface, the RTT is much
shorter (for instance my host reports 0,044 milliseconds pinging
127.0.0.1), but it is still a lot if you need to perform many
writes in a row.
Fortunately there is a way to improve this use cases.
Redis Pipelining
================
A Request/Response server can be implemented so that it is able to
process new requests even if the client didn't already read the old
responses. This way it is possible to send **multiple commands** to
the server without waiting for the replies at all, and finally read
the replies in a single step.
This is called pipelining, and is a technique widely in use since
many decades. For instance many POP3 protocol implementations
already supported this feature, dramatically speeding up the
process of downloading new emails from the server.
Redis supports pipelining since the very early days, so whatever
version you are running, you can use pipelining with Redis. This is
an example using the raw netcat utility:
::
$ (echo -en "PING\r\nPING\r\nPING\r\n"; sleep 1) | nc localhost 6379
+PONG
+PONG
+PONG
This time we are not paying the cost of RTT for every call, but
just one time for the three commands.
To be very explicit, with pipelining the order of operations of our
very first example will be the following:
- **Client:** INCR X
- **Client:** INCR X
- **Client:** INCR X
- **Client:** INCR X
- **Server:** 1
- **Server:** 2
- **Server:** 3
- **Server:** 4
**IMPORTANT NOTE**: while the client sends commands using
pipelining, the server will be forced to queue the replies, using
memory. So if you need to send many many commands with pipelining
it's better to send this commands up to a given reasonable number,
for instance 10k commands, read the replies, and send again other
10k commands and so forth. The speed will be nearly the same, but
the additional memory used will be at max the amount needed to
queue the replies for this 10k commands.
Some benchmark
==============
In the following benchmark we'll use the Redis Ruby client,
supporting pipelining, to test the speed improvement due to
pipelining:
::
require 'rubygems'
require 'redis'
def bench(descr)
start = Time.now
yield
puts "#{descr} #{Time.now-start} seconds"
end
def without_pipelining
r = Redis.new
10000.times {
r.ping
}
end
def with_pipelining
r = Redis.new
r.pipelined {
10000.times {
r.ping
}
}
end
bench("without pipelining") {
without_pipelining
}
bench("with pipelining") {
with_pipelining
}
Running the above simple script will provide this figures in my Mac
OS X system, running over the loopback interface, where pipelining
will provide the smallest improvement as the RTT is already pretty
low:
::
without pipelining 1.185238 seconds
with pipelining 0.250783 seconds
As you can see using pipelining we improved the transfer by a
factor of five.
Pipelining VS other multi-commands
==================================
Often we get requests about adding new commands performing multiple
operations in a single pass. For instance there is no command to
add multiple elements in a set. You need calling many times SADD.
With pipelining you can have performances near to an MSADD command,
but at the same time we'll avoid bloating the Redis command set
with too many commands. An additional advantage is that the version
written using just SADD will be ready for a distributed environment
(for instance Redis Cluster, that is in the process of being
developed) just dropping the pipelining code.
.. |Redis Documentation| image:: redis.png
+94
View File
@@ -0,0 +1,94 @@
`|Redis Documentation| <index.html>`_
**RedisStatus: Contents**
  `Redis Status Page <#Redis%20Status%20Page>`_
  `How stable are the alpha previews? <#How%20stable%20are%20the%20alpha%20previews?>`_
  `How to obtain a 2.2-alpha preview <#How%20to%20obtain%20a%202.2-alpha%20preview>`_
  `ETA for Redis 2.2? <#ETA%20for%20Redis%202.2?>`_
  `When will we be able to see a working version of Redis Cluster? <#When%20will%20we%20be%20able%20to%20see%20a%20working%20version%20of%20Redis%20Cluster?>`_
RedisStatus
===========
Redis Status Page
=================
Hello! Redis uses versions composed of three numbers separated by a
dot: **major**.**minor**.**patchlevel**.
When the **minor** is an odd number, it is used for an unstable
release, so stable releases are for instance 1.2, 2.0, and so
forth.
This is the status of the different Redis versions currently
available:
- 1.2 is the **legacy redis stable release**, now it is completely
obsoleted by Redis 2.0. Redis 2.0 is almost completely back
compatible with 1.2 so upgrading is usually not a problem. Still
1.2 is believed to be a very stable release that works well, so if
you are using it in production with code that probably will not
modified to use more advanced Redis features available in 2.0, it
makes sense to take 1.2 running. For everything new, it's better to
start with 2.0.
- 2.0 is the current **stable release**. It is better than 1.2 in
more or less everything: more features, more mature code, better
replication, better persistence, and so forth. It is currently what
most users should use, unless they really need features that are
only available into an **unstable** release.
- 2.1 is the current **unstable release**, and there are no tar.gz
for this release, you need to download it from git. **Warning:**
the master branch in git may work most of the time but is NOT what
you should use. What's better instead is to use the 2.2-alpha tags:
every time Redis 2.1.x is stable enough and the new features merged
passed all the tests for a couple of weeks, and we didn't received
severe bug reports from users, we tag master as 2.2-alpha *number*,
where *number* is simply a progressive number. Just pick this
number.
How stable are the alpha previews?
==================================
Well it is surely ok for development, but it is not recommended for
production. Still there are many users that trust Redis development
process so much to use alpha releases in production, but this is up
to you, we don't give any guarantee ;)
How to obtain a 2.2-alpha preview
=================================
Simply using git:
::
$ git clone git://github.com/antirez/redis.git
Initialized empty Git repository in /tmp/redis/.git/
...
Then you can list all the branches matching 2.1-alpha with:
::
cd redis
$ git tag | grep 2.2-alpha
2.2-alpha0
2.2-alpha1
2.2-alpha2
At this point you can just use **git checkout *tagname***,
substituting *tagname* with 2.2-alphaX where X is the greater
progressive number you see in the listing.
ETA for Redis 2.2?
==================
Redis 2.2 is planned to enter the release candidate stage before
the end of the 2010.
When will we be able to see a working version of Redis Cluster?
===============================================================
I'm already working at it, I mean not just designing, but writing
code. In three months we should have some kind of experimental
version, while in six months we should have the first release
candidate.
Probably the first **stable** release of Redis with working cluster
will be called 3.0, but I'll try to merge it into 2.2 as an
experimental support if we'll be sure there is no impact in the
stability of the system when clustering is not used.
.. |Redis Documentation| image:: redis.png
+154
View File
@@ -0,0 +1,154 @@
`|Redis Documentation| <index.html>`_
**Redis\_1\_2\_0\_Changelog: Contents**
  `What's new in Redis 1.2 <#What's%20new%20in%20Redis%201.2>`_
    `New persistence mode: Append Only File <#New%20persistence%20mode:%20Append%20Only%20File>`_
    `New data type: sorted sets <#New%20data%20type:%20sorted%20sets>`_
    `Specialized integer objects encoding <#Specialized%20integer%20objects%20encoding>`_
    `MSET and MSETNX <#MSET%20and%20MSETNX>`_
    `Better Performances <#Better%20Performances>`_
    `Solaris Support <#Solaris%20Support>`_
    `Support for the new generation protocol <#Support%20for%20the%20new%20generation%20protocol>`_
    `A few new commands about already supported data types <#A%20few%20new%20commands%20about%20already%20supported%20data%20types>`_
    `Bug fixing <#Bug%20fixing>`_
  `CHANGELOG for Redis 1.1.90 <#CHANGELOG%20for%20Redis%201.1.90>`_
Redis\_1\_2\_0\_Changelog
=========================
What's new in Redis 1.2
=======================
New persistence mode: Append Only File
--------------------------------------
The Append Only File is an alternative way to save your data in
Redis that is fully durable! Unlike the snapshotting (default)
persistence mode, where the database is saved asynchronously from
time to time, the Append Only File saves every change ASAP in a
text-only file that works like a journal. Redis will play back this
file again at startup reloading the whole dataset back in memory.
Redis Append Only File supports background Log compaction. For more
info read the `Append Only File HOWTO <AppendOnlyFileHowto.html>`_.
New data type: sorted sets
--------------------------
Sorted sets are collections of elements (like Sets) with an
associated score (in the form of a double precision floating point
number). Elements in a sorted set are taken in order, so for
instance to take the greatest element is an O(1) operation.
Insertion and deletion is O(log(N)). Sorted sets are implemented
using a dual ported data structure consisting of an hash table and
a skip list. For more information please read the
`Introduction To Redis Data Types <IntroductionToRedisDataTypes.html>`_.
Specialized integer objects encoding
------------------------------------
Redis 1.2 will use less memory than Redis 1.0 for values in
Strings, Lists or Sets elements that happen to be representable as
32 or 64 bit signed integers (it depends on your arch bits for the
long C type). This is totally transparent form the point of view of
the user, but will safe a lot of memory (30% less in datasets where
there are many integers).
MSET and MSETNX
---------------
That is, setting multiple keys in one command, atomically. For more
information see the `MSET command <MsetCommand.html>`_ wiki page.
Better Performances
-------------------
- 100x times faster SAVE and BGSAVE! There was a problem in the
LZF lib configuration that is now resolved. The effect is this
impressive speedup. Also the saving child will no longer use 100%
of CPU.
- Glue output buffer and writev(). Many commands producing large
outputs, like LRANGE, will now be even 10 times faster, thanks to
the new output buffer gluing algorithm and the (optional) use of
writev(2) syscall.
- Support for epool and kqueue / kevent. 10,000 clients
scalability.
- Much better EXPIRE support, now it's possible to work with very
large sets of keys expiring in very short time without to incur in
memory problems (the new algorithm expires keys in an adaptive way,
so will get more aggressive if there are a lot of expiring keys)
Solaris Support
---------------
Redis will now compile and work on Solaris without problems.
Warning: the Solaris user base is very little, so Redis running on
Solaris may not be as tested and stable as it is on Linux and Mac
OS X.
Support for the new generation protocol
---------------------------------------
- Redis is now able to accept commands in a new fully binary safe
way: with the new protocol keys are binary safe, not only values,
and there is no distinction between bulk commands and inline
commands. This new protocol is currently used only for MSET and
MSETNX but at some point it will hopefully replace the old one. See
the Multi Bulk Commands section in the
`Redis Protocol Specification <ProtocolSpecification.html>`_ for
more information.
A few new commands about already supported data types
-----------------------------------------------------
- `SRANDMEMBER <SrandmemberCommand.html>`_
- The `SortCommand <SortCommand.html>`_ is now supprots the
**STORE** and **GET #** forms, the first can be used to save sorted
lists, sets or sorted sets into keys for caching. Check the manual
page for more information about the **GET #** form.
- The new `RPOPLPUSH command <RpoplpushCommand.html>`_ can do many
interesting magics, and a few of this are documented in the wiki
page of the command.
Bug fixing
----------
Of course, many bugs are now fixed, and I bet, a few others
introduced: this is how software works after all, so make sure to
report issues in the Redis mailing list or in the Google Code
issues tracker.
Enjoy! antirez
CHANGELOG for Redis 1.1.90
==========================
- 2009-09-10 in-memory specialized object encoding. (antirez)
- 2009-09-17 maxmemory fixed in 64 systems for values > 4GB.
(antirez)
- 2009-10-07 multi-bulk protocol implemented. (antriez)
- 2009-10-16 MSET and MSETNX commands implemented (antirez)
- 2009-10-21 SRANDMEMBER added (antirez)
- 2009-10-23 Fixed compilation in mac os x snow leopard when
compiling a 32 bit binary. (antirez)
- 2009-10-23 New data type: Sorted sets and Z-commands (antirez)
- 2009-10-26 Solaris fixed (Alan Harder)
- 2009-10-29 Fixed Issue a number of open issues (antirez)
- 2009-10-30 New persistence mode: append only file (antirez)
- 2009-11-01 SORT STORE option (antirez)
- 2009-11-03 redis-cli now accepts a -r (repeat) switch. (antirez)
- 2009-11-04 masterauth option merged (Anthony Lauzon)
- 2009-11-04 redis-test is now a better Redis citizen, testing
everything against DB 9 and 10 and only if this DBs are empty.
(antirez)
- 2009-11-10 Implemented a much better lazy expiring algorithm for
EXPIRE (antirez)
- 2009-11-11 RPUSHLPOP (antirez from an idea of @ezmobius)
- 2009-11-12 Merge git://github.com/ianxm/redis (Can't remmber
what this implements, sorry)
- 2009-11-17 multi-bulk reply support for redis-bench, LRANGE
speed tests (antirez)
- 2009-11-17 support for writev implemented. (Stefano Barbato)
- 2009-11-19 debug mode (-D) in redis-bench (antirez)
- 2009-11-21 SORT GET # implemented (antirez)
- 2009-11-23 ae.c made modular, with support for epoll. (antirez)
- 2009-11-26 background append log rebuilding (antirez)
- 2009-11-28 Added support for kqueue. (Harish Mallipeddi)
- 2009-11-29 SORT support for sorted sets (antirez, thanks to
@tobi for the idea)
.. |Redis Documentation| image:: redis.png
+120
View File
@@ -0,0 +1,120 @@
`|Redis Documentation| <index.html>`_
**Redis\_2\_0\_0\_Changelog: Contents**
  `Redis 2.0: What's new? <#Redis%202.0:%20What's%20new?>`_
      `MULTI/EXEC <#MULTI/EXEC>`_
      `Blocking pop <#Blocking%20pop>`_
      `Publish/subscribe <#Publish/subscribe>`_
      `Hashes <#Hashes>`_
      `Virtual Memory <#Virtual%20Memory>`_
      `Contributors <#Contributors>`_
      `Special Thanks <#Special%20Thanks>`_
      `DOWNLOAD <#DOWNLOAD>`_
Redis\_2\_0\_0\_Changelog
=========================
Redis 2.0: What's new?
======================
The release of Redis 2.0 marks a major milestone in Redis
development. Apart from an endless list of new features, there are
some major ones that deserve to be highlighted.
It's worth to mention that while Redis 2.0.0 just reached its first
stable release, Redis 2.2.0 is near to reach feature freeze, so ...
be prepared for new exiting things in very short time!
MULTI/EXEC
~~~~~~~~~~
The MULTI/EXEC family of commands were added to fulfill the need to
execute multiple commands as a single atomic block. Because all
commands inside a MULTI/EXEC block are serialized and executed
sequentially, it is not possible that another client request is
served in the middle of executing this block. All commands are
executed one after the other when EXEC is called, which makes sure
either **all** or **no** commands are executed, independent of the
state of the client connection.
More on MULTI/EXEC:
- `http://code.google.com/p/redis/wiki/MultiExecCommand <http://code.google.com/p/redis/wiki/MultiExecCommand>`_
Note that WATCH, a CAS (check and set) variant of MULTI/EXEC will
be available on 2.2.0 and is not part of 2.0.0.
Blocking pop
~~~~~~~~~~~~
The commands BLPOP and BRPOP were added to support popping from a
list in a blocking fashion. This means the client connection will
be blocked for a certain amount of time until another client pushes
an item on a list. These commands are frequently used in
producer/consumer scenarios.
More on blocking pop:
- `http://code.google.com/p/redis/wiki/BlpopCommand <http://code.google.com/p/redis/wiki/BlpopCommand>`_
Publish/subscribe
~~~~~~~~~~~~~~~~~
The family of publish/subscribe commands let clients publish
messages onto channels and subscribe to receive all messages that
are published on channels. Also included are commands to receive
all messages for which the channel matches a given pattern.
More on publish/subscribe:
- `http://code.google.com/p/redis/wiki/PublishSubscribe <http://code.google.com/p/redis/wiki/PublishSubscribe>`_
- `http://antirez.com/post/redis-weekly-update-3-publish-submit.html <http://antirez.com/post/redis-weekly-update-3-publish-submit.html>`_
- `http://rediscookbook.org/pubsub\_for\_asynchronous\_communication.html <http://rediscookbook.org/pubsub_for_asynchronous_communication.html>`_
Hashes
~~~~~~
This new datatype allows to store multiple key/value pairs on a
single key. Together with the list of regular commands you would
expect for such a datatype (HSET, HGET, HDEL, HLEN, HKEYS, ...), it
is also possible to use the values *inside* a hash for any SORT
operation.
More on hashes:
- `http://code.google.com/p/redis/wiki/HsetCommand <http://code.google.com/p/redis/wiki/HsetCommand>`_
- `http://antirez.com/post/redis-weekly-update-1.html <http://antirez.com/post/redis-weekly-update-1.html>`_
Virtual Memory
~~~~~~~~~~~~~~
Redis Virtual Memory allows users to grow their dataset beyond the
limits of their RAM.
More on virtual memory:
- `http://code.google.com/p/redis/wiki/VirtualMemoryUserGuide <http://code.google.com/p/redis/wiki/VirtualMemoryUserGuide>`_
- `http://antirez.com/post/redis-virtual-memory-story.html <http://antirez.com/post/redis-virtual-memory-story.html>`_
Contributors
~~~~~~~~~~~~
- Salvatore Sanfilippo
- Pieter Noordhuis
- Antonio Ognio
- Alex McHale
- Michel Martens
- Damian Janowski
- Bruno Deferrari
- Ashley Martens
- Derek Collison
- Damian Janowski
- Jeremy Zawodny
- Konstantin Merenkov
- Michel Martens
- Sam Hendley
Special Thanks
~~~~~~~~~~~~~~
Thanks to VMware sponsoring the work of Salvatore and Pieter, and
the Redis community of users and client library developers. Redis
2.0.0 was possible only thanks to your support.
DOWNLOAD
~~~~~~~~
You can grab Redis 2.0.0 from
`Google Code <http://code.google.com/p/redis/downloads/list>`_.
It is also tagged on Git.
.. |Redis Documentation| image:: redis.png
+101
View File
@@ -0,0 +1,101 @@
`|Redis Documentation| <index.html>`_
**Redis\_2\_0\_Whats\_new: Contents**
  `Redis 2.0: What's new? <#Redis%202.0:%20What's%20new?>`_
      `MULTI/EXEC <#MULTI/EXEC>`_
      `Blocking pop <#Blocking%20pop>`_
      `Publish/subscribe <#Publish/subscribe>`_
      `Hashes <#Hashes>`_
      `Virtual Memory <#Virtual%20Memory>`_
    `Contributors <#Contributors>`_
Redis\_2\_0\_Whats\_new
=======================
Redis 2.0: What's new?
======================
The release of Redis 2.0 marks a major milestone in Redis
development. Apart from an endless list of new features, there are
some major ones that deserve to be highlighted.
MULTI/EXEC
~~~~~~~~~~
The MULTI/EXEC family of commands were added to fulfill the need to
execute multiple commands as a single atomic block. Because all
commands inside a MULTI/EXEC block are serialized and executed
sequentially, it is not possible that another client request is
served in the middle of executing this block. All commands are
executed one after the other when EXEC is called, which makes sure
either **all** or **no** commands are executed, independent of the
state of the client connection.
More on MULTI/EXEC:
- `http://code.google.com/p/redis/wiki/MultiExecCommand <http://code.google.com/p/redis/wiki/MultiExecCommand>`_
Blocking pop
~~~~~~~~~~~~
The commands BLPOP and BRPOP were added to support popping from a
list in a blocking fashion. This means the client connection will
be blocked for a certain amount of time until another client pushes
an item on a list. These commands are frequently used in
producer/consumer scenarios.
More on blocking pop:
- `http://code.google.com/p/redis/wiki/BlpopCommand <http://code.google.com/p/redis/wiki/BlpopCommand>`_
Publish/subscribe
~~~~~~~~~~~~~~~~~
The family of publish/subscribe commands let clients publish
messages onto channels and subscribe to receive all messages that
are published on channels. Also included are commands to receive
all messages for which the channel matches a given pattern.
More on publish/subscribe:
- `http://code.google.com/p/redis/wiki/PublishSubscribe <http://code.google.com/p/redis/wiki/PublishSubscribe>`_
- `http://antirez.com/post/redis-weekly-update-3-publish-submit.html <http://antirez.com/post/redis-weekly-update-3-publish-submit.html>`_
- `http://rediscookbook.org/pubsub\_for\_asynchronous\_communication.html <http://rediscookbook.org/pubsub_for_asynchronous_communication.html>`_
Hashes
~~~~~~
This new datatype allows to store multiple key/value pairs on a
single key. Together with the list of regular commands you would
expect for such a datatype (HSET, HGET, HDEL, HLEN, HKEYS, ...), it
is also possible to use the values *inside* a hash for any SORT
operation.
More on hashes:
- `http://code.google.com/p/redis/wiki/HsetCommand <http://code.google.com/p/redis/wiki/HsetCommand>`_
- `http://antirez.com/post/redis-weekly-update-1.html <http://antirez.com/post/redis-weekly-update-1.html>`_
Virtual Memory
~~~~~~~~~~~~~~
Redis Virtual Memory allows users to grow their dataset beyond the
limits of their RAM.
More on virtual memory:
- `http://code.google.com/p/redis/wiki/VirtualMemoryUserGuide <http://code.google.com/p/redis/wiki/VirtualMemoryUserGuide>`_
- `http://antirez.com/post/redis-virtual-memory-story.html <http://antirez.com/post/redis-virtual-memory-story.html>`_
Contributors
------------
- Salvatore Sanfilippo
- Pieter Noordhuis
- Antonio Ognio
- Alex McHale
- Michel Martens
- Damian Janowski
- Bruno Deferrari
- Ashley Martens
- Derek Collison
- Damian Janowski
- Jeremy Zawodny
- Konstantin Merenkov
- Michel Martens
- Sam Hendley
.. |Redis Documentation| image:: redis.png
+21
View File
@@ -0,0 +1,21 @@
`|Redis Documentation| <index.html>`_
**RenameCommand: Contents**
  `RENAME \_oldkey\_ \_newkey\_ <#RENAME%20_oldkey_%20_newkey_>`_
    `Return value <#Return%20value>`_
RenameCommand
=============
#sidebar `GenericCommandsSidebar <GenericCommandsSidebar.html>`_
RENAME \_oldkey\_ \_newkey\_
============================
*Time complexity: O(1)*
Atomically renames the key *oldkey* to *newkey*. If the source
anddestination name are the same an error is returned. If
*newkey*already exists it is overwritten.
Return value
------------
`Status code repy <ReplyTypes.html>`_
.. |Redis Documentation| image:: redis.png
+25
View File
@@ -0,0 +1,25 @@
`|Redis Documentation| <index.html>`_
**RenamenxCommand: Contents**
  `RENAMENX \_oldkey\_ \_newkey\_ <#RENAMENX%20_oldkey_%20_newkey_>`_
    `Return value <#Return%20value>`_
RenamenxCommand
===============
#sidebar `GenericCommandsSidebar <GenericCommandsSidebar.html>`_
RENAMENX \_oldkey\_ \_newkey\_
==============================
*Time complexity: O(1)*
Rename *oldkey* into *newkey* but fails if the destination key
*newkey* already exists.
Return value
------------
`Integer reply <ReplyTypes.html>`_, specifically:
::
1 if the key was renamed
0 if the target key already exist
.. |Redis Documentation| image:: redis.png
+75
View File
@@ -0,0 +1,75 @@
`|Redis Documentation| <index.html>`_
**ReplicationHowto: Contents**
  `Redis Replication Howto <#Redis%20Replication%20Howto>`_
    `General Information <#General%20Information>`_
    `How Redis replication works <#How%20Redis%20replication%20works>`_
    `Configuration <#Configuration>`_
ReplicationHowto
================
#sidebar `RedisGuides <RedisGuides.html>`_
Redis Replication Howto
=======================
General Information
-------------------
Redis replication is a very simple to use and configure
master-slave replication that allows slave Redis servers to be
exact copies of master servers. The following are some very
important facts about Redis replication:
- A master can have multiple slaves.
- Slaves are able to accept other slaves connections, so instead
to connect a number of slaves against the same master it is also
possible to connect some of the slaves to other slaves in a
graph-alike structure.
- Redis replication is non-blocking on the master side, this means
that the master will continue to serve queries while one or more
slaves are performing the first synchronization. Instead
replication is blocking on the slave side: while the slave is
performing the first synchronization it can't reply to queries.
- Replications can be used both for scalability, in order to have
multiple slaves for read-only queries (for example heavy
`SORT <SortCommand.html>`_ operations can be launched against
slaves), or simply for data redundancy.
- It is possible to use replication to avoid the saving process on
the master side: just configure your master redis.conf in order to
avoid saving at all (just comment al the "save" directives), then
connect a slave configured to save from time to time.
How Redis replication works
---------------------------
In order to start the replication, or after the connection closes
in order resynchronize with the master, the slave connects to the
master and issues the SYNC command.
The master starts a background saving, and at the same time starts
to collect all the new commands received that had the effect to
modify the dataset. When the background saving completed the master
starts the transfer of the database file to the slave, that saves
it on disk, and then load it in memory. At this point the master
starts to send all the accumulated commands, and all the new
commands received from clients that had the effect of a dataset
modification, to the slave, as a stream of commands, in the same
format of the Redis protocol itself.
You can try it yourself via telnet. Connect to the Redis port while
the server is doing some work and issue the SYNC command. You'll
see a bulk transfer and then every command received by the master
will be re-issued in the telnet session.
Slaves are able to automatically reconnect when the master ``<->``
slave link goes down for some reason. If the master receives
multiple concurrent slave synchronization requests it performs a
single background saving in order to serve all them.
Configuration
-------------
To configure replication is trivial: just add the following line to
the slave configuration file:
::
slaveof 192.168.1.1 6379
Of course you need to replace 192.168.1.1 6379 with your master ip
address (or hostname) and port.
.. |Redis Documentation| image:: redis.png
+72
View File
@@ -0,0 +1,72 @@
`|Redis Documentation| <index.html>`_
**ReplyTypes: Contents**
  `Redis Reply Types <#Redis%20Reply%20Types>`_
  `Status code reply <#Status%20code%20reply>`_
  `Error reply <#Error%20reply>`_
  `Integer reply <#Integer%20reply>`_
  `Bulk reply <#Bulk%20reply>`_
  `Multi bulk reply <#Multi%20bulk%20reply>`_
ReplyTypes
==========
Redis Reply Types
=================
Redis commands can reply to the client with four different kind of
replies, you can find the protocol level specification of this
replies in the
`Redis Protocol Specification <ProtocolSpecification.html>`_. This
page is instead an higher level description of the four types of
replies from the point of view of the final user.
Status code reply
=================
Status code replies are single line strings having the **+**
character as first byte. The string to return to the client is
simply verything that follows the first **+** character. For
example the `PING <PingCommand.html>`_ command returns **+PONG**,
that is the string "PONG".
Error reply
===========
This is like a status code reply but the first character is **-**
instead of **+**. The client library should raise an error for
error replies and stop the execution of the program if the
exception is not trapped, showing the error message (everything
following the first **-** character). An example of error is
"-Error no such key" or "-foobar". Note that error replies will not
collide with negative integer replies since integer replies are
prefixed with the **:** character.
Integer reply
=============
At protocol level integer replies are single line replies in form
of a decimal singed number prefixed by a **:** character. For
example **:10** is an integer reply. Redis commands returning
*true* or *false* will use an integer reply with 0 or 1 as values
where 0 is false and 1 is true.
Integer replies are usually passed by client libraries as integer
values.
Bulk reply
==========
A bulk reply is a binary-safe reply that is used to return a binary
safe single string value (string is not limited to alphanumerical
strings, it may contain binary data of any kind). Client libraries
will usually return a string as return value of Redis commands
returning bulk replies. There is a special bulk reply that signal
that the element does not exist. When this happens the client
library should return 'nil', 'false', or some other special element
that can be distinguished by an empty string.
Multi bulk reply
================
While a bulk reply returns a single string value, multi bulk
replies are used to return multiple values: lists, sets, and so on.
Elements of a bulk reply can be missing. Client libraries should
return 'nil' or 'false' in order to make this elements
distinguishable from empty strings. Client libraries should return
multi bulk replies that are about ordered elements like list ranges
as lists, and bulk replies about sets as hashes or Sets if the
implementation language has a Set type.
.. |Redis Documentation| image:: redis.png
+37
View File
@@ -0,0 +1,37 @@
`|Redis Documentation| <index.html>`_
**RoadMap: Contents**
  `Road Map (ROUGH DRAFT) <#Road%20Map%20(ROUGH%20DRAFT)>`_
    `Features added in past versions <#Features%20added%20in%20past%20versions>`_
    `1.1 / 1.2 <#1.1%20/%201.2>`_
    `0.x / 1.0 <#0.x%20/%201.0>`_
RoadMap
=======
Road Map (ROUGH DRAFT)
======================
The up to date, raw Road Map for Redis is part of the source code,
you can find it here:
`http://github.com/antirez/redis/raw/master/TODO <http://github.com/antirez/redis/raw/master/TODO>`_
Features added in past versions
-------------------------------
1.1 / 1.2
---------
- `Ordered Set (ZSET) <DataTypes.html>`_
- `Multibulk Commands <MultiBulkCommands.html>`_
- In memory integer encoding of `integers <DataTypes.html>`_.
Memory saving of 20% or more with datasets using high number of
integer IDs.
- Enhanced `EXPIRE <ExpireCommand.html>`_ algorithm.
0.x / 1.0
---------
- TODO: Add 1.0 Features. This is important for clarity in
`SupportedLanguages <SupportedLanguages.html>`_
.. |Redis Documentation| image:: redis.png
+63
View File
@@ -0,0 +1,63 @@
`|Redis Documentation| <index.html>`_
**RpoplpushCommand: Contents**
  `RPOPLPUSH \_srckey\_ \_dstkey\_ (Redis > <#RPOPLPUSH%20_srckey_%20_dstkey_%20(Redis%20%3E>`_
    `Programming patterns: safe queues <#Programming%20patterns:%20safe%20queues>`_
    `Programming patterns: server-side O(N) list traversal <#Programming%20patterns:%20server-side%20O(N)%20list%20traversal>`_
    `Return value <#Return%20value>`_
RpoplpushCommand
================
#sidebar `ListCommandsSidebar <ListCommandsSidebar.html>`_
RPOPLPUSH \_srckey\_ \_dstkey\_ (Redis >
========================================
1.1) = *Time complexity: O(1)*
Atomically return and remove the last (tail) element of the
*srckey* list,and push the element as the first (head) element of
the *dstkey* list. Forexample if the source list contains the
elements "a","b","c" and thedestination list contains the elements
"foo","bar" after an RPOPLPUSH commandthe content of the two lists
will be "a","b" and "c","foo","bar".
If the *key* does not exist or the list is already empty the
specialvalue 'nil' is returned. If the *srckey* and *dstkey* are
the same theoperation is equivalent to removing the last element
from the list and pusingit as first element of the list, so it's a
"list rotation" command.
Programming patterns: safe queues
---------------------------------
Redis lists are often used as queues in order to exchange messages
betweendifferent programs. A program can add a message performing
an `LPUSH <RpushCommand.html>`_ operationagainst a Redis list (we
call this program a Producer), while another program(that we call
Consumer) can process the messages performing an
`RPOP <LpopCommand.html>`_ commandin order to start reading the
messages from the oldest.
Unfortunately if a Consumer crashes just after an
`RPOP <LpopCommand.html>`_ operation the messagegets lost.
RPOPLPUSH solves this problem since the returned message isadded to
another "backup" list. The Consumer can later remove the
messagefrom the backup list using the `LREM <LremCommand.html>`_
command when the message was correctlyprocessed.
Another process, called Helper, can monitor the "backup" list to
check fortimed out entries to repush against the main queue.
Programming patterns: server-side O(N) list traversal
-----------------------------------------------------
Using RPOPPUSH with the same source and destination key a process
canvisit all the elements of an N-elements List in O(N) without to
transferthe full list from the server to the client in a single
`LRANGE <LrangeCommand.html>`_ operation.Note that a process can
traverse the list even while other processesare actively RPUSHing
against the list, and still no element will be skipped.
Return value
------------
`Bulk reply <ReplyTypes.html>`_
.. |Redis Documentation| image:: redis.png
+27
View File
@@ -0,0 +1,27 @@
`|Redis Documentation| <index.html>`_
**RpushCommand: Contents**
      `RPUSH \_key\_ \_string\_ <#RPUSH%20_key_%20_string_>`_
      `LPUSH \_key\_ \_string\_ <#LPUSH%20_key_%20_string_>`_
    `Return value <#Return%20value>`_
RpushCommand
============
#sidebar `ListCommandsSidebar <ListCommandsSidebar.html>`_
RPUSH \_key\_ \_string\_
~~~~~~~~~~~~~~~~~~~~~~~~
LPUSH \_key\_ \_string\_
~~~~~~~~~~~~~~~~~~~~~~~~
*Time complexity: O(1)*
Add the *string* value to the head (LPUSH) or tail (RPUSH) of the
liststored at *key*. If the key does not exist an empty list is
created just beforethe append operation. If the key exists but is
not a List an erroris returned.
Return value
------------
`Integer reply <ReplyTypes.html>`_, specifically, the number of
elements inside the list after the push operation.
.. |Redis Documentation| image:: redis.png
+28
View File
@@ -0,0 +1,28 @@
`|Redis Documentation| <index.html>`_
**SaddCommand: Contents**
  `SADD \_key\_ \_member\_ <#SADD%20_key_%20_member_>`_
    `Return value <#Return%20value>`_
SaddCommand
===========
#sidebar `SetCommandsSidebar <SetCommandsSidebar.html>`_
SADD \_key\_ \_member\_
=======================
*Time complexity O(1)*
Add the specified *member* to the set value stored at *key*. If
*member*is already a member of the set no operation is performed.
If *key*does not exist a new set with the specified *member* as
sole member iscreated. If the key exists but does not hold a set
value an error isreturned.
Return value
------------
`Integer reply <ReplyTypes.html>`_, specifically:
::
1 if the new element was added
0 if the element was already a member of the set
.. |Redis Documentation| image:: redis.png
+27
View File
@@ -0,0 +1,27 @@
`|Redis Documentation| <index.html>`_
**SaveCommand: Contents**
      `SAVE <#SAVE>`_
    `Return value <#Return%20value>`_
SaveCommand
===========
#sidebar `ControlCommandsSidebar <ControlCommandsSidebar.html>`_
SAVE
~~~~
Save the whole dataset on disk (this means that all the databases
are saved, as well as keys with an EXPIRE set (the expire is
preserved). The server hangs while the saving is notcompleted, no
connection is served in the meanwhile. An OK codeis returned when
the DB was fully stored in disk.
The background variant of this command is
`BGSAVE <BgsaveCommand.html>`_ that is able to perform the saving
in the background while the server continues serving other
clients.
Return value
------------
`Status code reply <ReplyTypes.html>`_
.. |Redis Documentation| image:: redis.png
+24
View File
@@ -0,0 +1,24 @@
`|Redis Documentation| <index.html>`_
**ScardCommand: Contents**
  `SCARD \_key\_ <#SCARD%20_key_>`_
    `Return value <#Return%20value>`_
ScardCommand
============
#sidebar `SetCommandsSidebar <SetCommandsSidebar.html>`_
SCARD \_key\_
=============
*Time complexity O(1)*
Return the set cardinality (number of elements). If the *key* does
notexist 0 is returned, like for empty sets.
Return value
------------
`Integer reply <ReplyTypes.html>`_, specifically:
::
the cardinality (number of elements) of the set as an integer.
.. |Redis Documentation| image:: redis.png
+30
View File
@@ -0,0 +1,30 @@
`|Redis Documentation| <index.html>`_
**SdiffCommand: Contents**
  `SDIFF \_key1\_ \_key2\_ ... \_keyN\_ <#SDIFF%20_key1_%20_key2_%20...%20_keyN_>`_
    `Return value <#Return%20value>`_
SdiffCommand
============
#sidebar `SetCommandsSidebar <SetCommandsSidebar.html>`_
SDIFF \_key1\_ \_key2\_ ... \_keyN\_
====================================
*Time complexity O(N) with N being the total number of elements of all the sets*
Return the members of a set resulting from the difference between
the firstset provided and all the successive sets. Example:
::
key1 = x,a,b,c
key2 = c
key3 = a,d
SDIFF key1,key2,key3 => x,b
Non existing keys are considered like empty sets.
Return value
------------
`Multi bulk reply <ReplyTypes.html>`_, specifically the list of
common elements.
.. |Redis Documentation| image:: redis.png
+20
View File
@@ -0,0 +1,20 @@
`|Redis Documentation| <index.html>`_
**SdiffstoreCommand: Contents**
  `SDIFFSTORE \_dstkey\_ \_key1\_ \_key2\_ ... \_keyN\_ <#SDIFFSTORE%20_dstkey_%20_key1_%20_key2_%20...%20_keyN_>`_
    `Return value <#Return%20value>`_
SdiffstoreCommand
=================
#sidebar `SetCommandsSidebar <SetCommandsSidebar.html>`_
SDIFFSTORE \_dstkey\_ \_key1\_ \_key2\_ ... \_keyN\_
====================================================
*Time complexity O(N) where N is the total number of elements in all the provided sets*
This command works exactly like SDIFF but instead of being returned
the resulting set is stored in *dstkey*.
Return value
------------
`Status code reply <ReplyTypes.html>`_
.. |Redis Documentation| image:: redis.png
+20
View File
@@ -0,0 +1,20 @@
`|Redis Documentation| <index.html>`_
**SelectCommand: Contents**
  `SELECT \_index\_ <#SELECT%20_index_>`_
    `Return value <#Return%20value>`_
SelectCommand
=============
#sidebar `GenericCommandsSidebar <GenericCommandsSidebar.html>`_
SELECT \_index\_
================
Select the DB with having the specified zero-based numeric
index.For default every new client connection is automatically
selectedto DB 0.
Return value
------------
`Status code reply <ReplyTypes.html>`_
.. |Redis Documentation| image:: redis.png
+20
View File
@@ -0,0 +1,20 @@
`|Redis Documentation| <index.html>`_
**SetCommand: Contents**
  `SET \_key\_ \_value\_ <#SET%20_key_%20_value_>`_
    `Return value <#Return%20value>`_
SetCommand
==========
#sidebar `StringCommandsSidebar <StringCommandsSidebar.html>`_
SET \_key\_ \_value\_
=====================
*Time complexity: O(1)*
Set the string *value* as value of the *key*.The string can't be
longer than 1073741824 bytes (1 GB).
Return value
------------
`Status code reply <ReplyTypes.html>`_
.. |Redis Documentation| image:: redis.png
+24
View File
@@ -0,0 +1,24 @@
`|Redis Documentation| <index.html>`_
**SetCommandsSidebar: Contents**
SetCommandsSidebar
==================
== Set Commands ==
- `SADD <SaddCommand.html>`_
- `SREM <SremCommand.html>`_
- `SPOP <SpopCommand.html>`_
- `SMOVE <SmoveCommand.html>`_
- `SCARD <ScardCommand.html>`_
- `SISMEMBER <SismemberCommand.html>`_
- `SINTER <SinterCommand.html>`_
- `SINTERSTORE <SinterstoreCommand.html>`_
- `SUNION <SunionCommand.html>`_
- `SUNIONSTORE <SunionstoreCommand.html>`_
- `SDIFF <SdiffCommand.html>`_
- `SDIFFSTORE <SdiffstoreCommand.html>`_
- `SMEMBERS <SmembersCommand.html>`_
- `SRANDMEMBER <SrandmemberCommand.html>`_
- `SORT <SortCommand.html>`_
.. |Redis Documentation| image:: redis.png
+36
View File
@@ -0,0 +1,36 @@
`|Redis Documentation| <index.html>`_
**SetbitCommand: Contents**
  `SETBIT \_key\_ \_offset\_ \_value\_ (Redis > <#SETBIT%20_key_%20_offset_%20_value_%20(Redis%20%3E>`_
    `Return value <#Return%20value>`_
SetbitCommand
=============
SETBIT \_key\_ \_offset\_ \_value\_ (Redis >
============================================
2.1.8) = *Time complexity: O(1)*
Sets or clears the bit at *offset* in the string value stored at
*key*.
The bit is either set or cleared depending on *value*, which can be
either 0 or 1. When *key* does not exist, a new string value is
created. The string is grown to make sure it can hold a bit at
*offset*. The *offset* argument is required to be greater than or
equal to 0, and is limited to
2\ :sup:`32-1 (which limits bitmaps to 512MB). When the string at *key* is grown, added bits are set to 0.**Warning**: When setting the last possible bit (*offset* equal to 2`\ 32-1)
and the string value stored at *key* does not yet hold a string
value, or holds a small string value, Redis needs to allocate all
intermediate memory which can block the server for some time. On a
2010 Macbook Pro, setting bit number
2\ :sup:`32-1 (512MB allocation) takes ~300ms, setting bit number 2`\ 30-1
(128MB allocation) takes ~80ms, setting bit number
2\ :sup:`28-1 (32MB allocation) takes ~30ms and setting bit number 2`\ 26-1
(8MB allocation) takes ~8ms. Note that once this first allocation
is done, subsequent calls to SETBIT for the same *key* will not
have the allocation overhead.
Return value
------------
`Integer reply <ReplyTypes.html>`_, specifically: the original bit
value stored at *offset*.
.. |Redis Documentation| image:: redis.png

Some files were not shown because too many files have changed in this diff Show More