Dynamic Redis

Dynamic Redis

Current Versions

Version numbers are: Redis Version-Dynamic Addons Version

Dynamic Redis is defined as: module loading added to an existing Redis release.

Dynamic Redis only adds module loading to Redis. There are no performance enhancements or other feature additions.

Releases

  • Dynamic Redis 2.8.9-0.5.2 (.tar.gz)
    • Based on Redis 2.8.9 and now includes HyperLogLog (PF*) commands and ZRANGEBYLEX commands
    • Adds compile-time feature detection for features modules may need to compile against
  • Dynamic Redis 2.8.8-0.5.1 (.tar.gz)
    • Adds ability to export specific internal Redis functions for use in modules
    • compatible with new geo commands provided in Redis Module ToolKit
    • updated release; compiles all recent modules
  • Dynamic Redis 2.8.8-0.5 (.tar.gz)
    • Redis 2.8.8 with dynamic command loading
    • original release

Branches

unstable

All Redis development starts in the unstable branch then merges into releases as necessary.

Dynamic Redis unstable is where development of the module loading facility takes place. Improvements get back-ported to current releases as necessary.

Dynamic Redis unstable is continually rebased against proper Redis unstable to keep the command loading code applied on top of all upstream Redis changes. Any future merge conflicts are fixed in Dynamic Redis and not in the underlying Redis code.

What is Dynamic Redis?

Dynamic Redis allows you to load custom commands into Redis without patches, recompiles, or even restarting your Redis process.

Also see introductory post: Advanced Redis: Command Loading.

You should consider Redis Lua Scripting before evaluating Dynamic Redis.

Use Command Modules

Dynamic Redis adds two configuration directives: module-add and module-strict.

module-add

module-add takes one parameter: the location of the module to load. You should include the module as a path and not just a filename. If you only specify a filename without directory location, the system will search your LD_LIBRARY_PATH and ldconfig search path, which probably isn't what you want.

Usage example (config file):

module-add ./pingTest.so

Usage example (command line):

redis-server --module-add ./pingTest.so

You can load new (or reload existing) modules at runtime:

CONFIG SET module-add ./pingTest.so

In the examples above, pingTest.so is located in the directory where you first launched redis-server.

Note: There is no way to remove a loaded module. Once you load a module, you are stuck with it until you restart the server or load a new version on top of it.

module-strict

module-strict controls if Dynamic Redis loads a module compiled against a different version of Redis than is currently running. You can disable strict version checking by changing the setting to no. Dynamic Redis will always print a warning if you load a module compiled against a different version of Redis.

Usage example (config file):

module-strict no

Usage example (command line):

redis-server --module-strict no

You can change version strictness at runtime:

CONFIG SET module-strict no
CONFIG SET module-strict yes

INFO modules

You can view all loaded modules, their versions, and the commands they provide:

INFO modules

You'll notice all built-in Redis commands show up as well. Dynamic Redis loads built-in commands the same way it loads external commands, so they get an accounting record in INFO modules too.

Sample output:

127.0.0.1:6379> INFO modules
# Modules
module_<builtin>:filename=<builtin>,compiled_against=2.9.11,
module_version=2.9.11,first_loaded=0,last_loaded=0,commands=get,set,setnx,setex,
psetex,append,strlen,del,exists,setbit,getbit,setrange,getrange,substr,incr,
decr,mget,rpush,lpush,rpushx,lpushx,linsert,rpop,lpop,brpop,brpoplpush,blpop,
llen,lindex,lset,lrange,ltrim,lrem,rpoplpush,sadd,srem,smove,sismember,scard,
spop,srandmember,sinter,sinterstore,sunion,sunionstore,sdiff,sdiffstore,
smembers,sscan,zadd,zincrby,zrem,zremrangebyscore,zremrangebyrank,zunionstore,
zinterstore,zrange,zrangebyscore,zrevrangebyscore,zcount,zrevrange,zcard,zscore,
zrank,zrevrank,zscan,hset,hsetnx,hget,hmset,hmget,hincrby,hincrbyfloat,hdel,
hlen,hkeys,hvals,hgetall,hexists,hscan,incrby,decrby,incrbyfloat,getset,mset,
msetnx,randomkey,select,move,rename,renamenx,expire,expireat,pexpire,pexpireat,
keys,scan,dbsize,auth,ping,echo,save,bgsave,bgrewriteaof,shutdown,lastsave,type,
multi,exec,discard,sync,psync,replconf,flushdb,flushall,sort,info,monitor,ttl,
pttl,persist,slaveof,debug,config,subscribe,unsubscribe,psubscribe,punsubscribe,
publish,pubsub,watch,unwatch,cluster,restore,restore-asking,migrate,asking,
readonly,readwrite,dump,object,client,eval,evalsha,slowlog,script,time,bitop,
bitcount,bitpos,wait
module_test_poong:filename=ping.so,compiled_against=2.9.11,module_version=3bob,
first_loaded=0,last_loaded=1396025761,commands=poong,pooooong,pooong,pinger

Create Command Modules

Checkout krmt for building a custom Redis Add-On Module. (krmt is pronounced "Kermit" and stands for Redis Module ToolKit si está mareado).

krmt includes a sample module you can modify as needed.

Minimum Requirements

  • #include "redis.h"
  • Define module details as struct redisModule redisModuleDetail
    • struct redisModule redisModuleDetail = {
      REDIS_MODULE_COMMAND,  /* tell Redis our module contains new commands */
      REDIS_VERSION,         /* Redis version defined by redis.h */
      "0.1-sparkles",        /* version number of module (used for INFO) */
      "sh.matt.zodiac",      /* unique identifier for module */
      NULL,                  /* optional load function: void *load() */
      NULL                   /* optional cleanup: void *cleanup(void *) */
      };
  • Define command array as struct redisCommand redisCommandTable[]

Optional Load/Cleanup Functions

Dynamic Redis runs your (optional) load function when your module loads (simple, no?).

The load function takes no parameters and returns void *.

The cleanup function only runs if you defined a load function. The cleanup function receives the output from your load function as its only parameter.

If you reload a module (by module-add the same module again), the currently loaded module will run cleanup, unload itself, then your new module will be evaluated.

Building Your Custom Module

Start with krmt and modify the code/Makefile/CFLAGS/LDFLAGS as necessary.

Note: Building a module requires a checkout of the Dynamic Redis branch you intend to run as your server. See krmt for more details.

Need More?

Need more information? Is a critical pieec of usage information missing above? Are there annoying tyops you demand must be fixed?

File an issue and someone will get back to you within four to eleventryhundred business days.

This work is vomited forth unto the world by Matt@mattsta☁mattsta.

Sponsored By

This work is made possible by Pivotal, who employs me to do awesome things with Redis.

Pivotal offers Redis support to help you get started with Redis, improve your existing Redis deployments, and train your employees on Redis best practices.

Ask your boss about signing up for Pivotal Redis support today! (Please?) Signing up for support helps pay for awesome work like regular Redis, Redis Cluster, this experiment in Dynamic Redis, and more things we haven't even thought of yet. Just email redis@gopivotal.com and tell us a little about your data structure server storage needs, wants, and desires. Help us help you.