面试题答案
一键面试1. 分布式锁机制
- 使用 Redis 自身的 SETNX 命令:通过
SETNX key value
尝试设置一个键值对,如果键不存在则设置成功并返回 1,否则返回 0。可以利用这个特性来实现简单的分布式锁。例如,在对关键数据进行修改前,先尝试获取锁:
SETNX lock_key unique_value
获取锁成功后进行数据操作,操作完成后通过 DEL lock_key
释放锁。
- Redlock 算法:当 Redis 部署为多实例时,为避免单个实例故障导致锁失效,可使用 Redlock 算法。它基于多个独立的 Redis 实例,客户端需在大多数(超过半数)实例上成功获取锁才算获取成功。具体步骤如下:
- 获取当前时间戳
T1
。 - 依次向多个 Redis 实例发送
SETNX
命令获取锁,记录获取锁的总耗时T2
。 - 如果在大多数实例上成功获取锁,且
T2 < 锁的有效时间
,则认为获取锁成功。 - 如果获取锁失败,向所有已获取锁的实例发送
DEL
命令释放锁。
- 获取当前时间戳
2. 同步策略
- 主从复制:Redis 集群通常采用主从复制模式,主节点负责写操作,从节点复制主节点的数据。主节点将写命令发送给从节点,从节点执行这些命令来保持数据同步。为确保一致性,可配置为
WAIT numreplicas timeout
模式,主节点在收到numreplicas
个从节点确认已复制数据后,才向客户端返回成功。例如:
WAIT 2 1000
这表示主节点等待至少 2 个从节点在 1000 毫秒内确认复制数据。
- 异步同步:在一些场景下,为了提高性能,可以采用异步同步策略。主节点在写操作后立即返回给客户端成功,同时异步将写命令发送给从节点。从节点在后台进行数据同步。虽然这种方式可能会导致短时间的数据不一致,但在最终一致性的要求下,从节点会尽快跟上主节点的数据。
3. 应对网络分区异常情况
- 脑裂处理:当网络分区发生时,可能会出现“脑裂”现象,即部分节点组成新的小集群,各自进行数据操作。为避免这种情况导致数据不一致,可采用以下措施:
- 多数派机制:只有包含大多数节点的分区才能正常工作,小的分区自动停止写操作。例如,对于 5 节点的集群,当发生网络分区,包含 3 个及以上节点的分区可继续提供服务,而小于 3 个节点的分区停止写操作,仅提供读操作,待网络恢复后再进行数据同步。
- 设置节点超时时间:如果主节点在一段时间内没有收到多数从节点的心跳,就自动降级为从节点,直到网络恢复并重新选举出主节点。例如,通过配置
repl-timeout
参数设置从节点与主节点连接的超时时间。
- 数据恢复:网络恢复后,各节点需要进行数据合并和同步。可通过以下方式:
- 基于日志的恢复:每个节点记录自己的操作日志,网络恢复后,通过对比日志找出差异并进行同步。例如,主节点记录写操作日志,从节点在网络恢复后请求主节点的日志,根据日志进行数据更新。
- 全量同步和增量同步结合:对于数据差异较大的情况,先进行全量同步,即从节点从主节点获取完整的数据副本;对于差异较小的情况,采用增量同步,只同步自上次同步后发生变化的数据。例如,Redis 从节点在初次同步时采用全量同步,后续的同步则根据主节点的复制偏移量进行增量同步。