secra-cache 0.1.4

一个基于 Redis 的统一缓存管理库,专为插件化架构设计,提供强隔离、生命周期管理和极简 API
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
# Secra Cache

一个基于 Redis 的统一缓存管理库,专为插件化架构设计,提供强隔离、生命周期管理和极简 API。

## 📋 目录

- [功能特性]#功能特性
- [快速开始]#快速开始
- [安装]#安装
- [使用文档]#使用文档
  - [基座系统集成]#基座系统集成
  - [插件使用]#插件使用
  - [API 参考]#api-参考
- [Key 格式规范]#key-格式规范
- [配置说明]#配置说明
- [错误处理]#错误处理
- [最佳实践]#最佳实践
- [设计文档]#设计文档

## ✨ 功能特性

- **统一治理**:所有缓存操作必须通过 `CacheManager`,插件不能直接访问 Redis
- **强隔离**:每个插件拥有独立的命名空间,避免 Key 冲突
- **生命周期管理**:插件卸载/升级时自动清理相关缓存
- **极简 API**:插件侧 API 简单易用,隐藏 Redis 细节
- **可扩展性**:支持未来扩展(配额、监控、限流等)
- **异步支持**:基于 Tokio 异步运行时,高性能
- **类型安全**:利用 Rust 类型系统,编译时保证安全

## 🚀 快速开始

### 安装

在 `Cargo.toml` 中添加依赖:

```toml
[dependencies]
secra-cache = { version = "0.1.2", features = ["rustis"] }
```

### 运行示例

项目提供了一个完整的示例,展示所有主要功能:

```bash
# 确保 Redis 服务正在运行(默认 localhost:6379)
# 或设置环境变量指定 Redis 地址
export REDIS_URL="redis://localhost:6379"

# 运行示例
cargo run --example basic_demo
```

示例演示了以下功能:
- 创建 CacheManager 和插件缓存实例
- 基本缓存操作(set、get、delete、exists)
- TTL 管理(设置、查询、延长过期时间)
- 循环操作(模拟批量操作)
- 模块化缓存管理
- 插件生命周期管理
- Redis 连接健康检查
- 错误处理

### 基本使用

#### 基座系统

```rust
use secra_cache::CacheManager;

// 1. 创建 CacheManager
let cache_manager = CacheManager::new_with_defaults(
    "redis://localhost:6379",
).await?;

// 或者:传入已创建的 Redis client
// let client = rustis::client::Client::connect("redis://localhost:6379").await?;
// let cache_manager = CacheManager::new_with_client_defaults(client).await?;

// 2. 为插件创建 Cache 实例
let plugin_cache = cache_manager.create_plugin_cache("user_plugin".to_string());
```

#### 插件代码

```rust
use secra_cache::Cache;
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct User {
    id: u64,
    name: String,
}

// 1. 设置缓存
let user = User {
    id: 123,
    name: "Alice".to_string(),
};
plugin_cache.set("user:123", &user, None).await?;

// 2. 获取缓存
let user: Option<User> = plugin_cache.get("user:123").await?;

// 3. 删除缓存
plugin_cache.delete("user:123").await?;

// 4. 检查缓存是否存在
let exists = plugin_cache.exists("user:123").await?;

// 5. 清理所有缓存
plugin_cache.clear().await?;

// 6. 按模块清理缓存
plugin_cache.clear_module("user").await?; // 清理 user 模块的所有缓存
```

## 📖 使用文档

### 基座系统集成

基座系统负责创建和管理 `CacheManager` 实例,并为每个插件创建独立的缓存实例。

#### 创建 CacheManager

```rust
use secra_cache::{CacheManager, CacheConfig};

// 方式 1: 使用默认配置
let cache_manager = CacheManager::new_with_defaults(
    "redis://localhost:6379"
).await?;

// 方式 1.1: 传入已创建的 Redis client(默认配置)
// let client = rustis::client::Client::connect("redis://localhost:6379").await?;
// let cache_manager = CacheManager::new_with_client_defaults(client).await?;

// 方式 2: 使用自定义配置
let config = CacheConfig {
    redis_url: "redis://localhost:6379".to_string(),
    key_prefix: "secra".to_string(),
    default_ttl: Some(3600), // 默认 TTL 1 小时
    // ... 其他配置
};
let cache_manager = CacheManager::new(config).await?;

// 方式 2.1: 传入已创建的 Redis client(自定义配置)
// let client = rustis::client::Client::connect("redis://localhost:6379").await?;
// let cache_manager = CacheManager::new_with_client(client, config).await?;
```

#### 为插件创建缓存实例

```rust
// 为插件创建缓存实例
let plugin_cache = cache_manager.create_plugin_cache("user_plugin".to_string());

// 插件卸载时,清理该插件的所有缓存
cache_manager.remove_plugin_cache("user_plugin").await?;
```

### 插件使用

插件通过 `Cache` trait 提供的 API 进行缓存操作,无需关心 Redis 细节。

#### 基本操作

