分布式锁使用场景以及实现方式
目录
1.分布式锁的使用场景
场景:单机多个线程并发更新数据库同一行时
方案:使用线程锁
场景:多个进程(多台机器)并发更新数据库同一行时
方案:使用悲观锁,乐观锁
场景:多个进程(多台机器)并发更新多个资源时,同时更新数据库和Redis时
方案:需要对多个资源进行加锁,控制多个资源的并发更新,使用分布式锁
2.分布式锁的常用实现方式
2.1 基于Zookeeper实现
特点:利用Zookeeper的瞬时节点特性。Zookeeper以Zab协议保证高可用和强一致性
方式:加锁是创建一个瞬时节点,释放锁是删除瞬时节点。
此方案问题:
性能问题:高并发下,QPS不够
两个进程得到一把锁:由于使用心跳机制判断是否宕机,网络超时或者客户机FULL GC时,可能会发送误判。
2.2 基于Redis/MySql实现
特点:Redis比Zookeeper性能好,可利用RedLock来实现
方式:利用Redis的SetNx方法来实现分布式锁,SetNx的原理是当Redis有这个key时则set失败,当Redis没有这个值时,则set成功。
此方案问题:
1.Redis主从采用异步复制,如果主宕机,切换到从后,会导致部分锁的数据丢失,多个进程或得到同一把锁。
2.Redis之间没有心跳,获取锁时如果宕机,锁永远得不到释放。
3.如果加过期时间,如果客户端发生FullGC或者其他业务导致超时(非宕机导致过期释放锁),也会导致两个进程得到锁。
2.3 用串行化代替分布式锁
并发量大,可靠性高的场景,建议避免使用分布式锁,建议使用串行化
2.3.1 异步串行化
如果业务逻辑处理可以异步处理时,保证对同一个Key或者同一行的操作落入消息中间件的同一个分片中,并且单线程消费消息而后更新DB或缓存。
不使用消息中间件时,可以将操作存入数据库,然后单线程读取数据库存放的操作去执行。保证所有的操作是串行化执行的。
2.3.2 同步串行化
可以把同步串行化理解成,同步并发时,顾客的点了一盘菜,切菜员切好了菜,交给另外的线程处理,另外的线程去争抢这些菜,争抢到的线程炒这盘菜,炒好后,又给其他线程,其他线程再来抢夺这盘菜,将它端上桌,这里面涉及多个锁的释放和加锁,线程的上下文切换。
然后同步串行化的意思是,配菜,炒菜,传菜上桌的工作都串行的放在同一个队列里(这里同等于微服务调用中,将同一个竞态资源的操作交给同一台服务器同一个线程操作。需要做一致性哈希。),交给同一个线程去处理所有的操作。这样避免了线程的上下文切换,也保证了同一个静态资源只有一个线程操作,避免了锁的使用。 这里的同步是指顾客,也就是调用者需要等待线程执行完所有操作,才能停止阻塞状态。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)