当前位置: 首页 > news >正文

C# Redis 框架开发技术详解

引言

Redis 是一个高性能的键值存储系统,广泛用于缓存、消息队列和实时分析等场景。在 C# 中,有几个著名的库和框架可以方便地与 Redis 进行交互。以下是几个常用的 C# Redis 库:

  1. StackExchange.Redis: 这是目前最流行、最推荐的 C# Redis 客户端,由 StackExchange 团队(也就是开发 Stack Overflow 的团队)开发和维护。

  2. ServiceStack.Redis: 这是另一个功能齐全的 Redis 客户端,但需要注意的是,ServiceStack 是一个商业产品,对于非开源项目和商业用途可能需要付费。

  3. CSRedis: 这也是一个不错的 Redis 客户端,提供了简单易用的 API。

        其中最常用的是 StackExchange.Redis。本篇文章将深入解析 StackExchange.Redis 的概念、原理、作用、应用场景及应用实例。 

一、概念与原理

什么是 Redis

Redis(Remote Dictionary Server)是一个开源的、基于内存的数据结构存储系统,可以用作数据库、缓存和消息中间件。它支持多种数据结构,如字符串、哈希、列表、集合、有序集合等。Redis 的主要特点是速度快、支持持久化、丰富的数据结构和简单易用的 API。

什么是 StackExchange.Redis

StackExchange.Redis 是一个由 StackExchange 团队开发的 C# 客户端库,用于与 Redis 进行交互。它提供了高效、稳定且功能丰富的 API,适合在 .NET 应用中使用。

StackExchange.Redis 的基本原理

StackExchange.Redis 利用 Redis 的发布/订阅模型和数据结构,通过 TCP 连接与 Redis 服务器进行通信。它内部维护了连接池,以便高效地管理和复用连接,同时提供了丰富的异步操作支持。

二、作用与应用场景

作用

  1. 缓存:通过缓存热点数据,减少数据库的压力,提高系统性能。
  2. 消息队列:利用 Redis 的发布/订阅模型和列表结构,实现消息队列功能。
  3. 分布式锁:利用 Redis 的原子操作和过期时间,实现分布式锁。
  4. 计数器:利用 Redis 的字符串操作,快速实现计数器功能。
  5. 会话存储:将用户会话数据存储在 Redis 中,实现分布式会话管理。
  6. 排行榜:利用 Redis 的有序集合实现高效的排行榜功能。

应用场景

  1. 电商平台:缓存商品信息、库存数据、用户购物车等。
  2. 社交网络:缓存用户信息、好友列表、聊天记录等。
  3. 游戏后台:缓存玩家数据、排行榜、游戏状态等。
  4. 实时分析:缓存实时统计数据、分析结果等。
  5. 内容管理系统:缓存文章、评论、标签等。

三、应用实例

下面将通过一个详细的实例,展示如何在 C# 项目中使用 StackExchange.Redis 进行 Redis 操作。

项目准备

安装 StackExchange.Redis

首先,需要在项目中安装 StackExchange.Redis 包。可以使用 NuGet 包管理器进行安装。

使用 NuGet 命令行安装:

Install-Package StackExchange.Redis

 或者使用 .NET CLI 安装:

dotnet add package StackExchange.Redis

 

基本操作实例

连接 Redis

首先,我们需要连接到 Redis 服务器。以下是连接 Redis 的代码示例:

