使用Redis构建分布式锁
在软件开发中,锁是常见的一种业务处理方式,用途也很广泛。锁给我们提供了一种能够被多个线程访问的共享内存数据结构,在使用锁时,通常有着以下步骤“获取锁、然后执行操作、最后释放锁”。
最初的锁实现中,是提供给同一进程内的多个线程进行共享访问的,因为最初往往程序都是单机部署,而随着互联网技术的发展,分布式部署已成了主流,同一应用往往部署在多个不同的服务器中。
能让分布在不同服务器的进程同时访问的锁,称为分布式锁。分布式锁有多种实现方式,这里只介绍其中的一种:利用Redis实现分布式锁。
简易锁
大部分Redis用户对锁(lock)、加锁(locking)、锁超时(lock timeout)有所了解,但确不一定能够正确使用,都是因为未能正确考虑以下几种故障和异常情况:
- 持有锁的进程因为操作时间过长而导致锁被自动释放,但进程本身并不知道,那么当该线程对锁进行释放时就有可能会将其他进程持有的锁进行释放;
- 当前持有锁的进程在进行长时间操作时崩溃,导致锁未能正常释放,而其他想要获取锁的线程并不知道哪个线程持有锁,也无法知晓持有锁的线程已经崩溃,因此只能等待锁过期释放;
- 当一个进程持有的锁过期后,多个线程同时尝试去获取锁,且都获取了锁;
- 上述第一、第三种情况同时出现,导致多个线程获得了锁,而每个线程都以为自己是唯一获得锁的线程;
如今稍微好点硬件能够让Redis在服务器上每秒执行几十万次操作,虽说上述情况出现的几率较小,但在高负载时出现的几率会大大提高,因此需要编写能正确工作的锁。