-
Redis cares to store them on disk, even if they are always served and modified into the server memory. This means that Redis is fast, but that it is also non-volatile. -
The implementation of data structures emphasizes memory efficiency, so data structures inside Redis will likely use less memory compared to the same data structure modelled using a high-level programming language. -
Redis offers a number of features that are natural to find in a database, like replication, tunable levels of durability, clustering, and high availability.
-
Introduction to Redis data types. https://redis.io/topics/data-types-intro -
Try Redis directly inside your browser. https://try.redis.io -
The full list of Redis commands. https://redis.io/commands -
There is much more inside the official Redis documentation. https://redis.io/documentation
% make
% make BUILD_TLS=yes
% make USE_SYSTEMD=yes
% make PROG_SUFFIX="-alt"
% make 32bit
% make test
% ./ utils/gen-test-certs.sh % ./ runtest --tls
% make distclean
-
Install the package libc6-dev-i386 (also try g++-multilib). -
Try using the following command line instead of make 32bit : make CFLAGS="-m32 -march=native" LDFLAGS="-m32"
% make MALLOC=libc
% make MALLOC=jemalloc
% make CFLAGS="-DUSE_PROCESSOR_CLOCK"
% make V=1
% cd src % ./ redis-server
% cd src % ./ redis-server /path/to/redis.conf
% ./ redis-server --port 9999 --replicaof 127.0.0.1 6379 % ./ redis-server /etc/redis/6379.conf --loglevel debug
% cd src % ./ redis-cli redis> ping PONG redis> set foo bar OK redis> get foo "bar" redis> incr mycounter (integer) 1 redis> incr mycounter (integer) 2 redis>
% make install
% cd utils % ./ install_server.sh
src : contains the Redis implementation, written in C. tests : contains the unit tests, implemented in Tcl. deps : contains libraries Redis uses. Everything needed to compile Redis is inside this directory; your system just needs to provide libc , a POSIX compatible interface and a C compiler. Notably deps contains a copy of jemalloc , which is the default allocator of Redis under Linux. Note that under deps there are also things which started with the Redis project, but for which the main repository is not redis/redis .
server.db is an array of Redis databases, where data is stored. server.commands is the command table. server.clients is a linked list of clients connected to the server. server.master is a special client, the master, if the instance is a replica.
struct client { int fd ; sds querybuf ; int argc ; robj * * argv ; redisDb * db ; int flags ; list * reply ; // ... many other fields ...
char buf [ PROTO_REPLY_CHUNK_BYTES ]; }
-
The fd field is the client socket file descriptor. argc and argv are populated with the command the client is executing, so that functions implementing a given Redis command can read the arguments. querybuf accumulates the requests from the client, which are parsed by the Redis server according to the Redis protocol and executed by calling the implementations of the commands the client is executing. reply and buf are dynamic and static buffers that accumulate the replies the server sends to the client. These buffers are incrementally written to the socket as soon as the file descriptor is writable.
struct redisObject { unsigned type : four ; unsigned encoding : four ; unsigned lru : LRU_BITS ; /* LRU time (relative to global lru_clock) or
* LFU data (least significant 8 bits frequency
* and most significant 16 bits access time). */
int refcount ; void * ptr ; };
initServerConfig() sets up the default values of the server structure. initServer() allocates the data structures needed to operate, setup the listening socket, and so forth. aeMain() starts the event loop which listens for new connections.
serverCron() is called periodically (according to server.hz frequency), and performs tasks that must be performed from time to time, like checking for timed out clients. beforeSleep() is called every time the event loop fired, Redis served a few requests, and is returning back into the event loop.
call() is used in order to call a given command in the context of a given client. activeExpireCycle() handles eviction of keys with a time to live set via the EXPIRE command. performEvictions() is called when a new write command should be performed but Redis is out of memory according to the maxmemory directive. -
The global variable redisCommandTable defines all the Redis commands, specifying the name of the command, the function implementing the command, the number of arguments required, and other properties of each command.
createClient() allocates and initializes a new client. -
The addReply*() family of functions are used by command implementations in order to append data to the client structure, that will be transmitted to the client as a reply for a given command executed. writeToClient() transmits the data pending in the output buffers to the client and is called by the writable event handler sendReplyToClient() . readQueryFromClient() is the readable event handler and accumulates data read from the client into the query buffer. processInputBuffer() is the entry point in order to parse the client query buffer according to the Redis protocol. Once commands are ready to be processed, it calls processCommand() which is defined inside server.c in order to actually execute the command. freeClient() deallocates, disconnects and removes a client.
lookupKeyRead() and lookupKeyWrite() are used in order to get a pointer to the value associated to a given key, or NULL if the key does not exist. dbAdd() and its higher level counterpart setKey() create a new key in a Redis database. dbDelete() removes a key and its associated value. emptyData() removes an entire single database or all the databases defined.
incrRefCount() and decrRefCount() are used in order to increment or decrement an object reference count. When it drops to 0 the object is finally freed. createObject() allocates a new object. There are also specialized functions to allocate string objects having a specific content, like createStringObjectFromLongLong() and similar functions.
script.c - integration of scripts with Redis (commands execution, set replication/resp, ...) script_lua.c - responsible to execute Lua code, uses script.c to interact with Redis from within the Lua code. function_lua.c - contains the Lua engine implementation, uses script_lua.c to execute the Lua code. functions.c - contains Redis Functions implementation ( FUNCTION command), uses functions_lua.c if the function it wants to invoke needs the Lua engine. eval.c - contains the eval implementation using script_lua.c to invoke the Lua code.
t_hash.c , t_list.c , t_set.c , t_string.c , t_zset.c and t_stream.c contains the implementation of the Redis data types. They implement both an API to access a given data type, and the client command implementations for these data types. ae.c implements the Redis event loop, it's a self contained library which is simple to read and understand. sds.c is the Redis string library, check https://github.com/antirez/sds for more information. anet.c is a library to use POSIX networking in a simpler way compared to the raw interface exposed by the kernel. dict.c is an implementation of a non-blocking hash table which rehashes incrementally. cluster.c implements the Redis Cluster. Probably a good read only after being very familiar with the rest of the Redis code base. If you want to read cluster.c make sure to read the Redis Cluster specification .
void foobarCommand ( client * c ) { printf ( "%s" , c -> argv [ one ] -> ptr ); /* Do something with the argument. */
addReply ( c , shared . ok ); /* Reply something to the client. */ }