分布式锁用redis和zk来实现,是常见的做法,下面简单列一下两方的优缺点:
redis版本应该是4.0以上,redisson版本3.14.0
public class RedissonLock {
private static int count = 0;
public static void main(String[] args) throws InterruptedException {
Config config = new Config();
config.useClusterServers()
.addNodeAddress("redis://192.168.11.1:6380")
.addNodeAddress("redis://192.168.11.2:6380")
.addNodeAddress("redis://192.168.11.3:6380");
config.setLockWatchdogTimeout(10000);
RedissonClient redisson = Redisson.create(config);
ExecutorService executorService = Executors.newCachedThreadPool();
RLock lock = redisson.getLock("lock0000");
int threadNum = 100;
final int repetitions = 2;
Long start = System.currentTimeMillis();
for (int i = 0; i < threadNum; i++) {
executorService.submit(() -> {
for (int j = 0; j < repetitions; j++) {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
return null;
});
}
executorService.shutdown();
executorService.awaitTermination(10, TimeUnit.MINUTES);
System.out.println("cost:"+(System.currentTimeMillis() - start));
System.out.println(count);
redisson.shutdown();
}
}
结果:
cost:1186
200
zookeeper版本3.4 curator版本2.13.0
public class CuratorLock {
private static final String ZK_ADDRESS = "192.168.1.1:2181,192.168.1.2:2181,192.168.1.3:2181";
private static int count = 0;
public static void main(String[] args) throws Exception {
ExecutorService executorService = Executors.newCachedThreadPool();
CuratorFramework client = CuratorFrameworkFactory.newClient(ZK_ADDRESS, new RetryNTimes(10, 1000));
client.start();
InterProcessMutex lock = new InterProcessMutex(client, "/distributeLockTest/myLockName");
int threadNum = 100;
final int repetitions = 2;
Long start = System.currentTimeMillis();
for(int i = 0;i< threadNum;i++){
executorService.submit(() -> {
for(int j = 0;j<repetitions;j++){
try {
lock.acquire();
count++;
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
lock.release();
} catch (Exception e) {
e.printStackTrace();
}
}
}
return 0;
});
}
executorService.shutdown();
executorService.awaitTermination(10, TimeUnit.MINUTES);
System.out.println("cost:"+(System.currentTimeMillis() - start));
System.out.println(count);
CloseableUtils.closeQuietly(client);
}
}
结果:
cost:20538
200
总结:
Redis | Zookeeper | |
---|---|---|
语言 | C | Java |
库 | Redisson | Curator |
部署方案 | redis cluster 三主三从 | zk集群 三节点 |
实现方式 | lua + pub/sub | ZAB一致性协议 |
优势 | 内存操作性能较好 | 数据落磁盘可靠性高 |
缺点 | 主从切换可能有问题 | 高并发下性能可能有瓶颈 |
可用场景 | 容忍极端情形下的失败,追求高性能 | 安全第一 |
注意点: | ||
1、Redisson RedLock已标注为弃用,使用RLock即可,RLock使用了wait命令,但wait只能提高数据安全性不保证一致性 |
请注意,WAIT 不会使 Redis 成为强一致性的存储:虽然同步复制是复制状态机的一部分,
但它不是唯一需要的。但是,在 Sentinel 或 Redis 群集故障转移的情况下,WAIT 可以提高现实世界的数据安全性。