In depth understanding of redis distributed locks and message queues

  • 2020-05-24 06:25:44
  • OfStack

Recently, when looking at redis, bloggers found two ways to use redis. Instead of using redis as a cache, redis can set key's effective time and redis's BRPOP command.

A distributed lock

Because currently some programming languages, such as PHP, cannot use locks in memory, or when a simpler lock check is needed, such as Java, redis distributed locks are sufficient.

The distributed locking of redis is based on the setnx method and redis can set the effective time for key. The basic usage is simple.


public boolean tryLock(String lock,long expireTime){
  String expire = String.valueOf(System.currentTimeMillis() + expireTime + 1);
  Long result = jedis.setNx(lock,expire);
  if(result == 1L){
    jedis.expire(lock, expireTime);
    return true;
  }
  // Determine the timeout key Probably not deleted 
  String currentValue = jedis.get(lock);
  if(Long.parseLong(currentValue) < System.currentTimeMillis()){
    jedis.set(lock, expire);
    jedis.expire(lock, expireTime);
    return true;
  }
  return false;
}
//expire is key To prevent the runtime timeout lock from being accidentally deleted by another thread after it has been taken away 
public unlock(String lock,String expire){
  String value = jedis.get(lock);
  if(value != null && value != expire && Long.parseLong(value) > System.currentTimeMillis())
    jedis.del(lock);
}  

Here is the lock and unlock method I wrote according to redis's mechanism. Now redis does not recommend setNx, but instead USES the set command directly set(lock, expire,"NX", expireTime,"EX"), The functions of setNx and expire can be directly included.

The message queue

Message queuing is mainly applied to the implementation of asynchronous tasks in network services. redis can act as a message queue to implement a producer/consumer model and a subscription/publication model.

Producer/consumer model

The producer/consumer model requires both producers and consumers to exist, and the storage and retrieval of queues in redis can be used by producers and consumers as message queues. Instead of writing the Java code, use the redis command.

Actually, what redis is doing here is caching, LPUSH queue task redis has lpush and rpush, which means to insert a queue from the left and a queue from the right. This is the part of the producer that inserts the task into the specified queue.

The consumer part is a little bit similar, which is the use BRPOP queue 10 Of course, BRPOP here also has a corresponding BLPOP. Since the queue is to fetch tasks in order, what we do here is insert the left side and extract the right side. Here it is important to note that redis BRPOP and RPOP, the reason with BRPOP reason is that the one waiting, is the order of 10, this is a wait time, in seconds, which means if the queue is empty, so I won't return, I wait for 10 seconds, if there is a new task during insert, so I can get a new task to return to, or if not, return null.

In addition, BRPOP also supports priority, i.e BRPOP queue:1 queue:2 queue:3 10 If queue:1 does not get the task, go to queue:2 to get it, one after the other.

Subscribe/publish model

The subscription/publication model simply means that a publisher sends a task to all subscribers, and any subscriber can get the task. The implementation of redis here USES the subscription command.

Publishers can use publish channel task to publish related tasks, while subscribers can use subscribe channel, which is a listening command. redis will listen for this channel directly. However, redis also sets a timeout for this to ensure the effectiveness of the monitor. By default, if no message is received in 60s, it will exit unexpectedly. Of course, this can be configured.


Related articles: