RPC 系列(三十一):bvar 与性能指标

bvar 是多线程环境下的计数器类库,方便记录和查看用户程序中的各类数值。它利用了 thread local 存储减少了 cache bouncing,相比 UbMonitor(百度内的老计数器库)几乎不会给程序增加性能开销,也快于竞争频繁的原子操作。

brpc 集成了 bvar,/vars 可查看所有曝光的 bvar,/vars/VARNAME 可查阅某个 bvar,在 brpc 中的使用方法参见 vars 内置服务的说明。brpc 大量使用了 bvar 提供统计数值,当你需要在多线程环境中计数并展现时,应该第一时间想到 bvar。

但 bvar 不能代替所有的计数器,它的本质是把写时的竞争转移到了读:读得合并所有写过的线程中的数据,而不可避免地变慢了。当你读写都很频繁或得基于最新值做一些逻辑判断时,你不应该用 bvar。

原理与开销

为了理解 bvar 的原理,可以从 Cacheline(缓存行)一节提到的计数器例子入手:当很多线程都在累加一个计数器时,每个线程只累加私有的变量而不参与全局竞争,在读取时累加所有线程的私有变量。虽然读比之前慢多了,但由于这类计数器的读多为低频的记录和展现,慢点无所谓。而写就快多了,极小的开销使得用户可以无顾虑地使用 bvar 监控系统,这便是设计 bvar 的目的。

下图是 bvar 和原子变量、静态 UbMonitor、动态 UbMonitor 在被多个线程同时使用时的开销。可以看到 bvar 的耗时基本和线程数无关,一直保持在极低的水平(约 20 纳秒)。而动态 UbMonitor 在 24 核时每次累加的耗时达 7 微秒,这意味着使用 300 次 bvar 的开销才抵得上使用一次动态 UbMonitor 变量。

bvar、原子变量与静态/动态 UbMonitor 在不同线程数下的累加开销对比:bvar 基本恒定在 20 纳秒左右,动态 UbMonitor 在 24 线程时接近 7 微秒

增加 C++ bvar

增加 C++ bvar 的方法可见 bvar 的快速介绍。bvar 默认统计了进程、系统的一些变量,以 process_、system_ 等开头,比如:

process_context_switches_involuntary_second : 14
process_context_switches_voluntary_second : 15760
process_cpu_usage : 0.428
process_cpu_usage_system : 0.142
process_cpu_usage_user : 0.286
process_disk_read_bytes_second : 0
process_disk_write_bytes_second : 260902
process_faults_major : 256
process_faults_minor_second : 14
process_memory_resident : 392744960
system_core_count : 12
system_loadavg_15m : 0.040
system_loadavg_1m : 0.000
system_loadavg_5m : 0.020

还有像 brpc 内部的各类计数器:

bthread_switch_second : 20422
bthread_timer_scheduled_second : 4
bthread_timer_triggered_second : 4
bthread_timer_usage : 2.64987e-05
bthread_worker_count : 13
bthread_worker_usage : 1.33733
bvar_collector_dump_second : 0
bvar_collector_dump_thread_usage : 0.000307385
bvar_collector_grab_second : 0
bvar_collector_grab_thread_usage : 1.9699e-05
bvar_collector_pending_samples : 0
bvar_dump_interval : 10
bvar_revision : "34975"
bvar_sampler_collector_usage : 0.00106495
iobuf_block_count : 89
iobuf_block_count_hit_tls_threshold : 0
iobuf_block_memory : 729088
iobuf_newbigview_second : 10

导出与监控

打开 bvar 的 dump 功能可以导出所有的 bvar 到文件,格式就如上文一样,每行是一对”名字:值”。打开 dump 功能后应检查 monitor/ 目录下是否有数据,比如:

$ ls monitor/
bvar.echo_client.data  bvar.echo_server.data

$ tail -5 monitor/bvar.echo_client.data
process_swaps : 0
process_time_real : 2580.157680
process_time_system : 0.380942
process_time_user : 0.741887
process_username : "gejun"

每次导出都会覆盖之前的文件,这与普通 log 添加在后面是不同的。

监控系统应定期搜集每台单机导出的数据,并把它们汇总到一起。这里以百度内的 noah 为例,bvar 定义的变量会出现在 noah 的指标项中,用户可勾选并查看历史曲线。

使用 Prometheus 时,将其抓取 url 地址的路径设置为 /brpc_metrics 即可。例如 brpc server 跑在本机的 8080 端口,则抓取 url 配置为 127.0.0.1:8080/brpc_metrics。

系列导航


   转载规则


《RPC 系列(三十一):bvar 与性能指标》 由 吴杭沉 采用 知识共享署名 4.0 国际许可协议 进行许可。
 上一篇
RPC 系列(三十二):brpc 的 vars 变量 RPC 系列(三十二):brpc 的 vars 变量
bvar 是多线程环境下的计数器类库,方便记录和查看用户程序中的各类数值,它利用了 thread local 存储减少了 cache bouncing,相比 UbMonitor(百度内的老计数器库)几乎不会给程序增加性能开销,也快于竞争频繁
2024-04-09
下一篇 
RPC 系列(三十):用 rpcz 观测 RPC RPC 系列(三十):用 rpcz 观测 RPC
用户能通过 /rpcz 看到最近请求的详细信息,并可以插入注释(annotation)。不同于 tracing system(如 Dapper)以全局视角看到整体系统的延时分布,rpcz 更多是一个调试工具。虽然角色有所不同,但在 brpc
2024-03-26
  目录