面试题答案
一键面试应用场景
- 定时任务执行:在分布式环境下,可能有多个节点都配置了相同的定时任务。例如,每天凌晨进行数据备份的任务,如果没有分布式锁,多个节点可能同时执行该任务,导致数据备份重复、资源浪费等问题。使用分布式锁可以保证在同一时刻只有一个节点能够执行该定时任务。
- 任务分配:在任务调度系统中,有一批任务需要分配给不同的工作节点处理。为了避免多个节点同时争抢同一个任务,使用分布式锁来确保每个任务只能被一个节点获取并处理。比如在一个分布式爬虫系统中,需要抓取不同网页的任务,通过分布式锁可以保证每个网页的抓取任务只会被一个爬虫节点执行,防止重复抓取。
解决的问题
- 避免任务重复执行:确保相同的任务在分布式环境下不会被多个节点同时执行,保证任务执行的准确性和一致性,避免资源浪费和数据冲突。
- 任务分配的唯一性:在任务分配场景中,保证每个任务都能被唯一的节点处理,防止任务处理冲突和结果不一致。
工作原理
- 基于Redis的分布式锁:
- 加锁:客户端尝试使用SETNX(SET if Not eXists)命令在Redis中设置一个特定的键值对,键通常是任务的唯一标识,值可以是一个随机生成的字符串,用于后续解锁验证。如果SETNX命令执行成功,说明客户端成功获取到锁,否则获取锁失败。
- 解锁:客户端执行完任务后,通过Lua脚本来删除Redis中的锁键。在Lua脚本中,首先验证锁的值是否与加锁时设置的值相同,只有相同才执行删除操作,这样可以避免误删其他客户端的锁。
- 基于Zookeeper的分布式锁:
- 加锁:客户端在Zookeeper的指定目录下创建一个临时顺序节点。Zookeeper会为每个新创建的节点分配一个唯一的顺序号。客户端获取目录下所有子节点,并判断自己创建的节点序号是否最小。如果是最小,则表示获取到锁;否则,监听比自己序号小的前一个节点。
- 解锁:客户端执行完任务后,删除自己在Zookeeper中创建的临时顺序节点。此时,下一个序号最小的节点的客户端会收到通知,重新判断是否可以获取锁。