那个响应究竟需要多长时间?

Lobsters Hottest 工具

摘要

解释为什么 memcached 的内部响应时间指标有误导性,并建议使用客户端采样来准确测量总往返时间。

<p><a href="https://lobste.rs/s/expxtl/how_long_does_response_take_for_real">评论</a></p>
查看原文
查看缓存全文

缓存时间: 2026/06/23 07:43

# 分布式内存对象缓存系统 来源:https://memcached.org/blog/how-long-for-real ## 简介 为什么 memcached 没有响应时间指标?这个令人沮丧的问题有一个令人不满意的答案:这些指标会产生误导。 先剧透一下:测量 memcached 响应时间的最佳方式是从客户端采样响应时间。这会将整个往返过程纳入考量,并且在大多数情况下能提供最具可操作性的信息。本文剩余部分将探讨其中原因。 ## 要测量时间,必须从某处开始 已用时间 测量响应时间的目标是什么?我们希望它能告知我们系统的健康状况及其对上游的影响。我们希望将这些时间点绘制成图表,并在出现异常时触发警报,或者在服务受到影响时与其他数据进行关联。这看起来是个愚蠢的问题,但确保指标确实能回答我们以为它回答的问题,这一点非常重要。 在大多数常见服务中,测量响应时间的方式是相同的:请求到达服务时,服务会记录开始处理的时间。当它准备好将响应发送回客户端时,再次检查时间并与开始时间进行比较。很简单,对吧? --- ## 为 Web API 调用寻找起始点 Web 请求 --- 一个典型应用处理请求的时间远超过一毫秒。它可能需要竞争资源、向其他服务发起子请求、从磁盘读取数据等。一个应用有很多依赖项会影响生成响应所需的时间。 服务从网络读取请求,记录接收时间,然后将其入队或交给其他线程处理。例如,在 Go 应用中,当请求在程序中移动时,许多轻量级线程会不断启动和停止。 --- ## 为 memcached 调用寻找起始点 Web 请求 --- 这里的*开始时间*是关键。memcached 与大多数基础设施软件不同:请求通常在一毫秒内处理完毕。请求负载通常不会改变这个数字!这看起来荒谬,因为我们可以从客户端观察到远高于此的响应时间(在负载较高时)。 *我们测量时间的时间点至关重要*。memcached 一旦从网络套接字读取数据,就会立即处理请求。响应生成得非常快。它首次能测量时间的机会已经接近处理结束。 --- ## 什么影响总时间? Web 请求 大型图像的处理时间会比小型图像长。如果加载商店的产品类别,商品数量越多处理时间越长。它可能会进行多次数据库调用(或者调用 memcached!)来为商品添加尺寸、价格和库存信息。 如果服务器过载会发生什么?它会持续从网络读取请求,在内部创建队列,然后尽力处理吗?还是会拒绝后续请求,让负载均衡器重定向到另一台服务器? memcached 的线程模型是每个 CPU 核心对应一个工作线程。当请求发送到 memcached 时,一个线程会被通知有套接字准备好读取。然后它逐个遍历“就绪”的套接字,从网络读取数据。工作线程之间独立运行,仅共享缓存数据。 --- Web 请求 如果一个工作线程同时有大量套接字需要读取,列表中的*最后一个*套接字将具有最差的响应时间。遗憾的是,我们无法测量请求在队列中等待的时间,只能测量处理请求所花费的时间。无论服务器有多忙,GET 请求所需的时间都是相同的。 当 memcached 过载时会发生什么?请求会停留在操作系统的网络缓冲区中等待读取,而没有任何办法启动计时。现在我们无法回答最初的目标:内部响应时间并不能告诉我们太多信息。最好的情况是,我们浪费了 CPU 资源来跟踪测量。 ## 测量时间如何误导 我确实撒了一点谎:内部响应时间确实会变化。响应时间的问题在于,它无法告诉我们该往哪里看。 - 配置错误?工作线程数超过 CPU 核心数?同时运行的程序太多? - 如果客户端同时发送 100 个请求,每个单独请求只需十分之一毫秒,但客户端可能只有在所有 100 个请求都处理完后才能看到响应。 - 对于 memcached 来说,处理大响应和处理小响应所需的时间相同。但客户端读取和解析一兆字节数据的时间会比一千字节长得多。 - SET 请求在 memcached 中的扩展性较差。非常高的 SET 负载会导致请求时间明显变长……但仅限于 SET 命令!GET 请求仍然卡在网络队列中。 - 当启用 extstore(https://docs.memcached.org/features/flashstorage/)时,我们会使用 SSD 存储,这可能会变慢。这是合理的,我们应该*专门测量等待磁盘的时间*。这能给出一个明确的数字说“磁盘慢了”,而不是一些模糊的信息。 ## 从客户端测量 --- Web 请求 我们建议查看客户端的总响应时间。这样你*确切地*知道对你的服务造成了什么影响。然后你可以与其他指标关联。如果响应时间很高,memcached 的 CPU 使用率是否也很高?网络是否丢包?是否有人在以每秒百万级的速度批量加载数据? 至少对我来说,自上而下关联比自下而上容易得多。如果 memcached 的内部响应时间很高,我们完全不知道上游影响*实际*是什么。 虽然我很想链接一个工具来帮你完成这项工作,但遥测设置种类繁多,很难给出一个简单的答案。希望这在你系统中很容易实现;快速的抽样遥测就能告诉你所需的一切。 我们的文档确实提供了一个用于实验的实用程序:这里讨论了一个连接测试脚本(https://docs.memcached.org/troubleshooting/timeouts/)。 内置的 memcached 代理(https://docs.memcached.org/features/proxy/)也可以通过其日志系统测量采样时间。如果你在应用主机上本地运行代理,将其作为客户端使用,这会很有帮助。 一个指标拥有良好且有价值的信号非常重要。尤其是当我们出问题时首先查看的核心指标,或者作为需要扩展或缩减容量的预测指标。我们仔细检查了基础知识,并找到了一个简单且影响深远的变更。 ## 额外要点:本地测量 为了全面起见,让我们将客户端测量与运行在 memcached 同一服务器上的程序结合起来。这个程序每秒连接并发送一次或几次请求。这种测量很有用,因为它独立于 memcached 外部,并且必须与任何其他请求一样在相同的操作系统队列中等待。上面列出的连接测试器是一个很好的起点。 然后我们可以将其与客户端计时关联。如果时间同时上升,则守护进程负载很可能很高。如果它们出现分歧,则网络更可能是瓶颈。 这个技巧为你提供了一个很好的起点,可以选择一条故障排除路径。 ## 结论 在这篇文章中,我们看到了 memcached 始终如一的轻量级处理时间如何导致常见指标产生误导或毫无用处。我们确保收集的响应时间指标实际关联到系统的健康状况,并展示了对上游用户的影响。希望这能澄清为什么我们不从服务器提供这些指标的疑惑!

相似文章

赞美memcached

Hacker News Top

作者主张使用memcached而非Redis作为缓存层,强调其简单性、易于处理故障、以及直截了当的集群功能,与Redis的功能膨胀以及被误用作持久化数据库的倾向形成对比。

前端缺失的指标:TBT 窗口

Lobsters Hottest

本文介绍了 TBT 窗口这一缺失的前端性能指标概念,它突出显示了从首次内容绘制到可交互时间之间的总阻塞时间,并通过一个案例研究说明,某客户端的 TBT 从 495 毫秒飙升至 5,789 毫秒。

No Slop Grenade

Hacker News Top

Redis与Memcached的比较,涵盖数据结构、性能、可扩展性和运维考量,以帮助选择正确的缓存解决方案。