Redis - 修剪队列期间数据丢失的可能性
Redis - possibility of data loss during trimming of a queue
我有一种生产者-消费者设置,其中生产者(不同线程上的多个生产者)将数据排入 redis 队列,消费者(单个线程上的单个消费者)监视该队列。当队列长度达到 >= 10000 项时,消费者应从队列中提取前 10000 项,将它们从队列中删除并对其进行某种计算。
使用 redis-py 客户端,我使用以下代码提取前 10000 个项目,并将它们删除:
logs = REDIS_CLIENT.lrange(task_queue, 0, 9999)
REDIS_CLIENT.ltrim(task_queue, start=10000, end=REDIS_CLIENT.llen(task_queue))
我的问题是,这里有没有可能丢失数据?例如,任务是否有可能在调用函数 ltrim() 和实际修剪队列之间的时间排队(在这种情况下,最新的日志将丢失,因为 end 将是较旧的长度)?还是在 ltrim 操作完成之前对队列加锁?
是的,您可能会丢失数据,因为 ltrim
和 llen
之间有时间 window。
为了关闭那个时间window,你可以设置-1
作为结束偏移量:
REDIS_CLIENT.ltrim(task_queue, start=10000, end=-1)
-1
表示列表结束,不需要明确指定结束偏移量。
我有一种生产者-消费者设置,其中生产者(不同线程上的多个生产者)将数据排入 redis 队列,消费者(单个线程上的单个消费者)监视该队列。当队列长度达到 >= 10000 项时,消费者应从队列中提取前 10000 项,将它们从队列中删除并对其进行某种计算。
使用 redis-py 客户端,我使用以下代码提取前 10000 个项目,并将它们删除:
logs = REDIS_CLIENT.lrange(task_queue, 0, 9999)
REDIS_CLIENT.ltrim(task_queue, start=10000, end=REDIS_CLIENT.llen(task_queue))
我的问题是,这里有没有可能丢失数据?例如,任务是否有可能在调用函数 ltrim() 和实际修剪队列之间的时间排队(在这种情况下,最新的日志将丢失,因为 end 将是较旧的长度)?还是在 ltrim 操作完成之前对队列加锁?
是的,您可能会丢失数据,因为 ltrim
和 llen
之间有时间 window。
为了关闭那个时间window,你可以设置-1
作为结束偏移量:
REDIS_CLIENT.ltrim(task_queue, start=10000, end=-1)
-1
表示列表结束,不需要明确指定结束偏移量。