听说 Chromium 里有个直方图

2025-04-03 pv

最近工作中经常使用 Chromium 里 Histogram 这个工具。

这是一个 Telemetry 机制,可用于统计、调试,甚至性能分析。

不可否认,Chromium 是一个广泛使用,且内部实现相当复杂的巨型工程项目。没有人能保证自己写的代码一定正确。

Bug 一定存在。

重要的不是假装它不存在,而是如何快速地识别、调试并解决(Identify, debug, and resolve)

因此今天这篇文章,打算从 Histogram 的设计理念出发,探讨实现的方式,以及我们该如何理解可观测性(Observability)。

1. 设计理念

对于单用户问题,在不同平台上有着很多经典的工具。比如性能分析,Linux 有 Perf,Windows 有 Windows Performance Toolkit 等。

但对于群体问题,传统的工具便会失效。

怎么判断某个函数被调用的频次,某个关键操作的耗时分布如何,更常规的,DAU (Daily Active User,日活跃用户数)怎么统计。

Chromium Histogram 提供了一套跨平台、分布式的数据采集方案

功能上的定位,有点类似前端领域的 Sentry🔗

Histogram 的设计目标是:

  • 高性能采样(无需锁)
  • 支持多种数据类型(布尔、计数器、枚举、延迟等)
  • 自动分桶和分位分析
  • 精准的数据聚合和上传

2. 实现

Chromium Histogram 的关键部分有三个:

  • 埋点
  • 采样
  • 上传

2.1 埋点

首先,Chromium 提供了多种类型的 Histogram,用于记录不同的数据类型。

类型描述
BooleanUMA_HISTOGRAM_BOOLEAN记录 true/false 的分布
EnumerationUMA_HISTOGRAM_ENUMERATION记录枚举类型的取值情况
Custom CountsUMA_HISTOGRAM_CUSTOM_COUNTS自定义区间和 bucket,用于记录计数(比如网络包大小)
TimesUMA_HISTOGRAM_TIMES记录时间类型,支持微秒到秒
SparseUMA_HISTOGRAM_SPARSE_SLOWLY用于高稀疏度的整数数据统计

2.2 采样

Histogram 底层的数据存储,是一个多级桶(bucket)。

类似:

struct Histogram {
std::string name;
int min;
int max;
int bucket_count;
std::vector<int> counts;
};

不同的数据类型,分桶的策略也有所差异。这样可以降低存储开销,并提高采样分布的清晰度

类型桶布局示例用途
LinearHistogram等距计数类事件
ExponentialHistogram对数时间延迟、网络 RTT
CustomHistogram手动指定特殊值域分布(如视频帧率)

Add() 的计数是原子的,线程安全且高效。

每个进程都有一个 HistogramBase 实例,并实现了延迟实例化(Lazy Initialization)。多进程埋点不冲突。

2.3 上传

Histogram 记录的数据不会实时上传。因为有一个采样缓存机制

  1. 所有注册的 Histogram 都由 StatisticsRecorder(只在 Browser 进程) 统一管理

  2. 触发上传时,所有 Histogram 数据被序列化(HistogramSnapshotManager

  3. 数据通过 UKMUMA、或者 DevTools 的 chrome://histograms 页面输出

跨进程的 Histogram 数据共享则是借助 PersistentMemoryAllocator

具体工作流程如下:

+-----------------+ +--------------------------+
| Renderer 进程 | | Browser 主进程 |
|-----------------| |--------------------------|
| Histogram::Add | | |
| PersistentHistogram (写入共享内存) | |
| ↓ | | |
| PersistentMemoryAllocator | |
| | | |
+-----------------+ | |
| StatisticsRecorder |
| ↓ |
| ImportGlobalPersistentHistograms()|
| ↓ |
| 合并数据并上传 UMA |
+--------------------------+

3. 启发

对于开发者,使用 Histogram 打点是简单的。

正是由于它的简洁性和高性能,在尽可能减小对软件性能影响的同时,提高了开发者对于一个复杂系统内部运行过程的观测能力。

系统越透明,失控的可能性越小

If you can not measure it, you can not improve it.

如果你不能衡量它,你就无法改进它。

4. 总结

我喜欢简单的东西。

无论是道理,还是 App。

简单本身便是一种强大。

好的道理,应该一两句话就能说清楚;好的 App,应该让不识字的儿童都能轻松上手。

当然,能化繁为简的人,往往有着对事物异于常人的洞察。

这是简单背后的不简单

(完)

参考

  1. Histogram Guidelines🔗
  2. Application Performance Monitoring & Error Tracking Software | Sentry🔗
在 GitHub 上编辑本页面

最后更新于: 2025-04-11T06:47:04+08:00