面试题答案
一键面试利用Redis持久化保证任务不丢失
- AOF持久化:
- 开启AOF(Append - Only File)持久化模式,Redis会将写命令追加到AOF文件中。
- 配置
appendfsync
参数,有always
、everysec
、no
三个可选值。always
每次写操作都同步到AOF文件,能最大程度保证数据不丢失,但性能开销较大;everysec
每秒同步一次,在性能和数据安全间做了平衡;no
由操作系统决定何时同步,性能最好但数据丢失风险相对较高,推荐使用everysec
。
- RDB持久化:
- 也可结合RDB(Redis Database)持久化,它会在指定的时间间隔内对数据进行快照。
- 通过配置
save
参数来设置快照触发条件,如save 900 1
表示900秒内如果至少有1个键被修改,则进行快照。当Redis重启时,可以加载RDB文件恢复数据。
利用Redis事务和Lua脚本保证任务原子性和避免重复执行
- Redis事务:
- 将任务相关的操作放在一个事务中,如使用
MULTI
开启事务,EXEC
执行事务。 - 例如,在向任务队列添加任务时,同时设置一个任务状态标识,确保这两个操作要么都成功,要么都失败,防止任务添加成功但状态标识未设置的不一致情况。
- 将任务相关的操作放在一个事务中,如使用
- Lua脚本:
- 编写Lua脚本来处理复杂的任务调度逻辑,Lua脚本在Redis中是原子执行的。
- 比如,判断任务是否存在并添加任务的逻辑可以写在Lua脚本中,这样能避免并发情况下任务重复添加。如下是一个简单示例:
-- 判断任务是否已存在,不存在则添加任务
if redis.call('EXISTS', KEYS[1]) == 0 then
redis.call('RPUSH', KEYS[2], ARGV[1])
return 1
else
return 0
end
在应用中调用该Lua脚本,通过EVAL
命令执行,保证任务添加的原子性和唯一性。
利用Redis的发布订阅和消费者确认机制保证任务可靠执行
- 发布订阅:
- 生产者将任务发布到指定频道,消费者订阅该频道接收任务。
- 例如,生产者使用
PUBLISH task_channel "task_info"
发布任务,消费者使用SUBSCRIBE task_channel
接收任务。
- 消费者确认机制:
- 消费者接收到任务后,先向Redis中某个标识任务处理状态的键写入“处理中”状态,如
SET task:1 status "processing"
。 - 任务处理完成后,将该状态更新为“已完成”,如
SET task:1 status "completed"
。 - 生产者或监控机制可以定期检查任务状态,如果发现任务长时间处于“处理中”,可以重新发布任务,确保任务不会因消费者故障而丢失。
- 消费者接收到任务后,先向Redis中某个标识任务处理状态的键写入“处理中”状态,如
利用Redis Sentinel或Cluster保证高可用性
- Redis Sentinel:
- 部署Redis Sentinel集群,它可以监控主从Redis实例。
- 当主节点发生故障时,Sentinel能自动将一个从节点晋升为主节点,保证Redis服务的可用性,进而保证任务调度的连续性。
- Redis Cluster:
- 采用Redis Cluster架构,数据会分布在多个节点上。
- 它具有自动故障转移功能,当某个节点出现故障时,集群会自动将该节点的请求转发到其他可用节点,保障任务调度不受单个节点故障影响。