目录
1.分布式锁的使用场景
2.分布式锁的常用实现方式
2.1 基于Zookeeper实现
特点:利用Zookeeper的瞬时节点特性。Zookeeper以Zab协议保证高可用和强一致性
方式:加锁是创建一个瞬时节点,释放锁是删除瞬时节点。
此方案问题:
2.2 基于Redis/MySql实现
特点:Redis比Zookeeper性能好,可利用RedLock来实现
方式:利用Redis的SetNx方法来实现分布式锁,SetNx的原理是当Redis有这个key时则set失败,当Redis没有这个值时,则set成功。
此方案问题:
2.3 用串行化代替分布式锁
并发量大,可靠性高的场景,建议避免使用分布式锁,建议使用串行化
2.3.1 异步串行化
如果业务逻辑处理可以异步处理时,保证对同一个Key或者同一行的操作落入消息中间件的同一个分片中,并且单线程消费消息而后更新DB或缓存。
不使用消息中间件时,可以将操作存入数据库,然后单线程读取数据库存放的操作去执行。保证所有的操作是串行化执行的。
2.3.2 同步串行化
可以把同步串行化理解成,同步并发时,顾客的点了一盘菜,切菜员切好了菜,交给另外的线程处理,另外的线程去争抢这些菜,争抢到的线程炒这盘菜,炒好后,又给其他线程,其他线程再来抢夺这盘菜,将它端上桌,这里面涉及多个锁的释放和加锁,线程的上下文切换。
然后同步串行化的意思是,配菜,炒菜,传菜上桌的工作都串行的放在同一个队列里(这里同等于微服务调用中,将同一个竞态资源的操作交给同一台服务器同一个线程操作。需要做一致性哈希。),交给同一个线程去处理所有的操作。这样避免了线程的上下文切换,也保证了同一个静态资源只有一个线程操作,避免了锁的使用。 这里的同步是指顾客,也就是调用者需要等待线程执行完所有操作,才能停止阻塞状态。