# 修复：清除 404 主题缓存时避免遍历 Redis 键

**URL:** <https://meta.discourse.org/t/fix-avoid-traversing-redis-keys-when-clearing-404-topic-cache/409622>\
**Category:** Bug\
**Tags:** fixed\
**Created:** [2026年八月9日 09:14 UTC](https://meta.discourse.org/t/fix-avoid-traversing-redis-keys-when-clearing-404-topic-cache/409622 "2026-08-09T09:14:29Z")\
**Posts on this page:** 1\
**Showing post:** 1

<div class="post-metadata">

**Author:** ![small-lovely-cat](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/small-lovely-cat/32/553546_2.png) [@small-lovely-cat](https://meta.discourse.org/u/small-lovely-cat)\
**Post date:** [2026年八月9日 09:14 UTC](https://meta.discourse.org/t/fix-avoid-traversing-redis-keys-when-clearing-404-topic-cache/409622/1 "2026-08-09T09:14:29Z")

</div>

在 #42413 中，主题的缓存失效逻辑进行了重新设计。

然而，`Discourse.cache.keys("page_not_found_topics:*").each { |key| Discourse.cache.redis.del(key) }` 将遍历所有 Redis 键，导致性能问题，并且在键数量较大时可能会超时。

在这种情况下，如果用户将主题移动到受限类别，可能会遇到 500 错误。

 ![image](https://global.discourse-cdn.com/meta/original/4X/8/5/8/8581549a80b362a4ac9cfb146c057bf0834d7651.png)

此提交将遍历范围限制为 `Discourse.cache.normalize_key("page_not_found_topics:#{locale}")`，这比整个 Redis 小得多，并添加了一个测试以避免执行 `scan_each`。在 #42413 中，主题的缓存失效逻辑进行了重新设计。

> <https://github.com/discourse/discourse/pull/42457>
>
> In #42413 , cache invalidation logic of topic is redesigned.
> 
> However, \`Discou…rse.cache.keys("page\_not\_found\_topics:\*").each { |key| Discourse.cache.redis.del(key) }\` will traverse all of the redis keys, causing performance issues, and may timeout if there are large amount of keys.
> 
> For a site with a large Redis DB, users may encounter 500 error when they move a topic to a restricted category.
> 
> \<img width="240" height="211" alt="image" src="https://github.com/user-attachments/assets/e16e87d0-2c1e-437e-99bf-521c5e4774a1" /\>
> 
> This commit restrict the traverse scope to \`Discourse.cache.normalize\_key("page\_not\_found\_topics:#{locale}")\`, which is far smaller than the whole redis, also add a test to avoid the execution of \`scan\_each\`.

---

_[View the full topic](https://meta.discourse.org/t/fix-avoid-traversing-redis-keys-when-clearing-404-topic-cache/409622)._
