Redis lua when to really use it

luaredis

I've started to research and play a bit with lua and have found it to be great when wanting to grab ranges of keys. Ex:

business:5:visits:2013-11-12
business:5:visits:2013-11-13
etc

With lua I only have to send one command to redis instead of the complete range of dates.

Now I'm thinking about converting more of our logic and move it onto Redis.

Take our message storing process which currently looks like this:

// create a new unique id
redisClient.incr(Config.messageId, function(err, reply) {
    var messageId = reply.toString();
    var timestmp = Date.now();

    // push message
    redisClient.zadd(Config.history + ':' + obj.uid + ':' + obj.channel.replace(/\s+/g, ''), timestmp, messageId);

    // store the message data by messageId
    redisClient.hmset(Config.messageHash + ':' + messageId, {
        'user_id': obj.uid,
        'text_body': "some text",
        'text_date': timestmp,
    });


    // set expires
    redisClient.expire(Config.history + ':' + obj.uid + ':' + obj.channel.replace(/\s+/g, ''), Config.messageExpire);
    redisClient.expire(Config.messageHash + ':' + messageId, Config.messageExpire);


    // add to mysql-sync queue
    redisClient.RPUSH(Config.messageMySQLSyncQueue, Config.messageHash + ':' + messageId);

});

The above could easily be converted into lua, but is it worth it for performance?

Would it be faster to write this in Lua instead and only have to issue 1 command to Redis? Would it cause problems with blocking other commands?

Best Solution

Lua scripts are meant to work like MULTI commands. Actually most commands that you would develop using MULTI commands from a Redis client can be implemented in Lua. That is, you can encapsulate some complex operations in a script and your data layer will perform the atomic write operation without worrying about your data modeling strategy on Redis.

Also, I find them useful when you want to perform quick but complex read operations. For example, you might want to get objects in order. Objects are stored in a hash key while the order is defined by a sorted set key. You get a range of the so-called sorted set and you get objects in hash using hmget.

The most important point is Lua scripts should implement things that can execute as fast as possible, since Redis will block other operations while a Lua script is running. That is, you need to perform quick interruptions or your overall Redis performance will decrease a lot.

Arguments to not use Lua

I would argue that you should use them when you really need them. Usually, clients are developed using high-level programming languages like C#, Java, JavaScript, Ruby... and they provide better development experience: good debuggers, IDE, code-completion...

Summary: you should use them if you can prove that there's an actual benefit (in performance) if you turn some part of your domain logic into Redis Lua scripts.