```rust
use secra_cache::Cache;
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize, Clone, Debug)]
struct Product {
    id: u64,
    name: String,
    price: f64,
}

// 设置缓存(无 TTL)
let product = Product {
    id: 1,
    name: "iPhone".to_string(),
    price: 9999.0,
};
cache.set("product:1", &product, None).await?;

// 设置缓存(带 TTL,单位:秒)
cache.set("product:1", &product, Some(3600)).await?;

// 获取缓存
match cache.get::<Product>("product:1").await? {
    Some(product) => println!("找到产品: {:?}", product),
    None => println!("缓存未命中"),
}

// 删除缓存
cache.delete("product:1").await?;

// 检查缓存是否存在
if cache.exists("product:1").await? {
    println!("缓存存在");
}
```

#### 批量操作

```rust
// 批量设置
let mut items = Vec::new();
items.push(("key1", "value1"));
items.push(("key2", "value2"));
cache.set_many(&items, Some(3600)).await?;

// 批量获取
let keys = vec!["key1", "key2"];
let values: Vec<Option<String>> = cache.get_many(&keys).await?;

// 批量删除
cache.delete_many(&keys).await?;
```

#### 模块化缓存管理

```rust
// 按模块设置缓存(推荐)
cache.set("user:123", &user, None).await?;      // user 模块
cache.set("order:456", &order, None).await?;    // order 模块

// 清理特定模块的所有缓存
cache.clear_module("user").await?;  // 只清理 user 模块的缓存

// 清理所有缓存
cache.clear().await?;  // 清理该插件的所有缓存
```

#### TTL 管理

```rust
// 设置 TTL
cache.set_ttl("key", 3600).await?;

// 获取剩余 TTL(秒)
let ttl = cache.get_ttl("key").await?;
match ttl {
    Some(seconds) => println!("剩余 TTL: {} 秒", seconds),
    None => println!("Key 不存在或没有设置 TTL"),
}

// 移除 TTL(使 Key 永久有效)
cache.remove_ttl("key").await?;
```

## 🔑 Key 格式规范

所有 Redis Key 必须遵循以下格式:

```
{system}:{plugin_id}:{biz}:{key}
```

### 格式说明