using System;
using StackExchange.Redis;class Program
{private static ConnectionMultiplexer redis;private static IDatabase db;static void Main(string[] args){// 连接到 Redis 服务器redis = ConnectionMultiplexer.Connect("localhost"); // 如果 Redis 运行在本地,使用 "localhost"db = redis.GetDatabase();Console.WriteLine("Connected to Redis");// 关闭连接redis.Close();Console.WriteLine("Redis connection closed.");}
}

在上面的代码中,我们使用 ConnectionMultiplexer.Connect 方法连接到 Redis 服务器,并使用 GetDatabase 方法获取一个 Redis 数据库实例。

字符串操作

下面展示了如何进行字符串类型键值对的操作:

// 设置一个键值对
db.StringSet("mykey", "Hello, Redis!");// 获取键对应的值
string value = db.StringGet("mykey");
Console.WriteLine("mykey: " + value);// 设置一个带过期时间的键
db.StringSet("mykey_expire", "This key will expire in 10 seconds", TimeSpan.FromSeconds(10));// 获取带过期时间的键的值
value = db.StringGet("mykey_expire");
Console.WriteLine("mykey_expire: " + value);// 等待 10 秒后再次尝试获取
System.Threading.Thread.Sleep(10000);
value = db.StringGet("mykey_expire");
Console.WriteLine("mykey_expire after 10 seconds: " + value);

 

哈希操作

下面展示了如何进行哈希类型数据的操作:

// 设置哈希字段值
db.HashSet("user:1", new HashEntry[]
{new HashEntry("name", "Alice"),new HashEntry("age", 30)
});// 获取哈希字段值
string name = db.HashGet("user:1", "name");
int age = (int)db.HashGet("user:1", "age");
Console.WriteLine($"User: name={name}, age={age}");// 获取所有哈希字段值
HashEntry[] hashEntries = db.HashGetAll("user:1");
foreach (var entry in hashEntries)
{Console.WriteLine($"{entry.Name}: {entry.Value}");
}

 

列表操作

下面展示了如何进行列表类型数据的操作:

// 添加元素到列表
db.ListRightPush("mylist", "item1");
db.ListRightPush("mylist", "item2");
db.ListRightPush("mylist", "item3");// 获取列表长度
long length = db.ListLength("mylist");
Console.WriteLine($"List length: {length}");// 获取列表中的所有元素
for (long i = 0; i < length; i++)
{string item = db.ListGetByIndex("mylist", i);Console.WriteLine($"List item {i}: {item}");
}// 移除并获取列表中的第一个元素
string firstItem = db.ListLeftPop("mylist");
Console.WriteLine($"First item: {firstItem}");

 

集合操作

下面展示了如何进行集合类型数据的操作:

// 添加元素到集合
db.SetAdd("myset", "item1");
db.SetAdd("myset", "item2");
db.SetAdd("myset", "item3");// 获取集合中的所有元素
RedisValue[] setItems = db.SetMembers("myset");
foreach (var item in setItems)
{Console.WriteLine($"Set item: {item}");
}// 判断元素是否在集合中
bool isMember = db.SetContains("myset", "item2");
Console.WriteLine($"Is item2 in set: {isMember}");

有序集合操作

下面展示了如何进行有序集合类型数据的操作:

// 添加元素到有序集合
db.SortedSetAdd("myzset", "item1", 1.0);
db.SortedSetAdd("myzset", "item2", 2.0);
db.SortedSetAdd("myzset", "item3", 3.0);// 获取有序集合中的所有元素
SortedSetEntry[] zsetItems = db.SortedSetRangeByRankWithScores("myzset");
foreach (var item in zsetItems)
{Console.WriteLine($"ZSet item: {item.Element}, score: {item.Score}");
}// 获取元素的分数
double score = db.SortedSetScore("myzset", "item2");
Console.WriteLine($"Score of item2: {score}");

高级操作实例

发布/订阅

Redis 的发布/订阅模型非常适合用于消息队列和事件通知。下面是发布/订阅的示例:

using System;
using StackExchange.Redis;class Program
{// 定义 Redis 连接和数据库实例private static ConnectionMultiplexer redis;private static IDatabase db;static void Main(string[] args){// 连接到 Redis 服务器redis = ConnectionMultiplexer.Connect("localhost"); // 这里假设 Redis 运行在本地db = redis.GetDatabase(); // 获取 Redis 数据库实例ISubscriber sub = redis.GetSubscriber(); // 获取 Redis 发布/订阅实例// 订阅频道 "mychannel"sub.Subscribe("mychannel", (channel, message) =>{// 当收到消息时,打印消息内容Console.WriteLine($"Received message: {message}");});// 发布 5 条消息到频道 "mychannel"for (int i = 0; i < 5; i++){sub.Publish("mychannel", $"Hello, Redis! {i}"); // 发布消息// 等待 1 秒再发布下一条消息System.Threading.Thread.Sleep(1000);}// 关闭 Redis 连接redis.Close();}
}

代码详解

  1. 定义 Redis 连接和数据库实例

    private static ConnectionMultiplexer redis;
    private static IDatabase db;
    
    • ConnectionMultiplexer redis: 用于管理 Redis 连接。
    • IDatabase db: 用于执行 Redis 数据库操作。
  2. 连接到 Redis 服务器

    redis = ConnectionMultiplexer.Connect("localhost");
    db = redis.GetDatabase();
    ISubscriber sub = redis.GetSubscriber();
    
    • ConnectionMultiplexer.Connect("localhost"): 连接到本地运行的 Redis 服务器。
    • redis.GetDatabase(): 获取 Redis 数据库实例。
    • redis.GetSubscriber(): 获取 Redis 发布/订阅实例。
  3. 订阅频道 "mychannel"

    sub.Subscribe("mychannel", (channel, message) =>
    {Console.WriteLine($"Received message: {message}");
    });
    
    • sub.Subscribe("mychannel", ...):订阅频道 "mychannel"。
    • 当收到消息时,匿名委托 (channel, message) => { ... } 会被调用,打印消息内容。
  4. 发布消息到频道 "mychannel"

    for (int i = 0; i < 5; i++)
    {sub.Publish("mychannel", $"Hello, Redis! {i}");System.Threading.Thread.Sleep(1000);
    }
    
    • 使用 for 循环发布 5 条消息。
    • sub.Publish("mychannel", ...):发布消息到频道 "mychannel"。
    • System.Threading.Thread.Sleep(1000):每次发布后等待 1 秒。
  5. 关闭 Redis 连接

    redis.Close();
    • redis.Close():关闭 Redis 连接。

 

在这个示例中,我们使用 Subscribe 方法订阅了一个频道,并通过 Publish 方法发布消息。

分布式锁

下面展示了如何使用 Redis 实现分布式锁:

using System;
using StackExchange.Redis;public class RedisLock
{// 定义 Redis 数据库实例、锁的键、锁的值及锁的超时时间private readonly IDatabase db;private readonly string lockKey;private readonly string lockValue;private readonly TimeSpan lockTimeout;/// <summary>/// 构造函数,初始化 RedisLock 实例/// </summary>/// <param name="db">Redis 数据库实例</param>/// <param name="lockKey">锁的键</param>/// <param name="lockTimeout">锁的超时时间</param>public RedisLock(IDatabase db, string lockKey, TimeSpan lockTimeout){this.db = db; // 设置 Redis 数据库实例this.lockKey = lockKey; // 设置锁的键this.lockValue = Guid.NewGuid().ToString(); // 生成一个唯一的锁值this.lockTimeout = lockTimeout; // 设置锁的超时时间}/// <summary>/// 尝试获取锁/// </summary>/// <returns>如果成功获取锁,返回 true;否则返回 false</returns>public bool Acquire(){// 尝试设置锁的键和值,并指定超时时间,只有键不存在时才能设置成功return db.StringSet(lockKey, lockValue, lockTimeout, When.NotExists);}/// <summary>/// 释放锁/// </summary>/// <returns>如果成功释放锁,返回 true;否则返回 false</returns>public bool Release(){// 只有当前实例持有的锁值与 Redis 中存储的锁值相同时,才删除锁if (db.StringGet(lockKey) == lockValue){return db.KeyDelete(lockKey); // 删除锁的键}return false;}
}// 使用示例
class Program
{static void Main(string[] args){// 连接到 Redis 服务器var redis = ConnectionMultiplexer.Connect("localhost"); // 这里假设 Redis 运行在本地var db = redis.GetDatabase(); // 获取 Redis 数据库实例// 创建 RedisLock 实例,指定锁的键和超时时间var redisLock = new RedisLock(db, "mylock", TimeSpan.FromSeconds(30));// 尝试获取锁if (redisLock.Acquire()){Console.WriteLine("Lock acquired");// 执行需要锁保护的代码System.Threading.Thread.Sleep(5000); // 模拟需要锁保护的代码执行// 释放锁redisLock.Release();Console.WriteLine("Lock released");}else{Console.WriteLine("Failed to acquire lock");}// 关闭 Redis 连接redis.Close();}
}

在这个示例中,我们使用 StringSet 方法和 When.NotExists 条件来实现分布式锁的获取,使用 KeyDelete 方法来释放锁。

事务操作

Redis 支持事务操作,可以通过 IDatabase.CreateTransaction 方法来创建一个事务,并通过 ITransaction.Execute 方法来执行事务。下面是一个事务操作的示例:

using System;
using StackExchange.Redis;class Program
{static void Main(string[] args){// 连接到 Redis 服务器var redis = ConnectionMultiplexer.Connect("localhost"); // 这里假设 Redis 运行在本地var db = redis.GetDatabase(); // 获取 Redis 数据库实例// 创建一个事务var tran = db.CreateTransaction();// 在事务中设置键值对tran.StringSetAsync("key1", "value1");tran.StringSetAsync("key2", "value2");// 提交事务bool committed = tran.Execute();// 检查事务是否成功提交if (committed){Console.WriteLine("Transaction committed");}else{Console.WriteLine("Transaction failed");}// 关闭 Redis 连接redis.Close();}
}

在这个示例中,我们在事务中设置了两个键值对,并通过 Execute 方法提交事务。

四、结论

        通过上面的讲解和示例,我们深入了解了 C# 中使用 StackExchange.Redis 进行 Redis 操作的基本概念、原理、作用、应用场景及具体应用实例。Redis 作为一个高性能的内存数据库,广泛应用于各种场景中,而 StackExchange.Redis 则提供了一个强大且易用的 API,可以帮助我们在 C# 项目中方便地使用 Redis。

        通过合理利用 Redis 的强大功能,可以大幅提升系统的性能和稳定性,希望本文能对你在 C# 项目中使用 Redis 提供一些帮助和参考。

 

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【Android Studio】API 29(即Android 10)或更高版本,在程序启动时检查相机权限,并在未获取该权限时请求它
  • 道路检测-目标检测数据集(包括VOC格式、YOLO格式)
  • Windows与Linux下 SDL2的第一个窗口程序
  • 【开发语言】写程序的两大基本原则(PO和NT原则)
  • 基于STM32设计的智能货架(华为云IOT)(225)
  • 【重学 MySQL】二十九、函数的理解
  • 神经网络通俗理解学习笔记(3)注意力神经网络
  • Html css水平居中+垂直居中+水平垂直居中的方法总结
  • 解决tiktoken库调用get_encoding时SSL超时
  • IP纯净度对跨境电商有哪些影响
  • 【VMvare虚拟机-Ubuntu】解决内存不足问题
  • Linux bash 关联数组
  • 解锁定位服务:Flutter应用中的高德地图定位
  • Python 数据类型详解:列表、字典、元组与集合的操作指南
  • 【Linux进程】Linux Shell编程实战:构建简易脚本示例与技巧详解
  • (三)从jvm层面了解线程的启动和停止
  • 【mysql】环境安装、服务启动、密码设置
  • 【从零开始安装kubernetes-1.7.3】2.flannel、docker以及Harbor的配置以及作用
  • angular2开源库收集
  • javascript 哈希表
  • JavaScript设计模式系列一:工厂模式
  • jquery cookie
  • LeetCode刷题——29. Divide Two Integers(Part 1靠自己)
  • Median of Two Sorted Arrays
  • Octave 入门
  • Python爬虫--- 1.3 BS4库的解析器
  • storm drpc实例
  • 阿里云应用高可用服务公测发布
  • 从输入URL到页面加载发生了什么
  • 官方新出的 Kotlin 扩展库 KTX,到底帮你干了什么?
  • 人脸识别最新开发经验demo
  • 树莓派 - 使用须知
  • 探索 JS 中的模块化
  • 主流的CSS水平和垂直居中技术大全
  • ​LeetCode解法汇总1410. HTML 实体解析器
  • ###项目技术发展史
  • #《AI中文版》V3 第 1 章 概述
  • #include<初见C语言之指针(5)>
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (二)pulsar安装在独立的docker中,python测试
  • (翻译)terry crowley: 写给程序员
  • (附源码)springboot青少年公共卫生教育平台 毕业设计 643214
  • (强烈推荐)移动端音视频从零到上手(下)
  • (一)搭建springboot+vue前后端分离项目--前端vue搭建
  • (原創) 如何將struct塞進vector? (C/C++) (STL)
  • (转)机器学习的数学基础(1)--Dirichlet分布
  • (自适应手机端)行业协会机构网站模板
  • .cn根服务器被攻击之后
  • .Net Core和.Net Standard直观理解
  • .NET 设计模式初探
  • .NET轻量级ORM组件Dapper葵花宝典
  • .NET项目中存在多个web.config文件时的加载顺序
  • .sys文件乱码_python vscode输出乱码
  • [ C++ ] 继承
  • [ Linux ] git工具的基本使用(仓库的构建,提交)