|
11 | 11 | - [基本用法](#基本用法) |
12 | 12 | - [API 参考](#api-参考) |
13 | 13 | - [配置选项](#配置选项) |
14 | | -- [ChangeStreamWrapper 方法](#changestreamwrapper-方法) |
| 14 | +- [ChangeStream 原生方法](#changestream-原生方法) |
15 | 15 | - [使用示例](#使用示例) |
16 | 16 | - [自动缓存失效](#自动缓存失效) |
17 | 17 | - [注意事项](#注意事项) |
|
24 | 24 |
|
25 | 25 | ## 概述 |
26 | 26 |
|
27 | | -`watch()` 方法提供 MongoDB Change Streams 的封装,支持实时监听集合的数据变更,并自动处理重连、缓存失效等复杂场景。 |
| 27 | +`watch()` 方法直接返回 MongoDB Change Streams 的原生 `ChangeStream<T>` 对象,支持实时监听集合的数据变更。如需自动断点续传、多目标同步或缓存失效,请结合 [`ChangeStreamSyncManager`](./sync-backup.md) 使用。 |
28 | 28 |
|
29 | 29 | --- |
30 | 30 |
|
@@ -202,21 +202,46 @@ process.on('SIGTERM', async () => { |
202 | 202 |
|
203 | 203 | --- |
204 | 204 |
|
205 | | -## 自动缓存失效 |
| 205 | +## 缓存失效集成 |
206 | 206 |
|
207 | | -当 `autoInvalidateCache: true` (默认) 时,watch 会自动失效相关缓存: |
| 207 | +> ⚠️ `collection.watch()` 本身**不提供**内置的缓存失效功能。如需将 watch 与缓存集成,有两种方案: |
208 | 208 |
|
209 | | -| 操作类型 | 失效的缓存 | |
210 | | -|---------|----------| |
211 | | -| `insert` | `find`, `findPage`, `count`, `findAndCount` | |
212 | | -| `update` | `findOne`, `findOneById` (匹配 _id), `find`, `findPage`, `findAndCount` | |
213 | | -| `replace` | `findOne`, `findOneById` (匹配 _id), `find`, `findPage`, `findAndCount` | |
214 | | -| `delete` | `findOne`, `findOneById` (匹配 _id), `find`, `findPage`, `count`, `findAndCount` | |
| 209 | +### 方案一:手动处理(推荐轻量场景) |
215 | 210 |
|
216 | | -**跨实例同步**: |
217 | | -- 如果配置了 `distributed.enabled: true`,缓存失效会自动广播到其他实例 |
218 | | -- 其他实例收到通知后自动失效本地缓存 |
219 | | -- 无需手动实现跨实例同步 |
| 211 | +```javascript |
| 212 | +const cs = collection.watch(); |
| 213 | + |
| 214 | +cs.on('change', async (change) => { |
| 215 | + // 根据操作类型手动失效相应缓存键 |
| 216 | + if (['insert', 'update', 'replace', 'delete'].includes(change.operationType)) { |
| 217 | + myCache.delete('user-list'); |
| 218 | + myCache.delete(`user:${change.documentKey?._id}`); |
| 219 | + } |
| 220 | +}); |
| 221 | +``` |
| 222 | +
|
| 223 | +### 方案二:ChangeStreamSyncManager(推荐生产场景) |
| 224 | +
|
| 225 | +[`ChangeStreamSyncManager`](./sync-backup.md) 内置了断点续传、多目标同步和统计能力,可在 `apply` 回调中处理缓存: |
| 226 | +
|
| 227 | +```javascript |
| 228 | +const syncManager = new MonSQLize.ChangeStreamSyncManager({ |
| 229 | + db, |
| 230 | + config: { |
| 231 | + enabled: true, |
| 232 | + targets: [{ |
| 233 | + name: 'cache-invalidation', |
| 234 | + apply: async (event) => { |
| 235 | + // 在 apply 中处理缓存失效 |
| 236 | + myCache.delete('user-list'); |
| 237 | + } |
| 238 | + }] |
| 239 | + } |
| 240 | +}); |
| 241 | +await syncManager.start(); |
| 242 | +``` |
| 243 | +
|
| 244 | +**跨实例同步**: 如需分布式缓存同步,请使用 [`DistributedCacheInvalidator`](./cache-and-function-cache.md),它支持通过 Pub/Sub 广播失效信号到其他实例。 |
220 | 245 |
|
221 | 246 | --- |
222 | 247 |
|
@@ -269,18 +294,16 @@ const msq = new MonSQLize({ |
269 | 294 | ### 2. 性能影响 |
270 | 295 |
|
271 | 296 | - watch 本身对性能影响很小(MongoDB 原生支持) |
272 | | -- 缓存失效是异步的,不阻塞主流程 |
273 | | -- 跨实例广播延迟 < 10ms |
| 297 | +- ChangeStream 监听是异步的,不阻塞主流程 |
274 | 298 |
|
275 | 299 | ### 3. resumeToken 过期 |
276 | 300 |
|
277 | 301 | MongoDB oplog 有大小限制,resumeToken 可能过期(默认几小时)。 |
278 | 302 |
|
279 | | -**monSQLize 自动处理**: |
280 | | -- 检测到过期错误 |
281 | | -- 自动清除过期 token |
282 | | -- 从当前时间重新开始 |
283 | | -- 触发 `error` 事件通知用户 |
| 303 | +**处理建议**: |
| 304 | +- 监听 `error` 事件,检测 `ChangeStreamHistoryLost` 错误 |
| 305 | +- 关闭当前 ChangeStream 并重新调用 `collection.watch()`(不带 `resumeAfter`) |
| 306 | +- 如需自动处理断点续传,请使用 [`ChangeStreamSyncManager`](./sync-backup.md) |
284 | 307 |
|
285 | 308 | ### 4. 内存管理 |
286 | 309 |
|
@@ -317,21 +340,9 @@ cs.on('error', (err) => { |
317 | 340 | }); |
318 | 341 | ``` |
319 | 342 |
|
320 | | -### 问题 3: 缓存集成调试 |
321 | | - |
322 | | -> ⚠️ `collection.watch()` 本身不提供 `autoInvalidateCache` 选项或 `cache.getStats()` 接口,缓存集成由应用层处理。 |
| 343 | +### 问题 3: 缓存集成 |
323 | 344 |
|
324 | | -**推荐做法**: |
325 | | -```javascript |
326 | | -// 手动在 change 事件中处理缓存失效 |
327 | | -const cs = collection.watch(); |
328 | | - |
329 | | -cs.on('change', async (change) => { |
330 | | - console.log('变更:', change.operationType); |
331 | | - // 由业务代码决定如何失效缓存 |
332 | | - myCache.delete('user-list'); |
333 | | -}); |
334 | | -``` |
| 345 | +参见 [缓存失效集成](#缓存失效集成) 章节。 |
335 | 346 |
|
336 | 347 | --- |
337 | 348 |
|
|
0 commit comments