.net core Redis 使用有序集合实现延迟队列

Redis 有序集合和集合一样也是 string 类型元素的集合,且不允许重复的成员。

不同的是每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。

有序集合的成员是唯一的,但分数(score)却可以重复。

集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。

延迟队列的设计思想是将队列的延迟时间作为分数,按照这个进行排序

  1. 安装依赖
bash 复制代码
Newtonsoft.Json             13.0.3   
StackExchange.Redis         2.8.0 
  1. 封装Redis
csharp 复制代码
using StackExchange.Redis;
namespace LedayQueue.RedisHelper
{
    public class RedisConnection
    {
        private readonly ConnectionMultiplexer _connection;
        public IDatabase _database;

        public RedisConnection()
        {
            _connection = ConnectionMultiplexer.Connect("localhost:6379");
            _database = _connection.GetDatabase();
        }



        public async Task AddToQueueAsync(string task, TimeSpan delay)
        {
            var executionTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds() + delay.TotalSeconds;
            await _database.SortedSetAddAsync("delayedQueue", task, executionTime);
        }
    }
}
  1. 封装background service
csharp 复制代码
using StackExchange.Redis;

namespace LedayQueue.RedisHelper
{
    public class DelayedQueueProcessor : BackgroundService
    {
        private readonly RedisConnection _connection;
        private const string QueueKey = "delayedQueue";
        public DelayedQueueProcessor(RedisConnection redisConnection)
        {
            _connection = redisConnection;
        }
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                var now = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
                var tasks = await _connection._database.SortedSetRangeByScoreWithScoresAsync(QueueKey, 0, now);

                foreach (var task in tasks)
                {
                    // 处理任务
                    var taskString = task.Element.ToString();
                    ProcessTask(taskString);

                    // 从队列中移除任务
                    await _connection._database.SortedSetRemoveAsync(QueueKey, task.Element);
                }

                await Task.Delay(TimeSpan.FromSeconds(1), stoppingToken); // 每秒检查一次
            }
        }

        private void ProcessTask(string content)
        {
            Console.WriteLine(content);
        }
    }
}
  1. 注册
csharp 复制代码
builder.Services.AddSingleton<RedisConnection>();
builder.Services.AddHostedService<DelayedQueueProcessor>();

源码

官网

相关推荐
Fishermen_sail8 小时前
《Redis应用实例》学习笔记,第一章:缓存文本数据
redis
RingWu11 小时前
redis sentinel和redis cluster的主从切换选举过程
redis
AllenO.o13 小时前
Redis五种数据结构详解
java·数据结构·数据库·redis·缓存
onkel in blog14 小时前
【Docker】Docker Compose方式搭建分布式内存数据库(Redis)集群
数据库·redis·分布式·docker
我科绝伦(Huanhuan Zhou)16 小时前
Redis再次开源!reids8.0.0一键安装脚本分享
数据库·redis·开源
编程乐趣16 小时前
基于.Net Core开发的GraphQL开源项目
后端·.netcore·graphql
小吕学编程17 小时前
Redis从基础到高阶应用:核心命令解析与延迟队列、事务消息实战设计
java·数据结构·redis
liuhongJAVAEn18 小时前
分布式-Redis分布式锁
数据库·redis·分布式
追风赶月、18 小时前
【Redis】Redis的主从复制
数据库·redis
吾门20 小时前
机器视觉开发教程——C#如何封装海康工业相机SDK调用OpenCV/YOLO/VisionPro/Halcon算法
图像处理·opencv·计算机视觉·c#·.net·.netcore·visual studio