面试题系列:分布式夺命连环9问
本文插图
作者 | 前阿里技术专家 - 艾小仙
1.说说分布式锁吧?
对于一个单机的系统 , 我们可以通过synchronized或者ReentrantLock等这些常规的加锁方式来实现 , 然而对于一个分布式集群的系统而言 , 单纯的本地锁已经无法解决问题 , 所以就需要用到分布式锁了 , 通常我们都会引入三方组件或者服务来解决这个问题 , 比如数据库、Redis、Zookeeper等 。
通常来说 , 分布式锁要保证互斥性、不死锁、可重入等特点 。
互斥性指的是对于同一个资源 , 任意时刻 , 都只有一个客户端能持有锁 。
不死锁指的是必须要有锁超时这种机制 , 保证在出现问题的时候释放锁 , 不会出现死锁的问题 。
可重入指的是对于同一个线程 , 可以多次重复加锁 。
2.那你分别说说使用数据库、Redis 和 Zookeeper 的实现原理?
数据库的话可以使用乐观锁或者悲观锁的实现方式 。
乐观锁通常就是数据库中我们会有一个版本号 , 更新数据的时候通过版本号来更新 , 这样的话效率会比较高 , 悲观锁则是通过for update的方式 , 但是会带来很多问题 , 因为他是一个行级锁 , 高并发的情况下可能会导致死锁、客户端连接超时等问题 , 一般不推荐使用这种方式 。
Redis是通过set命令来实现 , 在2.6.2版本之前 , 实现方式可能是这样:
本文插图
setNX命令代表当key不存在时返回成功 , 否则返回失败 。
但是这种实现方式把加锁和设置过期时间的步骤分成两步 , 他们并不是原子操作 , 如果加锁成功之后程序崩溃、服务宕机等异常情况 , 导致没有设置过期时间 , 那么就会导致死锁的问题 , 其他线程永远都无法获取这个锁 。
之后的版本中 , Redis提供了原生的set命令 , 相当于两命令合二为一 , 不存在原子性的问题 , 当然也可以通过lua脚本来解决 。
set命令如下格式:
本文插图
key 为分布式锁的key
value 为分布式锁的值 , 一般为不同的客户端设置不同的值
NX 代表如果要设置的key已存在 , 则取消设置
EX 代表过期时间为秒 , PX则为毫秒 , 比如上面示例中为10秒过期
key 为分布式锁的key
value 为分布式锁的值 , 一般为不同的客户端设置不同的值
NX 代表如果要设置的key已存在 , 则取消设置
EX 代表过期时间为秒 , PX则为毫秒 , 比如上面示例中为10秒过期
Zookeeper是通过创建临时顺序节点的方式来实现 。
- 奥陶纪|奥陶纪生物:第二代霸主|地球简史系列
- AMD|荣耀60系列正式官宣,一年两代产品!网友:对标红米Note?
- 奥陶纪|奥陶纪大辐射|地球简史系列
- 荣耀|荣耀60系列爆料汇总:外观、性能、拍照、续航基本都确认了
- 支付宝|欠债3000亿,宣布破产!昔日民族品牌,为何总沦为反面教材?
- 三星|真安卓机皇诞生?103万跑分+双曲面2K屏幕,三星S22太激进了
- OLED|国产屏获得更多订单,有望成为苹果最大的OLED面板供应商
- 创投圈|87项技术专利!Reno7系列首发超感光猫眼镜头,夜拍体验或独一份
- 飞利浦·斯塔克|MySQL统计总数就用count,别花里胡哨的《死磕MySQL系列 十》
- iPhone|12代酷睿非K系列明年1月中旬发布,至少有7个型号