系统与基础设施eng.uber.com
我们如何用 Go 构建 Uber 每秒查询数最高的服务
How We Built Uber’s Highest Query per Second Service Using Go
2016 — 2019,它一次次回到首页
黑点是上首页(≥ 50 分)的那次投稿,空心点是没冲上去的投稿,点越大分数越高。
导读
这是 Uber 工程博客的一篇经典文章,介绍他们用 Go 实现的、号称公司内 QPS 最高的服务——为 Uber 移动端每次请求提供地理围栏(geofence)查询。文中说 2015 年跨年夜峰值达 170k QPS、40 台机器 CPU 占用 35%,p95 延迟低于 5ms、p99 低于 50ms;他们放弃了 R-tree 和 S2,改用一种把候选围栏数量从上万降到上百的简化方案。文章重点讲了 Go 的并发模型与 GC 调优,但社区普遍质疑:真正的性能来源是算法选择而非语言。
为什么经久不衰:它成了「语言 vs 算法」争论的经典样本,后来还有专文反驳其索引方案,多年后仍是学习地理空间索引和高并发服务设计的反面/正面教材。
HN 评论精选
自建 R-tree 服务在笔记本上就达到 15K QPS,性能关键在于数据结构而非 Go。
我不觉得从这篇文章里学到了什么。有意思的是 HN 上的关键词抓取得真快(Uber 和 Go)。三年多前我们就实现过一个反向地理编码 Web 服务,索引了完整的 Census TIGER 数据集,在一台 2011 年的 MacBook 上扛住 15K 请求/秒,而且是精确的多边形内搜索(没有近似),用的是为多边形内搜索优化的 R-tree 结构。假设 Uber 的地理围栏查询数据集比 TIGER 小得多,我认为本可以用少得多的资源做出高效得多的实现。再说一遍,用 Go 与此无关。
emrekzd查看英文原文
I don't think I've learned anything from this article. It's interesting how quickly the keywords pick up on HN (Uber and Go). More than 3 years ago we've implemented a reverse geocoder web-service that indexed complete Census TIGER dataset. The service handled over 15K reqs/sec on a 2011 macbook, doing exact in polygon search(no approximations). We implemented an optimized (for in polygon search) R-tree data structure for the lookups. Assuming Uber's geofence lookups would rely on a much smaller dataset than TIGER, I think you could have come up with a much more efficient implementation requiring a fraction of the resources. And again, use of Go; irrelevant.
文章论证不充分,语言选择和 channel 的取舍都缺乏证据。
这篇文章对我来说有点含糊其辞。本质上他们可以用任何语言实现这个服务,也没有证据说明为什么不能用 channel。多给点细节才能让它成为一篇好文章,至少对我来说是这样。
StreamBright查看英文原文
This article is a little bit hand-wavy for me. Essentially they could use any languages to implement this, also there is no proof how channels could not be used. I bit more details would be essential to make this a good read, at least for me.
刻意回避复杂索引却谈语言性能,缺乏基准对比,算法选择才是重点。
「我们没有用 R-tree 或复杂的 S2 来建索引,而是选择了更简单的路线……」「虽然这个方案的运行时复杂度仍是 O(N),但这种简单技巧把 N 从数万量级降到了数百量级。」让我觉得奇怪的是,他们明明在谈 Go 的性能,却因为更好的算法「太复杂」而故意选了次优的。或者,如果他们的简化方案确实比 R-tree 或 S2 更快,那就该给出基准测试和更清楚的解释。在这种场景下,选对算法比选语言更重要。
chris_overseas查看英文原文
"Instead of indexing the geofences using R-tree or the complicated S2, we chose a simpler route..." "While the runtime complexity of the solution remains O(N), this simple technique reduced N from the order of 10,000s to the order of 100s." It seems odd to me that they're posting about the performance of Go, yet they deliberately chose a less optimal algorithm because the better ones were "complicated". Or, if their simpler approach did in fact run faster than R-trees or S2, it would have been nice to see some benchmarks and a clearer explanation for why. Choosing the best algorithm seems more important than the language in a case like this one.
直指实现低效,并引用专文用 R-tree 对比证明。
这是一个非常低效的实现。说实话整体质量不高,任何对空间索引有基本了解的人都清楚 R-tree 会快很多倍,正如这里所示:https://medium.com/@buckhx/unwinding-uber-s-most-efficient-service-406413c5871d
woeirua查看英文原文
This is a very inefficient implementation. Really, just poor quality work overall, as anyone with even a basic understanding of spatial indexing would know that an R-tree would be many times faster, as illustrated here: https://medium.com/@buckhx/unwinding-uber-s-most-efficient-service-406413c5871d
总预算 100ms 而单服务 p99 占 50ms,这个数字并不值得夸耀。
「吞吐和延迟都很高。仅服务非中国流量时,这个服务在 2015 年跨年夜峰值处理 170k QPS,40 台机器 CPU 占用 35%。响应时间 p95 低于 5ms,p99 低于 50ms。」「Uber 移动端每个请求都需要地理围栏查询,必须快速响应(p99 低于 100 毫秒)。」在总共 100ms 的预算里,单个微服务的 p99 就要 50ms,这似乎没什么好炫耀的。
hobofan查看英文原文
> High performance in throughput and latency. In our main data center serving non-China traffic alone, this service handled a peak load of 170k QPS with 40 machines running at 35% CPU usage on NYE 2015. The response time was < 5 ms at 95th percentile, and < 50 ms at the 99th percentile. > Geofence lookups are required on every request from Uber’s mobile apps and must quickly (99th percentile < 100 milliseconds) answer For a 100ms total budget, a ~50ms 99th percentile for a single microservice doesn't sound like something to boast about.
历次讨论
同类还值得读
TTY 揭秘(2008)
The TTY demystified (2008)
经典文章深入剖析了 Unix/Linux 中 TTY 子系统的工作原理,包括线路规程、终端驱动、信号与控制字符等机制。
系统与基础设施上首页 11 次 · 2009–2025linusakesson.net编辑精选为什么 GNU grep 这么快
Why GNU grep is Fast
FreeBSD 邮件列表上一篇广为流传的帖子,解释 GNU grep 为什么快:核心在于 Boyer-Moore 字符串搜索算法配合精心优化的内部循环和 I/O,让程序在搜索时“…
系统与基础设施上首页 9 次 · 2010–2022lists.freebsd.orgXplain:为普通人讲解 X11
Xplain – Explaining X11 for the rest of us
《Xplain》是作者(HN 用户 Jasper_)写的一系列 X11 长文,用他在浏览器中重建的 X11 绘图模型做交互演示,讲解 X11 的绘图模型与窗口系统设计。
系统与基础设施上首页 6 次 · 2013–2020magcius.github.io编辑精选旋风教程:为 Linux 创建极小 ELF 可执行文件(1999)
A Whirlwind Tutorial on Creating Really Teensy ELF Executables for Linux (1999)
breadbox 写于 1999 年的经典教程,主题是如何为 Linux 手工构造并裁剪出体积极小的 ELF 可执行文件。
系统与基础设施上首页 6 次 · 2007–2025muppetlabs.comPostgreSQL 内部原理
The internals of PostgreSQL
《The Internals of PostgreSQL》是一本免费在线书籍,系统讲解 PostgreSQL 的内部实现,包括查询处理、并发控制、WAL、缓冲区管理等核心机制。
系统与基础设施上首页 5 次 · 2017–2025interdb.jp编辑精选