大型网站及应用都是分布式部署的,在分布式环境中的数据一致性问题一直是一个比较重要的话题,如何保证数据的一致性,那就离不开分布式锁。那么问题也就接踵而至。分布式锁有基于数据库的行数、redis以及zookeeper三种实现方式,同样是分布式锁,三者的区别何在?各自适用什么场景?
一.场景
- 电商场景中的秒杀、抢购;保证产品不超卖。
- 比如是在分布式集群环境里,多个客户端同时修改一个共享的数据保证数据的一致性。
二.分布式锁的方案
- 基于数据库的行锁,有乐观锁、悲观锁。
- 使用redis来解决,也有乐观锁和悲观锁两种实现。
- 基于zookeeper
三.几种方案的比较
- 基于数据库的实现,首先数据库的访问其实就是对磁盘文件的访问,高并发环境下,磁盘IO读写过多,肯定会占用很多资源,必然导致CPU占用会居高不下,在高并发的情况下,肯定不能如此高频率的去读写数据库。而且mysql是一个连接给一个线程,当并发高的时候,每秒需要几百个甚至更多的线程,其中创建和销毁线程也很耗费性能。
- redis实现,首先redis本身是一个cache,所有的操作都在内存中进行的。当然redis是支持落地的(题外话)。
- zk.......等研究好了补上。
四.悲观锁和乐观锁的选择
我总结了一下有这么几点:
- 响应时间
- 冲突频率
- 重试代价
如果需要非常高的响应速度,建议使用乐观锁,成功就执行,不成功就失败,不需要等待其他并发去释放锁。如果冲突频率高或者重试代价大建议使用悲观锁。
五.实现方式
数据库的悲观锁和乐观锁
- 悲观锁使用mybatis的可以用for update。
- 乐观锁直接用版本号
redis悲观锁和乐观锁
- 悲观锁 SETNX
- 乐观锁 WATCH MULTI EXEC
zk实现
.................
下一篇将具体介绍如何使用redis实现分布式锁,敬请期待!