mm_redis 1.4.2 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +379 -0
- package/index.js +2021 -382
- package/package.json +33 -33
- package/test.js +83 -87
- package/index_new.js +0 -585
- package/test2.js +0 -22
package/README.md
ADDED
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
# mm_redis
|
|
2
|
+
|
|
3
|
+
mm_redis是一个高效的Redis客户端封装库,提供了全面的Redis功能支持,包括连接池管理、数据类型操作、错误处理和批量操作优化。
|
|
4
|
+
|
|
5
|
+
## 版本信息
|
|
6
|
+
|
|
7
|
+
- **当前版本**: 1.7.0
|
|
8
|
+
- **更新日期**: 2024-10-07
|
|
9
|
+
- **作者**: 邱文武
|
|
10
|
+
|
|
11
|
+
## 功能特性
|
|
12
|
+
|
|
13
|
+
- 完整的连接池管理,优化并发性能
|
|
14
|
+
- 支持Pipeline批量操作,提升执行效率
|
|
15
|
+
- 支持所有主要Redis数据类型:String、List、Hash等
|
|
16
|
+
- 自动重连机制,使用指数退避策略
|
|
17
|
+
- 全面的错误处理和日志记录
|
|
18
|
+
- 自动JSON序列化/反序列化
|
|
19
|
+
- 键前缀管理,支持多业务隔离
|
|
20
|
+
- 自动连接管理,无需手动维护连接状态
|
|
21
|
+
- 统一的事件系统,支持操作前后的事件监听
|
|
22
|
+
|
|
23
|
+
## 安装
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install mm_redis --save
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## 基本配置
|
|
30
|
+
|
|
31
|
+
```javascript
|
|
32
|
+
const { Redis } = require('mm_redis');
|
|
33
|
+
|
|
34
|
+
// 创建Redis实例
|
|
35
|
+
const redis = new Redis('default');
|
|
36
|
+
|
|
37
|
+
// 配置Redis连接
|
|
38
|
+
redis.setConfig({
|
|
39
|
+
// 服务器地址
|
|
40
|
+
"host": "localhost",
|
|
41
|
+
// 端口号
|
|
42
|
+
"port": 6379,
|
|
43
|
+
// 密码
|
|
44
|
+
"password": "",
|
|
45
|
+
// 数据库
|
|
46
|
+
"database": 0,
|
|
47
|
+
// 前缀
|
|
48
|
+
"prefix": "app:",
|
|
49
|
+
// 连接超时时间(ms)
|
|
50
|
+
"connect_timeout": 10000,
|
|
51
|
+
// 重试次数
|
|
52
|
+
"retry_count": 3,
|
|
53
|
+
// 重试间隔(ms)
|
|
54
|
+
"retry_delay": 1000,
|
|
55
|
+
// 连接池配置
|
|
56
|
+
"pool": {
|
|
57
|
+
"max_clients": 10, // 最大连接数
|
|
58
|
+
"min_idle": 2, // 最小空闲连接数
|
|
59
|
+
"max_idle": 5, // 最大空闲连接数
|
|
60
|
+
"idle_timeout": 30000 // 空闲超时时间(ms)
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## 使用示例
|
|
66
|
+
|
|
67
|
+
### 基本操作
|
|
68
|
+
|
|
69
|
+
```javascript
|
|
70
|
+
// 连接Redis
|
|
71
|
+
await redis.open();
|
|
72
|
+
|
|
73
|
+
// 设置缓存
|
|
74
|
+
await redis.set('user:1', { name: '张三', age: 25 }, 3600);
|
|
75
|
+
|
|
76
|
+
// 获取缓存
|
|
77
|
+
const user = await redis.get('user:1');
|
|
78
|
+
$.log.debug('[Redis] 获取用户信息:', user);
|
|
79
|
+
|
|
80
|
+
// 判断键是否存在
|
|
81
|
+
const exists = await redis.has('user:1');
|
|
82
|
+
|
|
83
|
+
// 删除缓存
|
|
84
|
+
await redis.del('user:1');
|
|
85
|
+
|
|
86
|
+
// 关闭连接
|
|
87
|
+
await redis.close();
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### 列表操作
|
|
91
|
+
|
|
92
|
+
```javascript
|
|
93
|
+
// 设置列表
|
|
94
|
+
await redis.list_set('users', ['user1', 'user2', 'user3']);
|
|
95
|
+
|
|
96
|
+
// 添加元素到列表
|
|
97
|
+
await redis.list_push('users', 'user4');
|
|
98
|
+
|
|
99
|
+
// 获取列表
|
|
100
|
+
const users = await redis.list_get('users');
|
|
101
|
+
$.log.debug('[Redis] 用户列表:', users);
|
|
102
|
+
|
|
103
|
+
// 获取列表的部分元素
|
|
104
|
+
const partialUsers = await redis.list_get('users', 0, 2);
|
|
105
|
+
|
|
106
|
+
// 清空列表
|
|
107
|
+
await redis.list_clear('users');
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Hash操作
|
|
111
|
+
|
|
112
|
+
```javascript
|
|
113
|
+
// 设置哈希字段
|
|
114
|
+
await redis.hset('user:profile:1', 'name', '张三');
|
|
115
|
+
await redis.hset('user:profile:1', 'age', 25);
|
|
116
|
+
|
|
117
|
+
// 批量设置哈希字段
|
|
118
|
+
await redis.hmset('user:profile:1', {
|
|
119
|
+
'email': 'zhangsan@example.com',
|
|
120
|
+
'phone': '13800138000'
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// 获取哈希字段
|
|
124
|
+
const name = await redis.hget('user:profile:1', 'name');
|
|
125
|
+
|
|
126
|
+
// 获取哈希的所有字段和值
|
|
127
|
+
const profile = await redis.hgetall('user:profile:1');
|
|
128
|
+
$.log.debug('[Redis] 用户资料:', profile);
|
|
129
|
+
|
|
130
|
+
// 获取哈希的所有字段名
|
|
131
|
+
const fields = await redis.hkeys('user:profile:1');
|
|
132
|
+
|
|
133
|
+
// 获取哈希的所有字段值
|
|
134
|
+
const values = await redis.hvals('user:profile:1');
|
|
135
|
+
|
|
136
|
+
// 判断哈希字段是否存在
|
|
137
|
+
const hasEmail = await redis.hexists('user:profile:1', 'email');
|
|
138
|
+
|
|
139
|
+
// 获取哈希字段数量
|
|
140
|
+
const fieldCount = await redis.hlen('user:profile:1');
|
|
141
|
+
|
|
142
|
+
// 删除哈希字段
|
|
143
|
+
await redis.hdel('user:profile:1', ['email', 'phone']);
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### 批量操作
|
|
147
|
+
|
|
148
|
+
```javascript
|
|
149
|
+
// 批量获取
|
|
150
|
+
const data = await redis.mget(['user:1', 'user:2', 'user:3']);
|
|
151
|
+
$.log.debug('[Redis] 批量获取结果:', data);
|
|
152
|
+
|
|
153
|
+
// 批量设置
|
|
154
|
+
await redis.mset({
|
|
155
|
+
'user:4': { name: '李四', age: 30 },
|
|
156
|
+
'user:5': { name: '王五', age: 35 }
|
|
157
|
+
}, 3600);
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### 使用Pipeline优化批量操作
|
|
161
|
+
|
|
162
|
+
```javascript
|
|
163
|
+
// 创建Pipeline
|
|
164
|
+
const pipeline = redis.pipeline();
|
|
165
|
+
|
|
166
|
+
// 添加多个命令
|
|
167
|
+
pipeline.set('counter:1', 100);
|
|
168
|
+
pipeline.ttl('counter:1', 3600);
|
|
169
|
+
pipeline.hset('stats:today', 'visits', 500);
|
|
170
|
+
pipeline.hset('stats:today', 'users', 100);
|
|
171
|
+
|
|
172
|
+
// 执行所有命令
|
|
173
|
+
const results = await pipeline.exec();
|
|
174
|
+
$.log.debug('[Redis] Pipeline执行结果:', results);
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### 发布订阅
|
|
178
|
+
|
|
179
|
+
```javascript
|
|
180
|
+
// 订阅频道
|
|
181
|
+
await redis.subscribe('notifications', async (message) => {
|
|
182
|
+
$.log.debug('[Redis] 收到通知:', message);
|
|
183
|
+
// 处理接收到的消息
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
// 发布消息
|
|
187
|
+
const receivedCount = await redis.publish('notifications', JSON.stringify({
|
|
188
|
+
type: 'info',
|
|
189
|
+
content: '系统更新成功'
|
|
190
|
+
}));
|
|
191
|
+
|
|
192
|
+
$.log.debug(`[Redis] 消息已发布,${receivedCount}个客户端接收`);
|
|
193
|
+
|
|
194
|
+
// 取消订阅
|
|
195
|
+
await redis.unsubscribe('notifications');
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### 事件系统
|
|
199
|
+
|
|
200
|
+
mm_redis提供了完善的事件系统,可以监听各种操作的前后事件,用于日志记录、数据修改或操作拦截。
|
|
201
|
+
|
|
202
|
+
```javascript
|
|
203
|
+
// 监听设置操作前的事件
|
|
204
|
+
redis.on('set_before', (data) => {
|
|
205
|
+
$.log.debug('[Redis] 设置缓存前:', data);
|
|
206
|
+
// 可以修改data中的值
|
|
207
|
+
// data.value = JSON.stringify(data.value);
|
|
208
|
+
// 可以通过设置data.cancel = true来取消操作
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
// 监听设置操作后的事件
|
|
212
|
+
redis.on('set_after', (data) => {
|
|
213
|
+
$.log.debug('[Redis] 设置缓存后:', data);
|
|
214
|
+
// data包含key, value, ttl, success等信息
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
// 监听设置操作的错误事件
|
|
218
|
+
redis.on('set_error', (data) => {
|
|
219
|
+
$.log.error('[Redis] 设置缓存错误:', data);
|
|
220
|
+
// data包含key, value, ttl, error等信息
|
|
221
|
+
});
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
#### 事件属性规范
|
|
225
|
+
|
|
226
|
+
所有事件都遵循统一的属性命名规范:
|
|
227
|
+
|
|
228
|
+
1. **通用属性**:
|
|
229
|
+
- `key`: 操作的键名
|
|
230
|
+
- `value`: 操作的值(替代str、fields、obj等)
|
|
231
|
+
- `ttl`: 过期时间(替代seconds)
|
|
232
|
+
- `result`: 操作结果(替代length)
|
|
233
|
+
- `success`: 操作是否成功
|
|
234
|
+
- `cancel`: 是否取消操作(仅限前置事件)
|
|
235
|
+
- `error`: 错误信息(仅限错误事件)
|
|
236
|
+
|
|
237
|
+
2. **特定属性**:
|
|
238
|
+
- `deleted`: 删除的键列表(用于del操作)
|
|
239
|
+
- `index`: 索引位置(用于setrange操作)
|
|
240
|
+
- `field`: 哈希字段名(用于hset操作)
|
|
241
|
+
|
|
242
|
+
3. **事件命名模式**:
|
|
243
|
+
- 前置事件: `${methodName}_before`
|
|
244
|
+
- 后置事件: `${methodName}_after`
|
|
245
|
+
- 错误事件: `${methodName}_error`
|
|
246
|
+
|
|
247
|
+
#### 支持的事件列表
|
|
248
|
+
|
|
249
|
+
| 操作方法 | 前置事件 | 后置事件 | 错误事件 |
|
|
250
|
+
|---------|---------|---------|--------|
|
|
251
|
+
| set | set_before | set_after | set_error |
|
|
252
|
+
| get | get_before | get_after | get_error |
|
|
253
|
+
| del | del_before | del_after | del_error |
|
|
254
|
+
| add | add_before | add_after | add_error |
|
|
255
|
+
| addInt | addInt_before | addInt_after | addInt_error |
|
|
256
|
+
| addFloat | addFloat_before | addFloat_after | addFloat_error |
|
|
257
|
+
| addStr | addStr_before | addStr_after | addStr_error |
|
|
258
|
+
| setrange | setrange_before | setrange_after | setrange_error |
|
|
259
|
+
| clear | clear_before | clear_after | clear_error |
|
|
260
|
+
| list_set | list_set_before | list_set_after | list_set_error |
|
|
261
|
+
| list_push | list_push_before | list_push_after | list_push_error |
|
|
262
|
+
| list_clear | list_clear_before | list_clear_after | list_clear_error |
|
|
263
|
+
| mset | mset_before | mset_after | mset_error |
|
|
264
|
+
| mget | mget_before | mget_after | mget_error |
|
|
265
|
+
| hset | hset_before | hset_after | hset_error |
|
|
266
|
+
| hmset | hmset_before | hmset_after | hmset_error |
|
|
267
|
+
| hdel | hdel_before | hdel_after | hdel_error |
|
|
268
|
+
| hget | hget_before | hget_after | hget_error |
|
|
269
|
+
| hgetall | hgetall_before | hgetall_after | hgetall_error |
|
|
270
|
+
|
|
271
|
+
## API文档
|
|
272
|
+
|
|
273
|
+
### 连接管理
|
|
274
|
+
|
|
275
|
+
- `setConfig(config)`: 设置Redis配置
|
|
276
|
+
- `open()`: 连接Redis
|
|
277
|
+
- `close()`: 关闭连接
|
|
278
|
+
- `isConnected()`: 检查连接状态
|
|
279
|
+
|
|
280
|
+
### 字符串操作
|
|
281
|
+
|
|
282
|
+
- `set(key, value, seconds)`: 设置缓存
|
|
283
|
+
- `get(key)`: 获取缓存
|
|
284
|
+
- `has(key)`: 判断键是否存在
|
|
285
|
+
- `del(key)`: 删除缓存
|
|
286
|
+
- `add(key, value, seconds)`: 仅当键不存在时设置缓存
|
|
287
|
+
- `ttl(key, seconds)`: 设置或获取过期时间
|
|
288
|
+
- `addInt(key, num)`: 增加整数值
|
|
289
|
+
- `addFloat(key, num)`: 增加浮点数值
|
|
290
|
+
- `addStr(key, str)`: 追加字符串
|
|
291
|
+
- `getrange(key, start, end)`: 获取字符串子串
|
|
292
|
+
- `setrange(key, index, value)`: 设置字符串子串
|
|
293
|
+
|
|
294
|
+
### 列表操作
|
|
295
|
+
|
|
296
|
+
- `list_set(key, value, seconds)`: 设置列表
|
|
297
|
+
- `list_push(key, value)`: 添加元素到列表
|
|
298
|
+
- `list_get(key, start, end)`: 获取列表
|
|
299
|
+
- `list_has(key, value)`: 判断列表中是否存在元素
|
|
300
|
+
- `list_clear(key, value)`: 清空列表或重置列表
|
|
301
|
+
|
|
302
|
+
### Hash操作
|
|
303
|
+
|
|
304
|
+
- `hset(key, field, value)`: 设置哈希字段
|
|
305
|
+
- `hmset(key, obj)`: 批量设置哈希字段
|
|
306
|
+
- `hget(key, field)`: 获取哈希字段值
|
|
307
|
+
- `hgetall(key)`: 获取哈希的所有字段和值
|
|
308
|
+
- `hkeys(key)`: 获取哈希的所有字段名
|
|
309
|
+
- `hvals(key)`: 获取哈希的所有字段值
|
|
310
|
+
- `hdel(key, fields)`: 删除哈希字段
|
|
311
|
+
- `hexists(key, field)`: 判断哈希字段是否存在
|
|
312
|
+
- `hlen(key)`: 获取哈希字段数量
|
|
313
|
+
|
|
314
|
+
### 批量操作
|
|
315
|
+
|
|
316
|
+
- `mget(keys)`: 批量获取缓存
|
|
317
|
+
- `mset(obj, seconds)`: 批量设置缓存
|
|
318
|
+
- `pipeline()`: 创建Pipeline对象进行批量操作优化
|
|
319
|
+
|
|
320
|
+
### 高级操作
|
|
321
|
+
|
|
322
|
+
- `subscribe(channel, func)`: 订阅频道
|
|
323
|
+
- `unsubscribe(channel)`: 取消订阅
|
|
324
|
+
- `publish(channel, message)`: 发布消息
|
|
325
|
+
- `clear(key)`: 清空缓存或当前数据库
|
|
326
|
+
- `sort(key, options)`: 排序
|
|
327
|
+
- `keys(pattern)`: 获取所有键名
|
|
328
|
+
|
|
329
|
+
## 连接池管理
|
|
330
|
+
|
|
331
|
+
本模块内置了高效的连接池管理,可自动处理连接的创建、回收和复用。连接池配置可在初始化时设置:
|
|
332
|
+
|
|
333
|
+
```javascript
|
|
334
|
+
{
|
|
335
|
+
"pool": {
|
|
336
|
+
"max_clients": 10, // 最大连接数
|
|
337
|
+
"min_idle": 2, // 最小空闲连接数
|
|
338
|
+
"max_idle": 5, // 最大空闲连接数
|
|
339
|
+
"idle_timeout": 30000 // 空闲超时时间(ms)
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
## 错误处理
|
|
345
|
+
|
|
346
|
+
所有方法都包含了完善的错误处理机制,并提供详细的日志输出。在发生错误时,会自动记录错误信息,并在可能的情况下提供回退方案。
|
|
347
|
+
|
|
348
|
+
## 最佳实践
|
|
349
|
+
|
|
350
|
+
1. **使用连接池**: 对于高并发应用,连接池配置至关重要,合理设置最大连接数和空闲连接数
|
|
351
|
+
2. **使用Pipeline**: 对于批量操作,使用Pipeline可显著提升性能
|
|
352
|
+
3. **合理设置过期时间**: 避免Redis中数据无限增长
|
|
353
|
+
4. **使用键前缀**: 通过键前缀进行业务隔离,避免键冲突
|
|
354
|
+
5. **及时关闭连接**: 在应用结束时调用close()方法关闭所有连接
|
|
355
|
+
6. **利用事件系统**: 使用事件系统进行日志记录、数据验证和操作拦截
|
|
356
|
+
|
|
357
|
+
## 版本更新
|
|
358
|
+
|
|
359
|
+
### 1.7.0 (2024-10-07)
|
|
360
|
+
- 统一事件系统的属性命名规范
|
|
361
|
+
- 更新所有方法的事件emit属性,使用统一的key、value、ttl、result等命名
|
|
362
|
+
- 增加事件系统的详细文档
|
|
363
|
+
- 修复部分方法中的拼写错误
|
|
364
|
+
|
|
365
|
+
### 1.6.0 (2024-01-10)
|
|
366
|
+
- 添加完整的连接池管理功能
|
|
367
|
+
- 新增Pipeline批量操作优化
|
|
368
|
+
- 增加Hash数据类型支持
|
|
369
|
+
- 增强错误处理和日志记录
|
|
370
|
+
- 优化重连机制,实现指数退避策略
|
|
371
|
+
|
|
372
|
+
### 1.5.0
|
|
373
|
+
- 优化连接管理
|
|
374
|
+
- 完善错误处理
|
|
375
|
+
- 提升代码稳定性
|
|
376
|
+
|
|
377
|
+
### 1.0.0
|
|
378
|
+
- 初始版本发布
|
|
379
|
+
- 基础Redis功能支持
|