Redis悲观锁、乐观锁和调用Lua脚本三种方式的优缺点

教程前面主要讨论了 Java 互联网的高并发应用,先谈及了一些常用的系统设计理念,用以搭建高可用的互联网应用系统,着重介绍了抢红包的高并发应用,还讨论了数据不一致的超发问题。

并且还论述了乐观锁、悲观锁和 Redis 如何消除数据不一致性的问题,也对它们的性能进行了探讨。

悲观锁使用了数据库的锁机制,可以消除数据不一致性,对于开发者而言会十分简单,但是,使用悲观锁后,数据库的性能有所下降,因为大量的线程都会被阻塞,而且需要有大量的恢复过程,需要进一步改变算法以提高系统的并发能力。

通过 CAS 原理和 ABA 问题的讨论,我们更加明确了乐观锁的原理,使用乐观锁有助于提高并发性能,但是由于版本号冲突,乐观锁导致多次请求服务失败的概率大大提高,而我们通过重入(按时间戳或者按次数限定)来提高成功的概率,这样对于乐观锁而言实现的方式就相对复杂了,其性能也会随着版本号冲突的概率提升而提升,并不稳定。

使用乐观锁的弊端在于,导致大量的 SQL 被执行,对于数据库的性能要求较高,容易引起数据库性能的瓶颈,而且对于开发还要考虑重入机制,从而导致开发难度加大。

使用 Redis 去实现高并发,通过 Redis 提供的 Lua 脚本的原子性,消除了数据不一致性,并且在整个过程中只有最后一次涉及数据库,而且是使用了新的线程。

在实际的操作中笔者更加倾向于使用 JMS 启动另外的服务器进行操作。但是这样使用的风险在于 Redis 的不稳定性,因为其事务和存储都存在不稳定的因素,所以更多的时候,笔者都建议使用独立 Redis 服务器做高并发业务,一方面可以提高 Redis 的性能,另一方面即使在高并发的场合,Redis 服务器宕机也不会影响现有的其他业务,同时也可以使用备机等设备提高系统的高可用,保证网站的安全稳定。

以上讨论了 3 种方式实现高并发业务技术的利弊,妥善规避风险,同时保证系统的高可用和高效是值得每一位开发者思考的问题。