Redis是什么

安装Redis和可视化工具就直接跳过了

开始使用常见的五种数据类型

创建一个控制台应用,安装Nuget包

Install-Package StackExchange.Redis

String类型,常用来存储文本、Json、Base64图片编码等

static async void RedisString(IDatabase db)
{
    // 增加
    await db.StringSetAsync("UserName", "Alice");

    // 查询
    string userName = await db.StringGetAsync("UserName");
    await Console.Out.WriteLineAsync("Username: " + userName);

    // 修改
    await db.StringSetAsync("UserName", "Bob");

    // 查询
    userName = await db.StringGetAsync("UserName");
    await Console.Out.WriteLineAsync("Updated Username: " + userName);

    // 删除
    await db.KeyDeleteAsync("UserName");
}

Hash类型,是一种键值对的集合,用于存储结构化的数据

static async void RedisHash(IDatabase db)
{
    // 使用冒号拼接键可以进行分组
    await db.HashSetAsync("User:1001", "FirstName", "Alice");
    await db.HashSetAsync("User:1001", "LastName", "Amy");
    await db.HashSetAsync("User:1002", "Name", "Jack");

    // 查询
    string name = await db.HashGetAsync("User:1001", "FirstName");
    await Console.Out.WriteLineAsync("FirstName: " + name);

    // 修改
    await db.HashSetAsync("User:1001", "FirstName", "Bob");

    // 查询
    name = await db.HashGetAsync("User:1001", "FirstName");
    await Console.Out.WriteLineAsync("Updated FirstName: " + name);

    // 删除 Hash 类型键的指定字段
    await db.HashDeleteAsync("User:1002", "Name");
}

List列表,常用来做队列

分为先进先出(FIFO)和先进后出(FILO)

static async void RedisList(IDatabase db)
{
    // 以下是先进先出案例
    await db.ListLeftPushAsync("Emails", "Alice@example.com");
    await db.ListLeftPushAsync("Emails", "Jack@example.com");

    // 查询
    while (await db.KeyExistsAsync("Emails"))
    {
        string email = await db.ListRightPopAsync("Emails");
        await Console.Out.WriteLineAsync("Email: " + email);
    }

    // List在消费后会自动删除键,所以这里可以省略KeyDeleteAsync操作
    // await db.KeyDeleteAsync("Emails");
}

Set无序列表,根据插入的顺序进行排序

static async void RedisSet(IDatabase db)
{
    // 增加
    await db.SetAddAsync("Students", "Alice");
    await db.SetAddAsync("Students", "Jack");

    // 查询
    RedisValue[] students = await db.SetMembersAsync("Students");
    foreach (var student in students)
    {
        await Console.Out.WriteLineAsync("Student: " + student);
    }

    // 删除
    await db.KeyDeleteAsync("Students");
}

ZSet有序列表,根据字段Score进行排序

static async void RedisZSet(IDatabase db)
{
    // 增加
    await db.SortedSetAddAsync("Teachers", "Alice", 1000);
    await db.SortedSetAddAsync("Teachers", "Jack", 500);
    // 查询
    var teachers = await db.SortedSetRangeByRankWithScoresAsync("Teachers");
    foreach (var teacher in teachers)
    {
        await Console.Out.WriteLineAsync("Teacher: " + teacher.Element + ", Score: " + teacher.Score);
    }

    // 删除
    await db.KeyDeleteAsync("Teachers");
}

Redis发布订阅机制

模拟向NBA的频道发送一条消息

static async void PushMessage(ConnectionMultiplexer redis)
{
    // 频道名
    string channel = "NBA";
    // 消息内容
    string message = "Welcome to NBA";
    var subscriber = redis.GetSubscriber();
    // 订阅频道
    subscriber.Subscribe(new RedisChannel(channel, RedisChannel.PatternMode.Auto)).OnMessage(channelMessage =>
    {
        Console.WriteLine(($"订阅消息:{(string)channelMessage.Message}"));
    });
    // 发布消息
    await subscriber.PublishAsync(new RedisChannel(channel, RedisChannel.PatternMode.Auto), message);
}

需要先成功订阅频道才可以收到发布消息

Redis监听过期Key

首先需要修改配置文件中的otify-keyspace-events字段改为Ex

重启Redis之后调试如下代码

static async void RedisKeyExpired(ConnectionMultiplexer redis, IDatabase db)
{
    var subscriber = redis.GetSubscriber();

    // 订单号
    string orderNo = "20240402153515";

    // 模拟订单放入Redis中,10秒过期
    await db.StringSetAsync(orderNo, "iPhone15", TimeSpan.FromSeconds(10));

    // 订阅Redis过期键通知
    await subscriber.SubscribeAsync("__keyevent@0__:expired", async (pattern, value) =>
    {
        await Console.Out.WriteLineAsync($"订单号:{value}已过期!");
    });
}

使用场景一般是订单在规定时间未付款,过期后自动取消并释放库存

Main方法调用如下

static void Main()
{
    var redis = ConnectionMultiplexer.Connect("localhost");
    var db = redis.GetDatabase();
    RedisKeyExpired(redis, db);
    RedisString(db);
    RedisHash(db);
    RedisList(db);
    RedisSet(db);
    RedisZSet(db);
    PushMessage(redis);
    Console.ReadKey();
}

最后值得关注的是Redis的开源协议变更微软的Garnet横空出世


被这风吹散的人说Ta爱的不深,被这雨淋湿的人说Ta不会冷