多线程对同一资源的竞争,需要用到锁,例如Java自带的Synchronized、ReentrantLock。
但只能用于单机系统中,如果涉及到分布式环境(多机器)的资源竞争,则需要分布式锁。
分布式锁的主要作用:
保证数据的正确性:
比如:秒杀的时候防止商品超卖,表单重复提交,接口幂等性。
避免重复处理数据:
比如:调度任务在多台机器重复执行,缓存过期所有请求都去加载数据库。
分布式锁的主要特性:
互斥:同一时刻只能有一个线程获得锁。
可重入:当一个线程获取锁后,还可以再次获取这个锁,避免死锁发生。
高可用:当小部分节点挂掉后,仍然能够对外提供服务。
高性能:要做到高并发、低延迟。
支持阻塞和非阻塞:Synchronized是阻塞的,ReentrantLock.tryLock()就是非阻塞的
支持公平锁和非公平锁:Synchronized是非公平锁,ReentrantLock(boolean fair)可以创建公平锁
使用 MySQL 实现分布式锁
使用 Redis 实现分布式锁
使用 Zookeeper 实现分布式锁
Redis与zookeeper分布式锁对比
redis实现分布式锁优点在于其性能很高,能够支撑高并发的加锁与解锁操作。而其缺点也很明显,主要如下:
采用抢占式方式进行锁的获取,需要不断的在用户态进行CAS尝试获取锁,对CPU占用率高。
redis本身并不是CP模型,即便采用了redlock算法,但仍然无法保证百分百不会出现问题,如持久化问题。
对于redis分布式锁的使用,在企业中是非常常见的,绝大多数情况不会出现极端情况。
zookeeper实现分布式的优点在于其是强一致性的,采用排队监听的方式获取锁,不会像redis那样不断进行轮询尝试,对性能消耗较小。其缺点则是如果频繁的加锁和解锁,对zk服务器压力较大。
当进行技术选型时,应该对其优缺点结合公司当前情况进行考虑。 如果公司有条件使用zk集群,更推荐使用zk的分布式锁,因为redis实现分布式锁有可能出现数据不正确的情况,但如果公司没有zk集群,使用redis集群完成分布式锁也无可厚非。
https://blog.csdn.net/poizxc2014/article/details/123963250
https://blog.csdn.net/u010541670/article/details/125638229
标签:Synchronized,zk,实现,ReentrantLock,redis,分布式 From: https://www.cnblogs.com/loquat6/p/17241496.html