首先需要说明一点的是:我们一直在强调 redis 是单线程,只是在处理我们的网络请求的时候只有一个线程来处理,一个正式的Redis Server运行的时候肯定是不止一个线程的。
为什么redis是单线程的?
??官方FAQ表示,因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了。
为什么redis需要加锁?
??我们需要注意的是:redis是单线程这是毋庸置疑的。redis 本身是不会产生并发安全问题的,不需要加锁。再多的 commands 都是 one by one 执行的。 ??这里说的加锁是我们为了满足业务在使用的时候,可能会出现并发问题而需要加锁。比如,当一个 redis 服务器同时有多个客户端访问时,每个客户端会有一个线程。客户端访问之间存在竞争。因为存在多客户端并发,所以必须保证操作的原子性。比如银行卡扣款问题,获取余额,判断,扣款,写回就必须构成事务,否则就可能出错。 ??在传统单体应用单机部署的情况下,可以使用Java并发相关的锁,如ReentrantLcok或synchronized进行互斥控制。但是,随着业务发展的需要,原单体单机部署的系统,渐渐的被部署在多机器多JVM上同时提供服务,这使得原单机部署情况下的并发控制锁策略失效了,为了解决这个问题就需要一种跨JVM的互斥机制来控制共享资源的访问,这就是分布式锁要解决的问题。 ??分布式环境下,数据一致性问题一直是一个比较重要的话题,而又不同于单进程的情况。分布式与单机情况下最大的不同在于其不是多线程而是多进程。多线程由于可以共享堆内存,因此可以简单的采取内存作为标记存储位置。而进程之间甚至可能都不在同一台物理机上,因此需要将标记存储在一个所有进程都能看到的地方 ??可以用 redis 来实现分布式锁。
分布式锁的实现条件
1、互斥性:要保证任意时刻,只能有一个客户端持有锁。
2、可靠性:要保证系统的稳定性,不能产生死锁。
3、一致性:要保证锁只能由加锁人解锁,不能产生A的加锁被B用户解锁的情况。
|