一、概念与简介:
-
管道(Pipeline)的使用:
- 使用
CreateBatch
方法创建一个批处理对象。 - 将多个操作添加到批处理中,然后执行批处理以提高性能。
- 使用
-
发布-订阅模式(Pub/Sub)的实现:
- 使用
GetSubscriber
方法获取订阅者对象。 - 使用
PublishAsync
方法发布消息。 - 使用
SubscribeAsync
方法订阅频道并处理接收到的消息。
- 使用
-
事务(Transaction)的应用:
- 使用
CreateTransaction
方法创建一个事务对象。 - 将多个操作添加到事务中,然后执行事务以确保原子性。
- 使用
-
分布式锁的实现:
- 使用
LockTakeAsync
方法尝试获取锁。 - 在获取锁后执行关键操作,并使用
LockReleaseAsync
方法释放锁。
- 使用
二、高级用法实践
1、首先,在你的 ASP.NET Core 项目中安装 StackExchange.Redis
包:
dotnet add package StackExchange.Redis
2、在Program.cs文件,配置redis服务接口
//注册redis 服务连接接口IConnectionMultiplexer
builder.Services.AddSingleton<IConnectionMultiplexer>(c =>
{return ConnectionMultiplexer.Connect(builder.Configuration.GetConnectionString("Redis")??"localhost:6379");
});
3、appsetting.json文件,配置redis连接串
"ConnectionStrings": {"Redis": "localhost:6379"
},
4、新增RedisServices.cs文件,实现高级用法
public class RedisServices
{private readonly IConnectionMultiplexer _redis;public RedisServices(IConnectionMultiplexer redis){_redis = redis;}/// <summary>/// redis 管道用法/// </summary>/// <returns></returns>public async Task UsePipelineAsync(){var db = _redis.GetDatabase(3);var batch = db.CreateBatch();var tasks = new List<Task>();for (int i = 0;i<100;i++){_=batch.StringSetAsync($"key{i}", $"value{i}", TimeSpan.FromMinutes(1));//tasks.Add(batch.StringSetAsync($"key{i}",$"value{i}",TimeSpan.FromMinutes(1)));}batch.Execute();//await Task.WhenAll(tasks);await Console.Out.WriteLineAsync("Pipeline execution completed.");}/// <summary>/// redis 发布订阅用法:发布/// </summary>/// <param name="channel"></param>/// <param name="message"></param>/// <returns></returns>public async Task PublishAsync(RedisChannel channel,string message){ var subscriber = _redis.GetSubscriber();await subscriber.PublishAsync(channel, message);Console.WriteLine($"Message '{message}' published to channel '{channel}'.");}//订阅public async Task SubscriberAsync(RedisChannel channel){var subscriber = _redis.GetSubscriber();await subscriber.SubscribeAsync(channel, (ch,msg) => {Console.WriteLine($"Received message '{msg}' from channel '{ch}'.");});}/// <summary>/// redis 事务用法/// </summary>/// <returns></returns>public async Task UseTransactionAsync(){var db = _redis.GetDatabase(3);var trans = db.CreateTransaction();_=trans.StringSetAsync("key1", "new_value1");_=trans.StringSetAsync("keyk", "new_valuek");bool committed = await trans.ExecuteAsync();Console.WriteLine($"Transaction committed: {committed}");}/// <summary>/// redis 分布式锁用法/// </summary>/// <param name="lockkey"></param>/// <returns></returns>public async Task UseDistributedLockAsync(string lockkey){var db = _redis.GetDatabase(3);string lockvalue = Guid.NewGuid().ToString();TimeSpan expiry = TimeSpan.FromMinutes(1);bool acquired = await db.LockTakeAsync(lockkey,lockvalue,expiry);if (acquired){try{Console.WriteLine("Lock acquired, performing critical operation...");// Perform critical operation here}finally{await db.LockReleaseAsync(lockkey,lockvalue);Console.WriteLine("Lock released.");}}else{Console.WriteLine("Failed to acquire lock.");}}public async Task<bool> GetRedisLock(){var db = _redis.GetDatabase(3);string lockkey = "_redisLock_";string lockvalue = Guid.NewGuid().ToString();TimeSpan expiry = TimeSpan.FromMinutes(1);return await db.LockTakeAsync(lockkey, lockvalue, expiry);}
}
5、注册RedisServices
//注册redis高级用法builder.RegisterType<RedisServices>();
6、新建RedisController.cs
[Route("api/[controller]")]
[ApiController]
public class RedisController : ControllerBase
{private readonly Repository.IRepository<Product> _repository;private readonly RedisServices _redisServices;public RedisController(Repository.IRepository<Product> repository,RedisServices redisServices){_repository = repository;_redisServices = redisServices;}//测试redis高级用法[Route("UseRedis")][HttpPost]public async Task<ActionResult> UseRedis(){//管道await _redisServices.UsePipelineAsync();//在 Redis 的发布/订阅(Pub/Sub)模式下,消息是即时传递的,这意味着消息只会发送给当前在线的订阅者。//如果在发布消息时没有任何订阅者,那么这些消息将会丢失。因此,如果你在发布消息之后才开始订阅,之前发布的消息将不会被接收到。RedisChannel channel = new("mychannel",RedisChannel.PatternMode.Literal);await _redisServices.SubscriberAsync(channel);//先订阅await _redisServices.PublishAsync(channel, "hello redis!");//再发布//事务await _redisServices.UseTransactionAsync();//分布式锁await _redisServices.UseDistributedLockAsync("distributeLock");for (int i = 0;i<5000; i++){bool acquired = await _redisServices.GetRedisLock();if (acquired){await Console.Out.WriteLineAsync($"第{i}次请求获取锁成功,并执行成功");}else{Thread.Sleep(1000);}}return Ok();}
}
三、代码详解
1、IConnectionMultiplexer
接口
IConnectionMultiplexer
是 StackExchange.Redis
库中的一个接口,代表了与 Redis 服务器的连接。它是使用 StackExchange.Redis
与 Redis 进行交互的核心组件。
作用
-
管理连接:
IConnectionMultiplexer
管理与 Redis 服务器的所有连接,包括连接池、连接复用等。 -
提供数据库操作接口:通过
GetDatabase
方法获取IDatabase
对象,用于执行各种 Redis 命令。 -
发布-订阅功能:通过
GetSubscriber
方法获取ISubscriber
对象,用于实现发布-订阅模式。 -
服务器管理:通过
GetServer
方法获取IServer
对象,用于执行服务器级别的命令,如清空数据库、查看键空间等。 -
配置和监控:可以获取连接的配置信息,并提供一些监控和诊断功能
2. 基于Redis的分布式锁
Redis提供了一种高效的分布式锁实现方式,通常使用 SETNX
命令(Set if Not Exists)和 EXPIRE
命令(设置过期时间)来实现。
- 获取锁:使用
SETNX
命令尝试设置一个键,如果键不存在则设置成功并返回1,否则返回0。然后使用EXPIRE
命令为该键设置一个过期时间,以防止死锁。 - 释放锁:删除该键即可释放锁。
3. 数据结构
Redis 支持多种数据结构,每种结构都有其特定的应用场景:
- 字符串(String):最基本的数据类型,可以存储任何形式的字符串,包括二进制数据。
- 哈希(Hash):适合存储对象,类似于 Python 的字典。
- 列表(List):有序集合,支持从两端进行操作,适合实现队列和栈。
- 集合(Set):无序集合,自动去重,适合做交集、并集、差集运算。
- 有序集合(Sorted Set):带权重的集合,元素有序排列,适合排行榜等场景。
四、总结
Redis 作为一个高性能的内存数据结构存储系统,具有许多优点,使其在各种应用场景中广受欢迎。以下是 Redis 的一些主要优点:
1. 高性能
-
低延迟:由于数据存储在内存中,读写操作非常快速,通常在毫秒级别。
-
高吞吐量:支持每秒数十万次的读写操作,非常适合高并发场景。
2. 丰富的数据结构
-
支持字符串、哈希、列表、集合、有序集合、位图(Bitmaps)、HyperLogLog 和地理位置(GEO)等多种数据结构,满足不同的应用需求。
3. 持久化
-
提供 RDB(快照)和 AOF(追加日志)两种持久化机制,可以根据需要选择合适的方式来保证数据的持久性。
4. 主从复制
-
支持主从复制,一个主节点可以有多个从节点,从节点可以分担读请求,提高系统的可用性和扩展性。
5. 高可用和自动故障转移
-
通过 Redis Sentinel 实现高可用性监控和自动故障转移,确保系统在节点故障时仍能正常运行。
-
Redis Cluster 提供了分布式解决方案,支持数据分片和自动故障转移,实现水平扩展。
6. 灵活的发布/订阅机制
-
支持发布/订阅模式,可以用于实时消息传递、通知系统等场景。
7. 脚本支持
-
内置 Lua 脚本支持,通过 EVAL 命令执行脚本,实现复杂的原子操作。
8. 缓存功能
-
提供多种缓存淘汰策略,如 LRU、LFU 等,可以根据需求选择合适的策略,优化内存使用。
9. 管道技术
-
支持管道技术,一次性发送多个命令,减少网络延迟,提高性能。
10. 易于使用
-
简单易懂的命令集和丰富的客户端库,支持多种编程语言,方便开发者快速上手。
11. 社区和生态系统
-
拥有活跃的开源社区和丰富的生态系统,提供了大量的工具和扩展,方便集成和管理。
12. 安全性
-
支持基于密码的访问控制和 SSL/TLS 加密通信,增强数据传输的安全性。
这些优点使得 Redis 成为一个强大且灵活的内存数据库,广泛应用于缓存、会话管理、实时分析、消息队列等各种场景。