Ray 开发人员剖析#

本指南可帮助 Ray 项目的贡献者分析 Ray 性能。

获取 Ray C++ 进程的堆栈跟踪#

您可以使用以下 GDB 命令查看任何正在运行的 Ray 进程(例如,raylet)的当前堆栈跟踪。这对于调试 100% CPU 使用率或无限循环很有用(只需运行该命令几次即可查看进程卡在哪里)。

sudo gdb -batch -ex "thread apply all bt" -p <pid>

请注意,您可以使用 `pgrep raylet` 找到 raylet 的 pid。

安装#

这些说明仅适用于 Ubuntu。在 Mac OS 上尝试使 `pprof` 正确符号化已失败。

sudo apt-get install google-perftools libgoogle-perftools-dev

您可能需要安装 `graphviz` 才能让 `pprof` 生成火焰图。

sudo apt-get install graphviz

CPU 剖析#

要以剖析模式启动 Ray 并剖析 Raylet,请定义以下变量

export PERFTOOLS_PATH=/usr/lib/x86_64-linux-gnu/libprofiler.so
export PERFTOOLS_LOGFILE=/tmp/pprof.out
export RAY_RAYLET_PERFTOOLS_PROFILER=1

直到您让二进制文件运行目标工作负载一段时间然后通过 `ray stop` 或让驱动程序退出而 `kill` 它之前,文件 `/tmp/pprof.out` 都是空的。

注意:启用 `RAY_RAYLET_PERFTOOLS_PROFILER` 可以剖析 Raylet 组件。要剖析其他模块,请使用 `RAY_{MODULE}_PERFTOOLS_PROFILER`,其中 `MODULE` 代表进程类型的全大写形式,例如 `GCS_SERVER`。

可视化 CPU 剖析#

您可以通过多种方式可视化 `pprof` 的输出。下面,输出是一个可缩放的 `.svg` 图像,显示了带有热点路径注释的调用图。

# Use the appropriate path.
RAYLET=ray/python/ray/core/src/ray/raylet/raylet

google-pprof -svg $RAYLET /tmp/pprof.out > /tmp/pprof.svg
# Then open the .svg file with Chrome.

# If you realize the call graph is too large, use -focus=<some function> to zoom
# into subtrees.
google-pprof -focus=epoll_wait -svg $RAYLET /tmp/pprof.out > /tmp/pprof.svg

下面是官方文档中示例 SVG 输出的快照

http://goog-perftools.sourceforge.net/doc/pprof-test-big.gif

内存剖析#

要对 Ray 核心组件运行内存剖析,请使用 jemalloc。Ray 支持环境变量,这些环境变量可以在核心组件上覆盖 `LD_PRELOAD`。

您可以在 `ray_constants.py` 中找到组件名称。例如,如果您想剖析 gcs_server,请在 `ray_constants.py` 中搜索 `PROCESS_TYPE_GCS_SERVER`。您会看到其值为 `gcs_server`。

用户应提供 4 个环境变量用于内存剖析。

  • RAY_JEMALLOC_LIB_PATH:jemalloc 共享库 `libjemalloc.so` 的路径

  • RAY_JEMALLOC_CONF:jemalloc 的 MALLOC_CONF 配置,使用逗号分隔的值。有关更多详细信息,请参阅 jemalloc 文档

  • RAY_JEMALLOC_PROFILE:要运行 Jemalloc `.so` 的逗号分隔的 Ray 组件。例如(“raylet,gcs_server”)。请注意,组件应与 `ray_constants.py` 中的进程类型匹配。(这意味着“RAYLET,GCS_SERVER”将不起作用)。

  • RAY_LD_PRELOAD_ON_WORKERS:默认值为 `0`,这意味着如果库与 Jemalloc 不兼容,Ray 不会为工作进程预加载 Jemalloc。设置为 `1` 可指示 Ray 使用 `RAY_JEMALLOC_LIB_PATH` 和 `RAY_JEMALLOC_PROFILE` 配置的值为工作进程预加载 Jemalloc。

# Install jemalloc
wget https://github.com/jemalloc/jemalloc/releases/download/5.2.1/jemalloc-5.2.1.tar.bz2
tar -xf jemalloc-5.2.1.tar.bz2
cd jemalloc-5.2.1
export JEMALLOC_DIR=$PWD
./configure --enable-prof --enable-prof-libunwind
make
sudo make install

# Verify jeprof is installed.
which jeprof

# Start a Ray head node with jemalloc enabled.
# (1) `prof_prefix` defines the path to the output profile files and the prefix of their file names.
# (2) This example only profiles the GCS server component.
RAY_JEMALLOC_CONF=prof:true,lg_prof_interval:33,lg_prof_sample:17,prof_final:true,prof_leak:true,prof_prefix:$PATH_TO_OUTPUT_DIR/jeprof.out \
RAY_JEMALLOC_LIB_PATH=$JEMALLOC_DIR/lib/libjemalloc.so \
RAY_JEMALLOC_PROFILE=gcs_server \
ray start --head

# Check the output files. You should see files with the format of "jeprof.<pid>.0.f.heap".
# Example: jeprof.out.1904189.0.f.heap
ls $PATH_TO_OUTPUT_DIR/

# If you don't see any output files, try stopping the Ray cluster to force it to flush the
# profile data since `prof_final:true` is set.
ray stop

# Use jeprof to view the profile data. The first argument is the binary of GCS server.
# Note that you can also use `--pdf` or `--svg` to generate different formats of the profile data.
jeprof --text $YOUR_RAY_SRC_DIR/python/ray/core/src/ray/gcs/gcs_server $PATH_TO_OUTPUT_DIR/jeprof.out.1904189.0.f.heap

# [Example output]
Using local file ../ray/core/src/ray/gcs/gcs_server.
Using local file jeprof.out.1904189.0.f.heap.
addr2line: DWARF error: section .debug_info is larger than its filesize! (0x93f189 vs 0x530e70)
Total: 1.0 MB
    0.3  25.9%  25.9%      0.3  25.9% absl::lts_20230802::container_internal::InitializeSlots
    0.1  12.9%  38.7%      0.1  12.9% google::protobuf::DescriptorPool::Tables::CreateFlatAlloc
    0.1  12.4%  51.1%      0.1  12.4% ::do_tcp_client_global_init
    0.1  12.3%  63.4%      0.1  12.3% grpc_core::Server::Start
    0.1  12.2%  75.6%      0.1  12.2% std::__cxx11::basic_string::_M_assign
    0.1  12.2%  87.8%      0.1  12.2% std::__cxx11::basic_string::_M_mutate
    0.1  12.2% 100.0%      0.1  12.2% std::__cxx11::basic_string::reserve
    0.0   0.0% 100.0%      0.8  75.4% EventTracker::RecordExecution
...

运行微基准测试#

要运行一组单节点 Ray 微基准测试,请使用

ray microbenchmark

您可以在 GitHub 发行日志中找到 Ray 发行版的微基准测试结果。

参考文献#