@gordon.gan/specflow 1.3.3-beta → 1.4.1
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 +6 -2
- package/dist/integrations/shared/capability-evidence.js +37 -1
- package/dist/integrations/shared/command-catalog.js +1 -0
- package/dist/integrations/shared/parity-manifest.js +6 -0
- package/package.json +1 -1
- package/prompts/approval/database-guidance.md +79 -0
- package/prompts/approval/generate.md +1191 -0
- package/skills/database/LICENSE +405 -0
- package/skills/database/ORIGIN.md +6 -0
- package/skills/database/README.md +30 -0
- package/skills/database/elasticsearch/LICENSE.txt +202 -0
- package/skills/database/elasticsearch/SKILL.md +199 -0
- package/skills/database/elasticsearch/examples/01-fulltext-search.md +215 -0
- package/skills/database/elasticsearch/examples/02-aggregation-report.md +206 -0
- package/skills/database/elasticsearch/examples/03-reindex-zero-downtime.md +200 -0
- package/skills/database/elasticsearch/examples/04-cluster-monitoring.md +204 -0
- package/skills/database/elasticsearch/references/01-query-dsl-fulltext.md +162 -0
- package/skills/database/elasticsearch/references/02-query-dsl-term.md +210 -0
- package/skills/database/elasticsearch/references/03-aggregations-metric.md +161 -0
- package/skills/database/elasticsearch/references/04-aggregations-bucket.md +236 -0
- package/skills/database/elasticsearch/references/05-mapping-types.md +134 -0
- package/skills/database/elasticsearch/references/06-analyzers.md +187 -0
- package/skills/database/elasticsearch/references/07-cluster-ops.md +225 -0
- package/skills/database/elasticsearch/references/08-elk-integration.md +170 -0
- package/skills/database/mysql/SKILL.md +195 -0
- package/skills/database/mysql/examples/01-connection-pool.md +75 -0
- package/skills/database/mysql/examples/02-slow-query-optimization.md +98 -0
- package/skills/database/mysql/examples/03-master-slave-setup.md +144 -0
- package/skills/database/mysql/examples/04-backup-strategy.md +212 -0
- package/skills/database/mysql/references/01-functions-string.md +103 -0
- package/skills/database/mysql/references/02-functions-date.md +152 -0
- package/skills/database/mysql/references/03-functions-aggregate-window.md +167 -0
- package/skills/database/mysql/references/04-functions-json.md +129 -0
- package/skills/database/mysql/references/05-sql-ddl-types.md +235 -0
- package/skills/database/mysql/references/06-index-optimization.md +232 -0
- package/skills/database/mysql/references/07-replication-ha.md +213 -0
- package/skills/database/mysql/references/08-backup-restore.md +207 -0
- package/skills/database/mysql/references/09-advanced-features.md +345 -0
- package/skills/database/oracle/LICENSE.txt +202 -0
- package/skills/database/oracle/SKILL.md +238 -0
- package/skills/database/oracle/examples/01-plsql-procedure.md +90 -0
- package/skills/database/oracle/examples/02-awr-analysis.md +99 -0
- package/skills/database/oracle/examples/03-rman-backup.md +108 -0
- package/skills/database/oracle/examples/04-dataguard-setup.md +146 -0
- package/skills/database/oracle/references/01-functions-string.md +91 -0
- package/skills/database/oracle/references/02-functions-date.md +71 -0
- package/skills/database/oracle/references/03-analytic-functions.md +103 -0
- package/skills/database/oracle/references/04-plsql-guide.md +303 -0
- package/skills/database/oracle/references/05-performance-tuning.md +164 -0
- package/skills/database/oracle/references/06-backup-recovery.md +115 -0
- package/skills/database/oracle/references/07-dataguard-rac.md +76 -0
- package/skills/database/oracle/references/08-security.md +170 -0
- package/skills/database/oracle/references/09-sql-syntax.md +152 -0
- package/skills/database/oracle/references/10-features.md +174 -0
- package/skills/database/postgresql/LICENSE.txt +202 -0
- package/skills/database/postgresql/SKILL.md +182 -0
- package/skills/database/postgresql/examples/.gitkeep +0 -0
- package/skills/database/postgresql/examples/01-jsonb-query.md +72 -0
- package/skills/database/postgresql/examples/02-cte-recursive.md +110 -0
- package/skills/database/postgresql/examples/03-performance-tuning.md +114 -0
- package/skills/database/postgresql/examples/04-streaming-replication.md +113 -0
- package/skills/database/postgresql/references/.gitkeep +0 -0
- package/skills/database/postgresql/references/01-functions-string.md +174 -0
- package/skills/database/postgresql/references/02-functions-datetime.md +54 -0
- package/skills/database/postgresql/references/03-functions-aggregate-window.md +142 -0
- package/skills/database/postgresql/references/04-functions-jsonb.md +117 -0
- package/skills/database/postgresql/references/05-fulltext-search.md +109 -0
- package/skills/database/postgresql/references/06-index-types.md +95 -0
- package/skills/database/postgresql/references/07-partition-fdw.md +133 -0
- package/skills/database/postgresql/references/08-replication-backup.md +215 -0
- package/skills/database/redis/LICENSE.txt +202 -0
- package/skills/database/redis/SKILL.md +922 -0
- package/skills/database/redis/examples/01-cache-usage.md +104 -0
- package/skills/database/redis/examples/02-session-storage.md +72 -0
- package/skills/database/redis/examples/03-leaderboard.md +63 -0
- package/skills/database/redis/examples/04-redis-cluster-setup.md +70 -0
- package/skills/database/redis/examples/05-stream-queue.md +65 -0
- package/skills/database/redis/references/command-quick-ref.md +180 -0
- package/skills/database/redis/references/commands-admin-key.md +413 -0
- package/skills/database/redis/references/commands-set-sorted-advanced.md +539 -0
- package/skills/database/redis/references/commands-string-hash-list.md +458 -0
- package/skills/database/redis/references/memory-optimization.md +150 -0
- package/skills/database/redis/references/redis-conf-production.md +139 -0
- package/skills/specflow-approval/SKILL.md +427 -0
- package/templates/approval.md +464 -0
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
# Redis 命令详解 — String / Hash / List
|
|
2
|
+
|
|
3
|
+
> 内容源自 doc.redisfans.com 完整翻译版 (Redis 2.8+),每个命令包含简介、参数说明、业务场景。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. String(字符串)命令
|
|
8
|
+
|
|
9
|
+
| 命令 | 时间复杂度 | 可用版本 | 分类 |
|
|
10
|
+
|------|-----------|---------|------|
|
|
11
|
+
| SET | O(1) | ≥1.0.0 | 基础 |
|
|
12
|
+
| GET | O(1) | ≥1.0.0 | 基础 |
|
|
13
|
+
| INCR | O(1) | ≥1.0.0 | 计数器 |
|
|
14
|
+
| MSET | O(N) | ≥1.0.1 | 批量 |
|
|
15
|
+
| APPEND | O(1) | ≥2.0.0 | 字符串操作 |
|
|
16
|
+
|
|
17
|
+
### SET
|
|
18
|
+
**SET key value [EX seconds] [PX milliseconds] [NX|XX] [KEEPTTL]**
|
|
19
|
+
|
|
20
|
+
将字符串值 value 关联到 key。如果 key 已存在,SET 覆写旧值。对于原带 TTL 的 key,SET 执行后清除原 TTL。
|
|
21
|
+
|
|
22
|
+
**参数说明**:
|
|
23
|
+
- `EX seconds`:设置过期时间(秒),等价 SETEX
|
|
24
|
+
- `PX milliseconds`:设置过期时间(毫秒),等价 PSETEX
|
|
25
|
+
- `NX`:仅在 key 不存在时设置,等价 SETNX
|
|
26
|
+
- `XX`:仅在 key 已存在时设置
|
|
27
|
+
- `KEEPTTL` (Redis 6.0+):保留 key 原有的 TTL
|
|
28
|
+
|
|
29
|
+
> ⚠️ Redis 未来版本可能废弃 SETNX / SETEX / PSETEX,推荐统一使用 SET 的可选参数。
|
|
30
|
+
|
|
31
|
+
**业务场景:分布式锁**
|
|
32
|
+
```
|
|
33
|
+
SET resource:lock random_string NX EX 30
|
|
34
|
+
```
|
|
35
|
+
- 返回 OK → 获得锁
|
|
36
|
+
- 返回 NIL → 锁被占用,稍后重试
|
|
37
|
+
- 解锁需配合 Lua 脚本原子校验 token 后 DEL
|
|
38
|
+
|
|
39
|
+
**业务场景:缓存**
|
|
40
|
+
```
|
|
41
|
+
SET user:profile:42 '{"name":"Alice"}' EX 3600
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**返回值**:OK(成功)| NIL(NX/XX 条件未满足)
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
### GET
|
|
49
|
+
**GET key**
|
|
50
|
+
|
|
51
|
+
返回 key 所关联的字符串值。key 不存在返回 nil,key 不是 string 类型返回错误。
|
|
52
|
+
|
|
53
|
+
**业务场景**:
|
|
54
|
+
- 缓存读取(配合 SETEX 写入)
|
|
55
|
+
- 分布式锁 token 校验
|
|
56
|
+
- Session 数据获取
|
|
57
|
+
|
|
58
|
+
**返回值**:字符串值 | nil(key 不存在)
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
### INCR
|
|
63
|
+
**INCR key**
|
|
64
|
+
|
|
65
|
+
将 key 中存储的数字值增一。key 不存在则先初始化为 0 再执行。值不能超过 64 位有符号整数。
|
|
66
|
+
|
|
67
|
+
**业务场景**:
|
|
68
|
+
- **计数器**:页面访问量、文章 PV/UV
|
|
69
|
+
- **序列生成器**:订单号自增 (`INCR order:seq`)
|
|
70
|
+
- **限流计数器**:每秒/每分钟请求计数
|
|
71
|
+
- **消息未读数**:`INCR user:42:unread`
|
|
72
|
+
|
|
73
|
+
**错误处理**:如果 key 存的值不是数字,返回 WRONGTYPE 错误。
|
|
74
|
+
|
|
75
|
+
**返回值**:执行 INCR 后的新值
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
### INCRBY
|
|
80
|
+
**INCRBY key increment**
|
|
81
|
+
|
|
82
|
+
将 key 中的数字加上指定增量(可正可负)。等价于 INCR 的通用版本。
|
|
83
|
+
|
|
84
|
+
**业务场景**:
|
|
85
|
+
- 积分增减 `INCRBY user:42:points 100`
|
|
86
|
+
- 库存批量扣减 `INCRBY stock:item:1001 -1`
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
### INCRBYFLOAT
|
|
91
|
+
**INCRBYFLOAT key increment**
|
|
92
|
+
|
|
93
|
+
为 key 中的值加上浮点数增量。支持精度到小数点后 17 位。
|
|
94
|
+
|
|
95
|
+
**业务场景**:价格计算、余额操作、汇率换算
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
### DECR / DECRBY
|
|
100
|
+
**DECR key** / **DECRBY key decrement**
|
|
101
|
+
|
|
102
|
+
将 key 中的数字值减一/减 decrement。等价于 INCRBY 的减量版本。
|
|
103
|
+
|
|
104
|
+
**业务场景**:
|
|
105
|
+
- 库存剩余量实时递减
|
|
106
|
+
- 优惠券剩余数量
|
|
107
|
+
- 限流可用配额
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
### MSET
|
|
112
|
+
**MSET key value [key value ...]**
|
|
113
|
+
|
|
114
|
+
同时设置一个或多个 key-value。MSET 是原子操作(要么全设要么全不设),MGET 不是(但读取本身是原子单次操作)。
|
|
115
|
+
|
|
116
|
+
**业务场景**:批量初始化缓存、批量保存配置
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
MSET user:1:name "Alice" user:1:age 30 user:1:city "Beijing"
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**返回值**:OK
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
### MSETNX
|
|
127
|
+
**MSETNX key value [key value ...]**
|
|
128
|
+
|
|
129
|
+
仅当所有给定 key 都不存在时,才同时设置一个或多个 key-value。原子性保证"全部或全不"。
|
|
130
|
+
|
|
131
|
+
**业务场景**:批量初始化确保不覆盖已有数据
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
### MGET
|
|
136
|
+
**MGET key [key ...]**
|
|
137
|
+
|
|
138
|
+
返回所有给定 key 的值(按请求顺序返回)。某个 key 不存在则返回 nil。
|
|
139
|
+
|
|
140
|
+
**业务场景**:批量查缓存(比 N 次 GET 节省 RTT)
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
### APPEND
|
|
145
|
+
**APPEND key value**
|
|
146
|
+
|
|
147
|
+
将 value 追加到 key 原值的末尾。key 不存在则等同于 SET。
|
|
148
|
+
|
|
149
|
+
**业务场景**:日志追加、文本拼接、Feed 构建
|
|
150
|
+
|
|
151
|
+
**返回值**:追加后的字符串长度
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
### GETRANGE
|
|
156
|
+
**GETRANGE key start end**
|
|
157
|
+
|
|
158
|
+
返回 key 中字符串的子串(0-based,包含 start 和 end)。支持负数偏移(-1 是最后一个字符)。
|
|
159
|
+
|
|
160
|
+
**业务场景**:截取部分内容展示、分页读取长字符串
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
### SETRANGE
|
|
165
|
+
**SETRANGE key offset value**
|
|
166
|
+
|
|
167
|
+
从 offset 开始,用 value 覆写 key 的字符串。原字符串长度不足则自动补充零字节(\x00)。
|
|
168
|
+
|
|
169
|
+
**业务场景**:更新固定长度字段、位图叠加写入
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
### STRLEN
|
|
174
|
+
**STRLEN key**
|
|
175
|
+
|
|
176
|
+
返回字符串值的长度。key 不存在返回 0。
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
### GETSET
|
|
181
|
+
**GETSET key value**
|
|
182
|
+
|
|
183
|
+
原子操作:设置新值,返回旧值。如果 key 不存在则返回 nil(此时相当于 SET)。
|
|
184
|
+
|
|
185
|
+
**业务场景**:计数器重置(获取旧值后置零)、轮转更新
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
### SETEX
|
|
190
|
+
**SETEX key seconds value**
|
|
191
|
+
|
|
192
|
+
等价 `SET key value EX seconds`。建议直接用 SET 替代。
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
### SETNX
|
|
197
|
+
**SETNX key value**
|
|
198
|
+
|
|
199
|
+
等价 `SET key value NX`。建议直接用 SET 替代。
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
### PSETEX
|
|
204
|
+
**PSETEX key milliseconds value**
|
|
205
|
+
|
|
206
|
+
等价 `SET key value PX milliseconds`。建议直接用 SET 替代。
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
### BITCOUNT
|
|
211
|
+
**BITCOUNT key [start end [BYTE|BIT]]**
|
|
212
|
+
|
|
213
|
+
计算字符串中 1 的比特位数量(popcount)。可通过 start/end 指定字节范围。
|
|
214
|
+
|
|
215
|
+
**业务场景**:
|
|
216
|
+
- **在线用户统计**:每天一个 BITMAP,用户 ID 作为 offset
|
|
217
|
+
- **签到统计**:`BITCOUNT sign:2024-01-15`
|
|
218
|
+
- **日活 UV 统计**:多天 BITMAP 的 BITOP OR 再 BITCOUNT
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
### BITOP
|
|
223
|
+
**BITOP operation destkey key [key ...]**
|
|
224
|
+
|
|
225
|
+
对一个或多个 key 执行位运算:AND / OR / NOT / XOR,结果保存到 destkey。
|
|
226
|
+
|
|
227
|
+
**业务场景**:
|
|
228
|
+
- **连续签到统计**:`BITOP AND result sign:01 sign:02 sign:03` (当月全部签到的用户)
|
|
229
|
+
- **任意签到查找**:`BITOP OR result sign:01 sign:02`(月内至少签到一次的用户)
|
|
230
|
+
- **广告去重**:多日曝光用户 BITOP OR
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
### SETBIT / GETBIT
|
|
235
|
+
**SETBIT key offset value** / **GETBIT key offset**
|
|
236
|
+
|
|
237
|
+
设置/获取指定偏移量上的比特位(0 或 1)。
|
|
238
|
+
|
|
239
|
+
**业务场景**:
|
|
240
|
+
- 用户签到:`SETBIT sign:2024-01 42 1`
|
|
241
|
+
- 布隆过滤器实现
|
|
242
|
+
- 独立用户标记
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## 2. Hash(哈希表)命令
|
|
247
|
+
|
|
248
|
+
| 命令 | 时间复杂度 | 可用版本 | 说明 |
|
|
249
|
+
|------|-----------|---------|------|
|
|
250
|
+
| HSET | O(1) | ≥2.0.0 | 设置字段 |
|
|
251
|
+
| HGET | O(1) | ≥2.0.0 | 获取字段 |
|
|
252
|
+
| HGETALL | O(N) | ≥2.0.0 | 获取所有 |
|
|
253
|
+
| HMSET | O(N) | ≥2.0.0 | 批量设置 |
|
|
254
|
+
| HINCRBY | O(1) | ≥2.0.0 | 字段计数 |
|
|
255
|
+
|
|
256
|
+
### HSET
|
|
257
|
+
**HSET key field value [field value ...] (Redis 4.0+ 支持多 field)**
|
|
258
|
+
|
|
259
|
+
设置哈希表 key 中的字段。字段已存在则覆盖旧值。多字段版本返回新创建字段数量。
|
|
260
|
+
|
|
261
|
+
**业务场景:对象存储**
|
|
262
|
+
```
|
|
263
|
+
HSET user:1001 name "Alice" age 30 email "alice@example.com"
|
|
264
|
+
```
|
|
265
|
+
替代了 `set user:1001:name` / `set user:1001:age` / `set user:1001:email` 三个 key,节省约 50% 内存。
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
### HGET
|
|
270
|
+
**HGET key field**
|
|
271
|
+
|
|
272
|
+
获取哈希表中指定字段的值。
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
### HGETALL
|
|
277
|
+
**HGETALL key**
|
|
278
|
+
|
|
279
|
+
返回哈希表中所有字段和值(交替排列)。**大 Hash 场景慎用**(阻塞 Redis)。
|
|
280
|
+
|
|
281
|
+
**业务场景**:小对象(字段数 < 100)适合全量读取;大对象改用 HSCAN 分批迭代。
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
### HMSET / HMGET
|
|
286
|
+
**HMSET key field value [field value ...]**
|
|
287
|
+
**HMGET key field [field ...]**
|
|
288
|
+
|
|
289
|
+
批量设置/获取字段。HMSET 已被 HSET 的多 field 版本取代。
|
|
290
|
+
|
|
291
|
+
**业务场景**:`HMGET user:1001 name email` 只取需要的字段,避免 HGETALL 浪费带宽。
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
295
|
+
### HEXISTS / HDEL
|
|
296
|
+
**HEXISTS key field** — 判断字段是否存在
|
|
297
|
+
**HDEL key field [field ...]** — 删除一个或多个字段
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
### HLEN
|
|
302
|
+
**HLEN key** — 返回哈希表中字段数量
|
|
303
|
+
|
|
304
|
+
**业务场景**:Hash 大小时监控(HLEN 是 O(1) 的快照)。
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
### HKEYS / HVALS
|
|
309
|
+
**HKEYS key** — 获取所有字段名
|
|
310
|
+
**HVALS key** — 获取所有字段值
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
### HINCRBY / HINCRBYFLOAT
|
|
315
|
+
**HINCRBY key field increment** — 整数增加
|
|
316
|
+
**HINCRBYFLOAT key field increment** — 浮点数增加
|
|
317
|
+
|
|
318
|
+
**业务场景**:Hash 中的计数器(如用户积分 `HINCRBY user:1001 score 10`)
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
### HSETNX
|
|
323
|
+
**HSETNX key field value** — 字段不存在时才设置(等价 Hash 版的 SETNX)
|
|
324
|
+
|
|
325
|
+
**业务场景**:
|
|
326
|
+
- 第一次访问时设置初始值
|
|
327
|
+
- 防止覆盖已有数据
|
|
328
|
+
|
|
329
|
+
### HSCAN
|
|
330
|
+
**HSCAN key cursor [MATCH pattern] [COUNT count]**
|
|
331
|
+
|
|
332
|
+
渐进式迭代哈希表中的字段。**替代 HGETALL 大 Hash 场景**。
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
## 3. List(列表)命令
|
|
337
|
+
|
|
338
|
+
| 命令 | 时间复杂度 | 可用版本 | 说明 |
|
|
339
|
+
|------|-----------|---------|------|
|
|
340
|
+
| LPUSH | O(1) | ≥1.0.0 | 左推 |
|
|
341
|
+
| RPUSH | O(1) | ≥1.0.0 | 右推 |
|
|
342
|
+
| LPOP | O(1) | ≥1.0.0 | 左弹 |
|
|
343
|
+
| LRANGE | O(S+N) | ≥1.0.0 | 范围查 |
|
|
344
|
+
| LTRIM | O(N) | ≥1.0.0 | 修剪 |
|
|
345
|
+
| BLPOP | O(1) | ≥2.0.0 | 阻塞左弹 |
|
|
346
|
+
|
|
347
|
+
### RPUSH / LPUSH
|
|
348
|
+
**RPUSH key value [value ...]** — 右端推入
|
|
349
|
+
**LPUSH key value [value ...]** — 左端推入
|
|
350
|
+
|
|
351
|
+
**业务场景**:
|
|
352
|
+
- **队列** (FIFO):`RPUSH queue job1` + `LPOP queue` 或 `BLPOP queue`
|
|
353
|
+
- **栈** (LIFO):`LPUSH stack item` + `LPOP stack`
|
|
354
|
+
- **时间线**:`LPUSH timeline:user42 post_id` + `LTRIM timeline:user42 0 99`
|
|
355
|
+
|
|
356
|
+
---
|
|
357
|
+
|
|
358
|
+
### LRANGE
|
|
359
|
+
**LRANGE key start stop**
|
|
360
|
+
|
|
361
|
+
返回列表中指定区间内的元素(0-based)。负偏移索引:-1 是最后一个。
|
|
362
|
+
|
|
363
|
+
**业务场景**:分页读取列表、获取最新 N 条消息
|
|
364
|
+
|
|
365
|
+
```
|
|
366
|
+
LRANGE messages 0 9 -- 最新 10 条
|
|
367
|
+
LRANGE messages 0 -1 -- 全部(慎用,大列表会阻塞)
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
### LTRIM
|
|
373
|
+
**LTRIM key start stop**
|
|
374
|
+
|
|
375
|
+
修剪列表,仅保留指定区间内的元素。
|
|
376
|
+
|
|
377
|
+
**业务场景:固定长度列表**
|
|
378
|
+
```
|
|
379
|
+
LPUSH recent:items article:1001
|
|
380
|
+
LTRIM recent:items 0 99 -- 最多保留 100 条
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
---
|
|
384
|
+
|
|
385
|
+
### LPOP / RPOP
|
|
386
|
+
**LPOP key [count] (Redis 6.2+)** — 移除并返回左边第一个元素
|
|
387
|
+
**RPOP key [count] (Redis 6.2+)** — 移除并返回右边第一个元素
|
|
388
|
+
|
|
389
|
+
---
|
|
390
|
+
|
|
391
|
+
### BLPOP / BRPOP
|
|
392
|
+
**BLPOP key [key ...] timeout**
|
|
393
|
+
**BRPOP key [key ...] timeout**
|
|
394
|
+
|
|
395
|
+
阻塞式弹出:列表为空时等待,直到超时或有元素加入。timeout=0 表示无限等待。
|
|
396
|
+
|
|
397
|
+
**业务场景:可靠消息队列**
|
|
398
|
+
```
|
|
399
|
+
# Worker 端
|
|
400
|
+
BLOP queue 0 # 无限等待新任务
|
|
401
|
+
# 有元素加入队列时立即返回,无需轮询
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
**阻塞特性**:
|
|
405
|
+
- 多个客户端同时 BLPOP 同一 key → 第一个等待的客户端优先
|
|
406
|
+
- 监视多个 key:按 key 顺序依次检查
|
|
407
|
+
- 超时返回 nil(两个 nil 值)
|
|
408
|
+
|
|
409
|
+
---
|
|
410
|
+
|
|
411
|
+
### RPOPLPUSH / BRPOPLPUSH
|
|
412
|
+
**RPOPLPUSH source destination** — 转存(原子操作)
|
|
413
|
+
**BRPOPLPUSH source destination timeout** — 阻塞版转存
|
|
414
|
+
|
|
415
|
+
**业务场景:可靠消息处理(备份队列)**
|
|
416
|
+
```
|
|
417
|
+
# 生产:RPUSH queue:incoming job
|
|
418
|
+
# 消费:BRPOPLPUSH queue:incoming queue:processing 0
|
|
419
|
+
# 成功处理后:LREM queue:processing 1 job
|
|
420
|
+
# 处理失败:RPUSH queue:retry job
|
|
421
|
+
```
|
|
422
|
+
原子转移保证消息不丢——崩溃重启后还能从 processing 队列恢复。
|
|
423
|
+
|
|
424
|
+
---
|
|
425
|
+
|
|
426
|
+
### LINDEX / LSET / LINSERT
|
|
427
|
+
**LINDEX key index** — 根据索引获取
|
|
428
|
+
**LSET key index value** — 设置索引位置的元素
|
|
429
|
+
**LINSERT key BEFORE|AFTER pivot value** — 在指定元素前后插入
|
|
430
|
+
|
|
431
|
+
**业务场景**:LRANGE 读取后定位到特定位置修改、列表中间插入优先级任务
|
|
432
|
+
|
|
433
|
+
---
|
|
434
|
+
|
|
435
|
+
### LLEN
|
|
436
|
+
**LLEN key** — 返回列表长度(O(1))
|
|
437
|
+
|
|
438
|
+
**业务场景**:消息队列积压长度监控、列表大小的快速判断
|
|
439
|
+
|
|
440
|
+
---
|
|
441
|
+
|
|
442
|
+
### LREM
|
|
443
|
+
**LREM key count value**
|
|
444
|
+
|
|
445
|
+
移除列表中与 value 匹配的元素。
|
|
446
|
+
- count > 0:从左到右移除最多 count 个
|
|
447
|
+
- count < 0:从右到左移除最多 |count| 个
|
|
448
|
+
- count = 0:移除全部匹配
|
|
449
|
+
|
|
450
|
+
**业务场景**:取消点赞、清理已处理消息
|
|
451
|
+
|
|
452
|
+
---
|
|
453
|
+
|
|
454
|
+
### LPUSHX / RPUSHX
|
|
455
|
+
**LPUSHX key value** — 仅当列表存在时左推
|
|
456
|
+
**RPUSHX key value** — 仅当列表存在时右推
|
|
457
|
+
|
|
458
|
+
**业务场景**:仅在队列初始化后才接收新消息,避免自动创建空列表。
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# Redis 内存优化深度指南
|
|
2
|
+
|
|
3
|
+
## 1. 内存模型
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
Redis 内存构成:
|
|
7
|
+
┌─────────────────────────────────┐
|
|
8
|
+
│ 数据内存 (key + value) │ ← 主要部分
|
|
9
|
+
│ 元数据 (dict entry/robj) │ ← 每个 key 约 64 字节开销
|
|
10
|
+
│ 缓冲区 (client/复制/AOF) │
|
|
11
|
+
│ 自身 (代码/栈) │
|
|
12
|
+
└─────────────────────────────────┘
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## 2. 编码优化 — 选择最省内存的数据结构
|
|
16
|
+
|
|
17
|
+
| 数据结构 | 小数据编码 | 省内存机制 | 阈值配置 |
|
|
18
|
+
|---------|-----------|-----------|---------|
|
|
19
|
+
| Hash | ziplist | 连续内存块,无指针开销 | `hash-max-ziplist-entries 512`<br>`hash-max-ziplist-value 64` |
|
|
20
|
+
| ZSet | ziplist | 同上 | `zset-max-ziplist-entries 128`<br>`zset-max-ziplist-value 64` |
|
|
21
|
+
| Set | intset | 整数数组,连续内存 | `set-max-intset-entries 512` |
|
|
22
|
+
| List | quicklist | ziplist 链表节点 | `list-max-ziplist-size -2`<br>`list-compress-depth 0` |
|
|
23
|
+
|
|
24
|
+
## 3. 内存优化 10 大技巧
|
|
25
|
+
|
|
26
|
+
### 3.1 用 Hash 替代 String 存对象
|
|
27
|
+
|
|
28
|
+
```redis
|
|
29
|
+
# 坏: 每个字段一个 key (大量元数据开销)
|
|
30
|
+
SET user:1001:name "Alice"
|
|
31
|
+
SET user:1001:age 30
|
|
32
|
+
SET user:1001:email "alice@example.com"
|
|
33
|
+
# 内存: 3 × (37+key_overhead) ≈ 300 字节
|
|
34
|
+
|
|
35
|
+
# 好: 一个 Hash 存所有字段
|
|
36
|
+
HSET user:1001 name "Alice" age 30 email "alice@example.com"
|
|
37
|
+
# 内存: ~160 字节 (节省 ~50%)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### 3.2 合理设置过期时间
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# 不使用过期 = 内存只增不减
|
|
44
|
+
# 最佳实践: 每个 key 都设 TTL
|
|
45
|
+
SET cache:xxx value EX 3600
|
|
46
|
+
|
|
47
|
+
# 批量设置随机 TTL 避免雪崩
|
|
48
|
+
SET cache:a value EX $(( 300 + RANDOM % 60 ))
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 3.3 短 key 命名
|
|
52
|
+
|
|
53
|
+
```redis
|
|
54
|
+
# 坏: 超长 key 名
|
|
55
|
+
SET "user:profile:data:by:user:id:1001:preferences" value
|
|
56
|
+
|
|
57
|
+
# 好: 短 key 名
|
|
58
|
+
SET u:1001:pref value
|
|
59
|
+
# 节省: 每个 key 减少数十字节, 百万 key 节省数十 MB
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 3.4 使用小数据类型
|
|
63
|
+
|
|
64
|
+
```redis
|
|
65
|
+
# 统计在线用户数
|
|
66
|
+
# 坏: Set 存储所有用户ID
|
|
67
|
+
SADD online:users 1001 # 每个 member 约 60+ 字节
|
|
68
|
+
|
|
69
|
+
# 好: Bitmap 按位存储 (每个用户 1 bit)
|
|
70
|
+
SETBIT online:2024-01-15 1001 1 # 仅 1 位
|
|
71
|
+
|
|
72
|
+
# 统计 UV
|
|
73
|
+
# 坏: Set 存储所有访问用户 (大数据量)
|
|
74
|
+
# 好: HyperLogLog (单 key 仅 12KB)
|
|
75
|
+
PFADD visits:2024-01-15 "user1" "user2"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### 3.5 压缩大 Value
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
import zlib
|
|
82
|
+
import json
|
|
83
|
+
|
|
84
|
+
# 存储前压缩
|
|
85
|
+
data = json.dumps(large_object)
|
|
86
|
+
compressed = zlib.compress(data.encode())
|
|
87
|
+
redis.set("large:key", compressed)
|
|
88
|
+
|
|
89
|
+
# 读取后解压
|
|
90
|
+
compressed = redis.get("large:key")
|
|
91
|
+
data = json.loads(zlib.decompress(compressed))
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## 4. 内存监控与调优
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
# 查看内存使用
|
|
98
|
+
redis-cli INFO MEMORY
|
|
99
|
+
|
|
100
|
+
# 关键指标解读
|
|
101
|
+
used_memory_human: 4.00G # 已用内存
|
|
102
|
+
used_memory_peak_human: 6.00G # 峰值 (需关注)
|
|
103
|
+
used_memory_rss_human: 5.50G # 系统分配内存 (含碎片)
|
|
104
|
+
mem_fragmentation_ratio: 1.37 # 碎片率 (>1.5 需处理)
|
|
105
|
+
|
|
106
|
+
# 找到大 key
|
|
107
|
+
redis-cli --bigkeys
|
|
108
|
+
|
|
109
|
+
# 查看 key 的精确内存占用
|
|
110
|
+
redis-cli MEMORY USAGE user:1001
|
|
111
|
+
|
|
112
|
+
# 查看 key 的编码
|
|
113
|
+
redis-cli OBJECT ENCODING user:1001
|
|
114
|
+
redis-cli OBJECT IDLETIME user:1001
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## 5. 内存淘汰策略选择
|
|
118
|
+
|
|
119
|
+
| 策略 | 适用场景 | 示例配置 |
|
|
120
|
+
|------|---------|---------|
|
|
121
|
+
| allkeys-lru | 通用缓存,访问时间间隔模式 | `maxmemory-policy allkeys-lru` |
|
|
122
|
+
| volatile-lru | 部分 key 持久化部分做缓存 | `maxmemory-policy volatile-lru` |
|
|
123
|
+
| allkeys-lfu | 访问频率差异大的场景 | `maxmemory-policy allkeys-lfu` |
|
|
124
|
+
| allkeys-random | 缓存键命中率均匀 | `maxmemory-policy allkeys-random` |
|
|
125
|
+
| volatile-ttl | 优先保留过期时间短的 | `maxmemory-policy volatile-ttl` |
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
# 最佳生产配置: 4GB 内存 + LRU 淘汰
|
|
129
|
+
maxmemory 4gb
|
|
130
|
+
maxmemory-policy allkeys-lru
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## 6. 内存碎片处理
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
# 检查碎片率
|
|
137
|
+
redis-cli INFO | grep mem_fragmentation_ratio
|
|
138
|
+
|
|
139
|
+
# 自动碎片整理 (Redis 4.0+)
|
|
140
|
+
CONFIG SET activedefrag yes
|
|
141
|
+
CONFIG SET active-defrag-threshold-lower 10
|
|
142
|
+
CONFIG SET active-defrag-threshold-upper 100
|
|
143
|
+
CONFIG SET active-defrag-ignore-bytes 100mb
|
|
144
|
+
CONFIG SET active-defrag-cycle-min 5
|
|
145
|
+
CONFIG SET active-defrag-cycle-max 75
|
|
146
|
+
|
|
147
|
+
# 手动 (高碎片率时)
|
|
148
|
+
redis-cli MEMORY PURGE
|
|
149
|
+
# 如仍高,需重启 Redis 节点
|
|
150
|
+
```
|