一、环境准备
1. 安装 Redis 服务器
- Windows/macOS/Linux:使用 Docker 快速部署
bash
docker run -d --name redis -p 6379:6379 redis
- Linux:直接安装
bash
sudo apt-get install redis-server sudo systemctl start redis-server
2. 创建 .NET 项目
bash
dotnet new console -n RedisTutorial
cd RedisTutorial
3. 安装 NuGet 包
bash
dotnet add package StackExchange.Redis
二、基础操作:连接与数据读写
1. 连接 Redis
csharp
using StackExchange.Redis;
class Program
{
static void Main()
{
// 连接到本地 Redis
using var redis = ConnectionMultiplexer.Connect("localhost:6379");
IDatabase db = redis.GetDatabase();
Console.WriteLine("Redis 连接成功!");
}
}
2. 基本数据类型操作
字符串(String)
csharp
// 写入
db.StringSet("name", "John Doe");
// 读取
string name = db.StringGet("name");
Console.WriteLine($"Name: {name}");
// 自增计数
db.StringIncrement("counter");
哈希(Hash)
csharp
// 写入
db.HashSet("user:1", new HashEntry[] {
new HashEntry("age", 30),
new HashEntry("email", "john@example.com")
});
// 读取
string email = db.HashGet("user:1", "email");
列表(List)
csharp
// 左侧插入
db.ListLeftPush("tasks", "task1");
db.ListLeftPush("tasks", "task2");
// 获取列表
RedisValue[] tasks = db.ListRange("tasks");
集合(Set)
csharp
// 添加元素
db.SetAdd("tags", new RedisValue[] { "C#", ".NET", "Redis" });
// 判断元素是否存在
bool hasDotNet = db.SetContains("tags", ".NET");
三、进阶操作:过期时间与事务
1. 设置 Key 过期时间
csharp
// 写入时设置 10 分钟过期
db.StringSet("cache:data", "value", TimeSpan.FromMinutes(10));
// 为已存在的 key 设置过期
db.KeyExpire("counter", TimeSpan.FromHours(1));
// 检查剩余过期时间
TimeSpan? ttl = db.KeyTimeToLive("cache:data");
2. 事务操作
csharp
var transaction = db.CreateTransaction();
// 批量操作
transaction.StringSetAsync("key1", "value1");
transaction.StringSetAsync("key2", "value2");
// 执行事务
bool committed = await transaction.ExecuteAsync();
四、高级特性:发布订阅与分布式锁
1. 发布订阅(Pub/Sub)
发布者:
csharp
var subscriber = redis.GetSubscriber();
subscriber.Publish("news", "Hello, Redis!");
订阅者:
csharp
var subscriber = redis.GetSubscriber();
subscriber.Subscribe("news", (channel, message) => {
Console.WriteLine($"收到消息: {message}");
});
2. 分布式锁
csharp
// 获取锁(尝试 10 秒,持有 30 秒)
bool locked = db.LockTake("resource:lock", Environment.MachineName, TimeSpan.FromSeconds(30));
if (locked)
{
try
{
// 执行临界区代码
}
finally
{
// 释放锁
db.LockRelease("resource:lock", Environment.MachineName);
}
}
五、连接配置最佳实践
1. 配置连接选项
csharp
var options = ConfigurationOptions.Parse("localhost:6379");
options.AbortOnConnectFail = false;
options.ConnectRetry = 3;
options.SyncTimeout = 5000; // 5 秒超时
using var redis = ConnectionMultiplexer.Connect(options);
2. 连接池管理
csharp
// 使用连接池(根据并发量调整大小)
options.PoolSize = 50;
六、实战案例:缓存实现
1. 缓存优先模式
csharp
string GetDataFromCache(string key)
{
// 1. 先从缓存获取
string cacheData = db.StringGet(key);
if (!string.IsNullOrEmpty(cacheData))
{
return cacheData;
}
// 2. 缓存未命中,从数据库获取
string dbData = FetchFromDatabase(key);
// 3. 写入缓存(设置 5 分钟过期)
db.StringSet(key, dbData, TimeSpan.FromMinutes(5));
return dbData;
}
2. 缓存失效策略
csharp
// 主动更新缓存
async Task RefreshCache(string key)
{
string newData = FetchFromDatabase(key);
await db.StringSetAsync(key, newData, TimeSpan.FromMinutes(5));
}
七、性能优化与监控
1. 性能优化技巧
- 使用异步方法(如
StringSetAsync
) - 批量操作(Batch/Transaction)
- 合理设置超时参数
- 使用连接池
2. 监控 Redis
csharp
// 获取服务器信息
var server = redis.GetServer("localhost", 6379);
var info = server.Info();
// 打印内存使用情况
Console.WriteLine($"内存使用: {info["memory"]["used_memory_human"]}");
八、常见问题处理
1. 连接超时
- 增加
ConnectTimeout
和SyncTimeout
- 检查 Redis 服务器负载
2. 缓存穿透
- 缓存空值:
csharp
if (dbData == null) { db.StringSet(key, "", TimeSpan.FromMinutes(1)); // 短暂缓存空值 }
3. 缓存雪崩
- 为不同 key 设置随机过期时间:
csharp
var randomExpiry = TimeSpan.FromMinutes(5 + new Random().Next(10)); db.StringSet(key, value, randomExpiry);