antirez / redlock-rb

Redlock Redis-based distributed locks implementation in Ruby
BSD 2-Clause "Simplified" License
206 stars 25 forks source link

How to use Redlock in cluster #6

Open lgxbslgx opened 5 years ago

lgxbslgx commented 5 years ago

Hi @antirez,

At present, many companies use redis cluster to cache data or do other things. If these companies want to use the RedLock algorithm to implement distributed locks, they must create additional and independent redis nodes just for the Redlock. Because the Redlock algorithm assumes the nodes is independent. As quoted below.

In the distributed version of the algorithm we assume we have N Redis masters. Those nodes are totally independent, so we don’t use replication or any other implicit coordination system.

It is a waste to do that and it's better for us to reuse the cluster. This link provides more information about this problem.

Do you have any ideas about it? Thanks.

koalarun commented 4 years ago

I ran into this problem too. redisson used a funny method to compute the slot by key.In ClusterConnectionManager.java File, `

public int calcSlot(String key) {
    if (key == null) {
        return 0;
    } else {
        int start = key.indexOf(123);
        int result;
        if (start != -1) {
            result = key.indexOf(125);
            key = key.substring(start + 1, result);
        }

        result = CRC16.crc16(key.getBytes()) % 16384;
        this.log.debug("slot {} for {}", result, key);
        return result;
    }
}

key.indexOf(123) to find character '{' and key.indexOf(125) to find '}'。So we had better not to use {} in the key string. But when we use Redlock in cluster, we can use the code below to ensure the lock is distributed on different redis node(3 master node for example):

@Autowired
RedissonClient clusterClient;

private RedissonRedLock getRedLock(String key){
    RLock lock1 = clusterClient.getLock(key.concat("{lock1}"));
    RLock lock2 = clusterClient.getLock(key.concat("{lock2}"));
    RLock lock3 = clusterClient.getLock(key.concat("{lock3}"));

    return new RedissonRedLock(lock1, lock2, lock3);
}

` Simple use key.concat("{1}") also will work.Personly, I don't think is a good idea that redisson make a trick in slot compute algorim, but it just happen to help.