进阶 docs.memcached.org 2026-10-13 18:51:48 · 20 阅读

第24章 memcached 用户指南 FAQ

用户指南 FAQ 基础篇

如何列出所有键?

你可以通过一个刻意受限的接口来列出所有键。应用程序不应依赖从 memcached 服务器读取所有键。服务器可能包含数百万甚至数十亿个互不相关的键。依赖遍历所有键来渲染页面的应用最终一定会失败。你可以使用 lru crawler 来检查实例中的所有键。此接口提供了对缓存中存储的数据进行分析的有用数据。参见协议文档获取完整信息。

为什么只用内存?

memcached 所做的每一件事都是为了保证低延迟和高速度。话虽如此,对于某些较大的值,从高速闪存驱动器获取数据是有道理的。一个名为 extstore 的功能允许将数据拆分存储在内存和磁盘之间。

为什么不支持复杂操作?

所有操作都应在 O(1) 时间内完成,且必须是原子的。这并不意味着复杂操作永远无法实现,但意味着我们必须非常谨慎地思考它们。许多复杂操作可以在更基础的功能之上模拟实现。

为什么不建议用 memcached 管理会话?大家都在这么做!

如果会话丢失,用户通常会被强制登出。如果只是缓存的一部分消失(无论是由于硬件崩溃还是简单的软件升级),都不应给用户造成明显的困扰。这篇措辞略显冗长的文章解释了替代方案。memcached 通常可以将 IO 需求降低到极低水平,这意味着你可以继续将关系型数据库用于它擅长的事情。比如防止用户被踢出网站。

MySQL 查询缓存怎么样?

对于小型站点,MySQL 查询缓存是一个有用的起点。不幸的是,它在 MySQL 数据库上使用许多全局锁,因此启用它可能会拖慢速度。它还按表缓存查询,只要表发生任何变更,就必须使该表相关的所有缓存过期。如果你的站点相当静态,这可以运作良好,但当你的表开始频繁变更时,它会立刻失效。内存也有限制,因为它需要直接使用数据库旁边的一块内存。

memcached 是原子的吗?

除了你可能遇到的任何 bug,所有命令内部都是原子的。同时发出多个 set 命令不会有任何不良影响,除了最后一个命令会生效。

如何排查客户端超时?

请参阅「超时」部分以获取帮助。

设置问题

如何进行身份验证?

基本协议提供了有限的基于密码的身份验证。你还可以通过启用 TLS 并使用证书验证来进行身份验证。

如何处理故障转移?

通常不需要。一些客户端有一个「故障转移」选项,在发生故障时会尝试下一个服务器。

待办:翻新此部分。

如何处理复制?

它不处理。向系统添加复制会使有效缓存大小减半。如果你连百分之几的额外缓存未命中都无法承受,那你就有严重问题了。即使有了复制,事情也可能出错。更多的移动部件,更多的软件崩溃风险。

待办:翻新此部分。

能否在重启之间保留缓存?

可以,在某些情况下。请参见关于热重启的文档。

客户端和服务器是否都需要互相通信?

不。对话越少,系统可扩展性越高。

监控

为什么项过期时 curr_items 不减少?

memcached 中的过期是惰性的。通常,只有在有东西查看该项时,才能知道它已过期。这有助于服务器保持一致的性能。从 1.5.0 版本开始,一个后台线程会随时间分析缓存,并异步地从内存中移除过期项。更多细节请见这篇博客文章。

使用场景

什么时候你不应该使用 memcached?

并不总是适合将 memcached 添加到你的应用中。

待办:在此处链接到那个 whynot 页面,或者直接内联新内容?

为什么我不能把它用作数据库?

Memcached 是一个临时数据存储。意味着如果服务器宕机(崩溃、重启、「云嗝气」),你的数据就没了。这种临时性允许我们在设计上采取极端的权衡,从而比传统数据库快 10 倍、100 倍,甚至 1000 倍。将缓存与传统数据存储结合使用,可以降低成本并改善用户体验。

使用 memcached 会让我的应用变慢吗?

是的,绝对会。如果你的数据库查询都非常快,网站也很快,添加 memcached 可能不会让它更快。

此外,这也是一个反模式:

my @post_ids = fetch_all_posts($thread_id);
my @post_entries = ();
for my $post_id (@post_ids) {
    push(@post_entries, $memc->get($post_id));
}
# 太好了,我所有帖子条目都拿到了!

代替这种反模式,请使用流水线式的 get。从 memcached 获取单个项仍然需要一个网络往返和一点处理。一次性获取越多越好。

评论 (0)