MST

星途 面试题库

面试题:Redis分布式锁在解决MySQL并发写冲突场景下如何实现基本加锁操作

在《Redis分布式锁解决MySQL并发写冲突问题》的场景中,请描述使用Redis实现基本加锁操作的命令及相关参数含义,同时说明如何处理加锁失败的情况。
13.4万 热度难度
数据库Redis

知识考点

AI 面试

面试题答案

一键面试

使用Redis实现基本加锁操作的命令及参数含义

  1. SETNX命令
    • 命令SETNX key value
    • 含义SETNXSET if Not eXists 的缩写。如果 key 不存在,将 key 设置为 value 并返回 1 ,表示加锁成功;如果 key 已经存在,不做任何操作并返回 0 ,表示加锁失败。这里 key 通常作为锁的标识,例如可以是业务相关的唯一标识(如订单号等),value 可以是一个唯一值(如客户端生成的UUID),用于后续解锁时验证是否是当前加锁的客户端。
  2. SET命令(使用NX选项)
    • 命令SET key value NX
    • 含义:这是 SET 命令的一种变体,NX 选项表示只有在 key 不存在时才设置 key 的值。与 SETNX 命令类似,如果 key 不存在,将 key 设置为 value 并返回 OK ,加锁成功;如果 key 存在,则不做任何操作并返回 nil ,加锁失败。keyvalue 的含义与 SETNX 中的类似。

处理加锁失败的情况

  1. 重试机制
    • 说明:加锁失败后,客户端可以在一定时间间隔后重试加锁操作。例如使用指数退避算法,每次重试的间隔时间呈指数增长(如100ms、200ms、400ms等),避免短时间内大量无效重试对系统造成压力。代码示例(以Python为例):
import redis
import time

r = redis.Redis(host='localhost', port=6379, db = 0)
lock_key = 'order_lock'
lock_value = 'unique_value'
retry_count = 0
while True:
    result = r.set(lock_key, lock_value, nx = True)
    if result:
        # 加锁成功,执行相关业务逻辑
        try:
            # 业务代码
            pass
        finally:
            r.delete(lock_key)  # 解锁
        break
    else:
        # 加锁失败,重试
        sleep_time = 100 * (2 ** retry_count) / 1000  # 指数退避时间
        time.sleep(sleep_time)
        retry_count += 1
  1. 排队处理
    • 说明:可以使用Redis的列表(LIST)数据结构来实现排队机制。加锁失败的客户端将自己的请求信息(如任务ID、客户端标识等)添加到一个列表中。当持有锁的客户端完成业务操作并解锁后,从列表中取出下一个请求,通知对应的客户端进行加锁尝试。例如,使用 RPUSH 命令将请求添加到列表尾部,使用 LPOP 命令从列表头部取出请求。
  2. 放弃操作
    • 说明:对于一些对并发要求不是特别高或者加锁失败影响较小的业务场景,可以直接放弃当前操作,并向用户返回相关提示信息,如“系统繁忙,请稍后重试”等。