- `{system}`: 系统前缀,默认 `secra`,可通过配置修改
- `{plugin_id}`: 插件 ID,由基座系统传入
- `{biz}`: 业务模块标识,建议使用业务领域名称(如 `user``order`- `{key}`: 具体的缓存键

### 示例

```
secra:user_plugin:user:123
secra:order_service:order:2024:001
secra:payment_plugin:payment:txn:abc123
```

### 命名建议

- **业务模块** (`biz`):使用小写字母和下划线,如 `user_profile``order_list`
- **缓存键** (`key`):使用有意义的标识符,如用户 ID、订单号等
- **避免冲突**:不同业务模块使用不同的 `biz` 前缀

## ⚙️ 配置说明

### CacheConfig

```rust
use secra_cache::CacheConfig;

let config = CacheConfig {
    redis_url: "redis://localhost:6379".to_string(),
    key_prefix: "secra".to_string(),           // Key 前缀
    default_ttl: Some(3600),                   // 默认 TTL(秒),None 表示永久
    connection_timeout: Some(5000),            // 连接超时(毫秒)
    // ... 其他配置项
};
```

### 环境变量支持

可以通过环境变量配置 Redis 连接:

```bash
export REDIS_URL="redis://localhost:6379"
export REDIS_KEY_PREFIX="secra"
export REDIS_DEFAULT_TTL="3600"
```

## 🛠️ API 参考

### Cache Trait

`Cache` trait 定义了插件可用的所有缓存操作:

```rust
#[async_trait]
pub trait Cache: Send + Sync {
    /// 设置缓存
    async fn set<T: Serialize + Send + Sync>(
        &self,
        key: &str,
        value: &T,
        ttl: Option<u64>,
    ) -> Result<(), CacheError>;

    /// 获取缓存
    async fn get<T: DeserializeOwned + Send + Sync>(
        &self,
        key: &str,
    ) -> Result<Option<T>, CacheError>;

    /// 删除缓存
    async fn delete(&self, key: &str) -> Result<(), CacheError>;

    /// 检查缓存是否存在
    async fn exists(&self, key: &str) -> Result<bool, CacheError>;

    /// 设置 TTL
    async fn set_ttl(&self, key: &str, ttl: u64) -> Result<(), CacheError>;

    /// 获取剩余 TTL
    async fn get_ttl(&self, key: &str) -> Result<Option<u64>, CacheError>;

    /// 移除 TTL
    async fn remove_ttl(&self, key: &str) -> Result<(), CacheError>;

    /// 批量设置
    async fn set_many<T: Serialize + Send + Sync>(
        &self,
        items: &[(&str, &T)],
        ttl: Option<u64>,
    ) -> Result<(), CacheError>;

    /// 批量获取
    async fn get_many<T: DeserializeOwned + Send + Sync>(
        &self,
        keys: &[&str],
    ) -> Result<Vec<Option<T>>, CacheError>;

    /// 批量删除
    async fn delete_many(&self, keys: &[&str]) -> Result<(), CacheError>;

    /// 清理所有缓存
    async fn clear(&self) -> Result<(), CacheError>;

    /// 清理指定模块的缓存
    async fn clear_module(&self, module: &str) -> Result<(), CacheError>;
}
```

### CacheManager

```rust
impl CacheManager {
    /// 创建 CacheManager(使用默认配置)
    pub async fn new_with_defaults(redis_url: &str) -> Result<Self, CacheError>;

    /// 创建 CacheManager(使用自定义配置)
    pub fn new(config: CacheConfig) -> Result<Self, CacheError>;

    /// 为插件创建缓存实例
    pub fn create_plugin_cache(&self, plugin_id: String) -> PluginCache;

    /// 移除插件缓存(清理该插件的所有缓存)
    pub async fn remove_plugin_cache(&self, plugin_id: &str) -> Result<(), CacheError>;
}
```

## ❌ 错误处理

### CacheError

所有操作可能返回 `CacheError`:

```rust
use secra_cache::CacheError;

match cache.get::<User>("user:123").await {
    Ok(Some(user)) => println!("找到用户: {:?}", user),
    Ok(None) => println!("缓存未命中"),
    Err(CacheError::RedisError(e)) => eprintln!("Redis 错误: {}", e),
    Err(CacheError::SerializationError(e)) => eprintln!("序列化错误: {}", e),
    Err(e) => eprintln!("其他错误: {}", e),
}
```

### 错误类型

- `RedisError`: Redis 连接或操作错误
- `SerializationError`: 序列化/反序列化错误
- `InvalidKeyError`: Key 格式错误
- `TimeoutError`: 操作超时

## 💡 最佳实践

### 1. 使用模块化 Key 设计

```rust
// ✅ 推荐:使用模块前缀
cache.set("user:123", &user, None).await?;
cache.set("user:profile:123", &profile, None).await?;
cache.set("order:456", &order, None).await?;

// ❌ 不推荐:扁平化 Key
cache.set("123", &user, None).await?;
cache.set("456", &order, None).await?;
```

### 2. 合理设置 TTL

```rust
// 根据数据特性设置 TTL
cache.set("user:123", &user, Some(3600)).await?;        // 用户数据:1 小时
cache.set("hot_news:1", &news, Some(300)).await?;       // 热点新闻:5 分钟
cache.set("config:app", &config, None).await?;          // 配置数据:永久
```

### 3. 使用批量操作提高性能

```rust
// ✅ 推荐:批量操作
let keys = vec!["user:1", "user:2", "user:3"];
let users: Vec<Option<User>> = cache.get_many(&keys).await?;

// ❌ 不推荐:循环单个操作
for key in keys {
    let user = cache.get::<User>(key).await?;
    // ...
}
```

### 4. 插件卸载时清理缓存

```rust
// 基座系统:插件卸载时
cache_manager.remove_plugin_cache("user_plugin").await?;
```

### 5. 处理缓存未命中

```rust
match cache.get::<User>("user:123").await? {
    Some(user) => Ok(user),
    None => {
        // 从数据库加载
        let user = load_user_from_db(123).await?;
        // 写入缓存
        cache.set("user:123", &user, Some(3600)).await?;
        Ok(user)
    }
}
```

### 6. 类型安全

```rust
// ✅ 推荐:使用强类型
#[derive(Serialize, Deserialize)]
struct User { /* ... */ }
cache.set("user:123", &user, None).await?;
let user: Option<User> = cache.get("user:123").await?;

// ❌ 不推荐:使用字符串
cache.set("user:123", &user_json_string, None).await?;
```

## 📚 设计文档

详细的设计文档请参考项目文档目录(如果存在):

- `01-架构设计.md`:整体架构和调用关系
- `02-Key设计规范.md`:Key 命名规范和隔离机制
- `03-核心能力设计.md`:get/set/del/exists、TTL、序列化
- `04-生命周期管理.md`:插件卸载/升级时的缓存清理
- `05-接口设计.md`:Cache trait、CacheManager、使用示例
- `06-进阶能力.md`:批量操作、分布式锁、防穿透/雪崩
- `07-反模式与约束.md`:禁止行为和强制约束
- `08-实现指南.md`:实现步骤和最佳实践

## 🔧 依赖项

主要依赖:

- `rustis`: Redis 客户端
- `serde` / `serde_json`: 序列化/反序列化
- `tokio`: 异步运行时
- `async-trait`: 异步 trait 支持
- `dashmap`: 并发数据结构
- `tracing`: 结构化日志
- `thiserror`: 错误处理

详细依赖信息请参考 [DEPENDENCIES.md](./DEPENDENCIES.md)。

## 📝 许可证

本项目采用双重许可证:

- **MIT License** - 详见 [LICENSE-MIT]LICENSE-MIT
- **Apache License 2.0** - 详见 [LICENSE-APACHE]LICENSE-APACHE

您可以选择任一许可证使用本项目。

## 🤝 贡献

欢迎提交 Issue 和 Pull Request!

## 📞 联系方式

- **项目仓库**: [https://github.com/secra/secra-cache]https://github.com/secra/secra-cache
- **问题反馈**: 请在 GitHub Issues 中提交