27

I want to be able to run a callback when any change is made in my redis collection. The callback would take the key and value as inputs. Is something like this possible?

Thanks?

fancy
  • 48,619
  • 62
  • 153
  • 231

5 Answers5

32

UPDATE (2020): Whomever is reading this - these are ancient answers, disregard them all. What you need is Redis Keyspace Notifications which have been around for ages. See https://redis.io/topics/notifications

acdcjunior
  • 132,397
  • 37
  • 331
  • 304
Not_a_Golfer
  • 47,012
  • 14
  • 126
  • 92
17

Two options:

  1. Use MONITOR command - it traces every command that gets to Redis and you can analyze and see when your collection is being touched.

  2. If you "own" the code that writes to the collection, signal your other code (your callback). You can use Redis Pub/Sub channel for this.

EDIT Redis is actually going to implement this feature in version 2.8. See Antirez's blog post on this: Redis keyspace changes notification system.

Ofer Zelig
  • 17,068
  • 9
  • 59
  • 93
  • 2
    And `MONITOR` reduces the [performance by more than half](https://redis.io/commands/monitor), so you better not run that in Production very often – asgs Jul 03 '19 at 19:56
12

You can also connect to the Redis server like a follower using the sync command. See How Redis Replication Works? for a quick introduction.

The output of sync command has two phases. In the first phase, the server returns the database dump.rdb file. Once the file is sent, it starts sending commands in the Redis protocol, which is also the AOF format.

Here is the high level picture of what you can do :

  1. Connect to the Redis server and issue the SYNC command
  2. Save and parse the dump.rdb file. Build the initial data set. A node.js based rdb parser is available
  3. Parse the commands that follow. Since they are in Redis protocol, you can start with an existing Redis library.
  4. For every command you receive, invoke a callback

It seems a lot of work, but you should be able to hack this pretty easily. And it would make a good open source library too!

EDIT : Sync v/s Monitor

  1. Monitor is a debugging command. The response format can (and has) change(d) over time. Sync is used for Master -> Slave replication, and so will be better supported
  2. Monitor will emit all commands, including read-only commands. Sync will only get you commands that modify data.
  3. Monitor will log individual commands that are executed within a lua script. Sync will only transfer the entire lua script, so you will have to parse the script yourself. This is indeed a deal breaker for sync.
  4. Monitor will log commands that did not succeed, Sync will only log commands that modify data. For example, the command del non-existing-key will be logged by monitor but won't show up when you run sync.
Ben Smith
  • 19,589
  • 6
  • 65
  • 93
Sripathi Krishnan
  • 30,948
  • 4
  • 76
  • 83
  • Thanks Sripathi! Could you give me a high-level overview of this vs using monitor for updates? – fancy May 21 '12 at 03:39
5

In 2017

There's now a publish/subscribe mechanism which you can use with node-redis module. See specific documentation HERE. (Also works with redis-mock for testing)

You can have several subscribers (listeners) to the same channel, which in your case would be the key to your collection.

quick sample: (see above documentation for implementation details)

sub.subscribe('myCollection');
sub.on('message', (channel, data) => {
    // this is the callback you talked about
    console.log(`${channel} is now ${data}`);
});

// ... later on ...

pub.publish('myCollection', [1,2,3])
// console will output:
// myCollection is now [1,2,3]
Sergei Basharov
  • 51,276
  • 73
  • 200
  • 335
Xeltor
  • 4,626
  • 3
  • 24
  • 26
0
<dependency>
    <groupId>com.moilioncircle</groupId>
    <artifactId>redis-replicator</artifactId>
    <version>2.5.0</version>
</dependency>

If you are using java. redis-replicator implements redis replication protocol. More details please refer to references

Baoyi Chen
  • 71
  • 5