注意

本文档适用于 Ceph 的开发版本。

Crimson 开发人员文档

有关更多信息,请参阅 Crimson 用户指南

构建 Crimson

Crimson 默认不启用。在构建时通过运行以下命令启用它:

$ WITH_CRIMSON=true ./install-deps.sh
$ ./do_cmake.sh -DWITH_CRIMSON=ON

请注意,如果使用 git 克隆的源代码构建 Crimson,ASan 默认启用。

vstart.sh

注意

当使用 --crimson 时,vstart.sh 会自动启用 crimson Crimson 必要标志

以下选项可与 vstart.sh 一起使用。

--crimson

启动 crimson-osd 而不是 ceph-osd

--nodaemon

不将服务守护进程化。

--redirect-output

stdoutstderr 重定向到 out/$type.$num.stdout

--osd-args

crimson-osdceph-osd 传递额外的命令行选项。这对于向 crimson-osd 传递 Seastar 选项很有用。例如,可以提供 --osd-args "--memory 2G" 来设置要使用的内存量。请参考

crimson-osd --help-seastar

以获取额外的 Seastar 特定的命令行选项。

--crimson-smp

每个 OSD 要使用的核心数。如果使用 BlueStore,则可用核心的剩余部分(由 nproc 确定)将分配给对象存储。

--bluestore

使用 alienized BlueStore 作为对象存储后端。这是默认设置(有关详细信息,请参阅上面关于 Crimson 的对象存储后端 的部分)

--cyanstore

使用 CyanStore 作为对象存储后端。

--memstore

使用 alienized MemStore 作为对象存储后端。

--seastore

使用 SeaStore 作为后端对象存储。

--seastore-devs

指定 SeaStore 使用的块设备。

--seastore-secondary-devs

可选。SeaStore 支持多个设备。通过向此选项传递块设备来启用此功能。

--seastore-secondary-devs-type

可选。指定辅助设备的类型。当辅助设备比传递给 --seastore-devs 的主设备慢时,较快设备上的冷数据将随着时间的推移迁移到较慢的设备。有效类型包括 HDDSSD``(default)、 ``ZNSRANDOM_BLOCK_SSD。请注意,辅助设备不应比主设备快。

要启动一个包含单个 Crimson 节点的集群,请运行

$  MGR=1 MON=1 OSD=1 MDS=0 RGW=0 ../src/vstart.sh \
  --without-dashboard --bluestore --crimson \
  --redirect-output

另一个 SeaStore 示例

$  MGR=1 MON=1 OSD=1 MDS=0 RGW=0 ../src/vstart.sh -n -x \
  --without-dashboard --seastore \
  --crimson --redirect-output \
  --seastore-devs /dev/sda \
  --seastore-secondary-devs /dev/sdb \
  --seastore-secondary-devs-type HDD

通过运行以下命令停止此 vstart 集群

$ ../src/stop.sh --crimson

守护进程化 (daemonize)

ceph-osd 不同,crimson-osd 不会自行守护进程化,即使启用了 daemonize 选项也是如此。为了读取此选项,crimson-osd 需要准备其分片服务配置,但此分片服务位于 Seastar reactor 中。如果我们在启动 Seastar 引擎后派生一个子进程并退出父进程,那将只剩下一个线程,它是调用 fork() 的线程的副本。在 Crimson 中解决这个问题会不必要地使代码复杂化。

由于受支持的 GNU/Linux 发行版使用能够守护进程化进程的 systemd,因此无需自行守护进程化。使用 sysvinit 的人可以使用 start-stop-daemon 来守护进程化 crimson-osd。如果这不起作用,可以设计一个辅助工具。

日志记录 (logging)

Crimson-osd 目前使用 Seastar 提供的日志记录实用程序。有关 Ceph 日志记录级别与 Seastar 中严重性级别的映射,请参阅 src/common/dout.h。例如,发送到 derr 的消息将使用 logger::error() 发出,调试级别大于 20 的消息将使用 logger::trace() 发出。

ceph

seastar

< 0

error

0

warn

[1, 6)

info

[6, 20]

debug

> 20

trace

请注意,crimson-osd 不会直接将日志消息发送到指定的 log_file。它将日志消息写入 stdout 和/或 syslog。可以使用 --log-to-stdout--log-to-syslog 命令行选项更改此行为。默认情况下,--log-to-stdout 已启用,--log-to-syslog 已禁用。

分析 Crimson

Fio

crimson-store-nbd 将可配置的 FuturizedStore 内部结构公开为 NBD 服务器,供 fio 使用。

要使用 fio 测试 crimson-store-nbd,请执行以下步骤。

  1. 您需要安装 libnbd,并将其编译到 fio

    apt-get install libnbd-dev
    git clone git://git.kernel.dk/fio.git
    cd fio
    ./configure --enable-libnbd
    make
    
  2. 构建 crimson-store-nbd

    cd build
    ninja crimson-store-nbd
    
  3. 使用块设备运行 crimson-store-nbd 服务器。指定原始设备的路径,例如 /dev/nvme1n1,而不是创建的文件,用于使用块设备进行测试。

    export disk_img=/tmp/disk.img
    export unix_socket=/tmp/store_nbd_socket.sock
    rm -f $disk_img $unix_socket
    truncate -s 512M $disk_img
    ./bin/crimson-store-nbd \
      --device-path $disk_img \
      --smp 1 \
      --mkfs true \
      --type transaction_manager \
      --uds-path ${unix_socket} &
    

    下面是这些命令行参数的描述

    --smp

    要使用的 CPU 核心数(对称多处理器)

    --mkfs

    首先初始化设备。

    --type

    要使用的后端。如果指定 transaction_manager,则使用 SeaStore 的 TransactionManagerBlockSegmentManager 来模拟块设备。否则,此选项用于选择 FuturizedStore 的后端,其中整个“设备”被划分为多个固定大小的对象,其大小由 --object-size 指定。因此,如果您只对测试 SeaStore 的较低级别实现(如逻辑地址转换层和垃圾回收)而不需要对象存储语义感兴趣,那么 transaction_manager 将是更好的选择。

  4. 创建名为 nbd.fiofio 作业文件

    [global]
    ioengine=nbd
    uri=nbd+unix:///?socket=${unix_socket}
    rw=randrw
    time_based
    runtime=120
    group_reporting
    iodepth=1
    size=512M
    
    [job0]
    offset=0
    
  5. 使用刚刚构建的自定义 fio 测试 Crimson 对象存储

    ./fio nbd.fio
    

CBT

我们可以使用 cbt 进行性能测试

$ git checkout main
$ make crimson-osd
$ ../src/script/run-cbt.sh --cbt ~/dev/cbt -a /tmp/baseline ../src/test/crimson/cbt/radosbench_4K_read.yaml
$ git checkout yet-another-pr
$ make crimson-osd
$ ../src/script/run-cbt.sh --cbt ~/dev/cbt -a /tmp/yap ../src/test/crimson/cbt/radosbench_4K_read.yaml
$ ~/dev/cbt/compare.py -b /tmp/baseline -a /tmp/yap -v
19:48:23 - INFO     - cbt      - prefill/gen8/0: bandwidth: (or (greater) (near 0.05)):: 0.183165/0.186155  => accepted
19:48:23 - INFO     - cbt      - prefill/gen8/0: iops_avg: (or (greater) (near 0.05)):: 46.0/47.0  => accepted
19:48:23 - WARNING  - cbt      - prefill/gen8/0: iops_stddev: (or (less) (near 0.05)):: 10.4403/6.65833  => rejected
19:48:23 - INFO     - cbt      - prefill/gen8/0: latency_avg: (or (less) (near 0.05)):: 0.340868/0.333712  => accepted
19:48:23 - INFO     - cbt      - prefill/gen8/1: bandwidth: (or (greater) (near 0.05)):: 0.190447/0.177619  => accepted
19:48:23 - INFO     - cbt      - prefill/gen8/1: iops_avg: (or (greater) (near 0.05)):: 48.0/45.0  => accepted
19:48:23 - INFO     - cbt      - prefill/gen8/1: iops_stddev: (or (less) (near 0.05)):: 6.1101/9.81495  => accepted
19:48:23 - INFO     - cbt      - prefill/gen8/1: latency_avg: (or (less) (near 0.05)):: 0.325163/0.350251  => accepted
19:48:23 - INFO     - cbt      - seq/gen8/0: bandwidth: (or (greater) (near 0.05)):: 1.24654/1.22336  => accepted
19:48:23 - INFO     - cbt      - seq/gen8/0: iops_avg: (or (greater) (near 0.05)):: 319.0/313.0  => accepted
19:48:23 - INFO     - cbt      - seq/gen8/0: iops_stddev: (or (less) (near 0.05)):: 0.0/0.0  => accepted
19:48:23 - INFO     - cbt      - seq/gen8/0: latency_avg: (or (less) (near 0.05)):: 0.0497733/0.0509029  => accepted
19:48:23 - INFO     - cbt      - seq/gen8/1: bandwidth: (or (greater) (near 0.05)):: 1.22717/1.11372  => accepted
19:48:23 - INFO     - cbt      - seq/gen8/1: iops_avg: (or (greater) (near 0.05)):: 314.0/285.0  => accepted
19:48:23 - INFO     - cbt      - seq/gen8/1: iops_stddev: (or (less) (near 0.05)):: 0.0/0.0  => accepted
19:48:23 - INFO     - cbt      - seq/gen8/1: latency_avg: (or (less) (near 0.05)):: 0.0508262/0.0557337  => accepted
19:48:23 - WARNING  - cbt      - 1 tests failed out of 16

在这里,我们针对两个分支编译并运行相同的测试:mainyet-another-pr。然后我们比较结果。对于每个测试用例,都定义了一组规则来检查比较测试结果集时的性能退化。如果发现可能的退化,则突出显示该规则和相应的测试结果。

Hacking Crimson

Seastar 文档

请参阅 Seastar 教程。或者构建一个可浏览的版本并启动一个 HTTP 服务器

$ cd seastar
$ ./configure.py --mode debug
$ ninja -C build/debug docs
$ python3 -m http.server -d build/debug/doc/html

事先安装 pandoc 和其他依赖项。

调试 Crimson

使用 GDB 调试

调试 Scylla 的 提示 也适用于 Crimson。

使用 addr2line 获取人类可读的堆栈跟踪

当 Seastar 应用程序崩溃时,它会给我们留下一个地址的堆栈跟踪,例如

Segmentation fault.
Backtrace:
  0x00000000108254aa
  0x00000000107f74b9
  0x00000000105366cc
  0x000000001053682c
  0x00000000105d2c2e
  0x0000000010629b96
  0x0000000010629c31
  0x00002a02ebd8272f
  0x00000000105d93ee
  0x00000000103eff59
  0x000000000d9c1d0a
  /lib/x86_64-linux-gnu/libc.so.6+0x000000000002409a
  0x000000000d833ac9
Segmentation fault

Seastar 提供的 seastar-addr2line 实用程序可用于将这些地址映射到函数。该脚本期望在 stdin 上输入,因此我们需要复制并粘贴上述地址,然后在终端中输入 control-D 发送 EOF。可以使用 echocat 来代替

$ ../src/seastar/scripts/seastar-addr2line -e bin/crimson-osd

  0x00000000108254aa
  0x00000000107f74b9
  0x00000000105366cc
  0x000000001053682c
  0x00000000105d2c2e
  0x0000000010629b96
  0x0000000010629c31
  0x00002a02ebd8272f
  0x00000000105d93ee
  0x00000000103eff59
  0x000000000d9c1d0a
  0x00000000108254aa
[Backtrace #0]
seastar::backtrace_buffer::append_backtrace() at /home/kefu/dev/ceph/build/../src/seastar/src/core/reactor.cc:1136
seastar::print_with_backtrace(seastar::backtrace_buffer&) at /home/kefu/dev/ceph/build/../src/seastar/src/core/reactor.cc:1157
seastar::print_with_backtrace(char const*) at /home/kefu/dev/ceph/build/../src/seastar/src/core/reactor.cc:1164
seastar::sigsegv_action() at /home/kefu/dev/ceph/build/../src/seastar/src/core/reactor.cc:5119
seastar::install_oneshot_signal_handler<11, &seastar::sigsegv_action>()::{lambda(int, siginfo_t*, void*)#1}::operator()(int, siginfo_t*, void*) const at /home/kefu/dev/ceph/build/../src/seastar/src/core/reactor.cc:5105
seastar::install_oneshot_signal_handler<11, &seastar::sigsegv_action>()::{lambda(int, siginfo_t*, void*)#1}::_FUN(int, siginfo_t*, void*) at /home/kefu/dev/ceph/build/../src/seastar/src/core/reactor.cc:5101
?? ??:0
seastar::smp::configure(boost::program_options::variables_map, seastar::reactor_config) at /home/kefu/dev/ceph/build/../src/seastar/src/core/reactor.cc:5418
seastar::app_template::run_deprecated(int, char**, std::function<void ()>&&) at /home/kefu/dev/ceph/build/../src/seastar/src/core/app-template.cc:173 (discriminator 5)
main at /home/kefu/dev/ceph/build/../src/crimson/osd/main.cc:131 (discriminator 1)

请注意,seastar-addr2line 能够从其输入中提取地址,因此您也可以按如下方式粘贴日志消息

2020-07-22T11:37:04.500 INFO:teuthology.orchestra.run.smithi061.stderr:Backtrace:
2020-07-22T11:37:04.500 INFO:teuthology.orchestra.run.smithi061.stderr:  0x0000000000e78dbc
2020-07-22T11:37:04.501 INFO:teuthology.orchestra.run.smithi061.stderr:  0x0000000000e3e7f0
2020-07-22T11:37:04.501 INFO:teuthology.orchestra.run.smithi061.stderr:  0x0000000000e3e8b8
2020-07-22T11:37:04.501 INFO:teuthology.orchestra.run.smithi061.stderr:  0x0000000000e3e985
2020-07-22T11:37:04.501 INFO:teuthology.orchestra.run.smithi061.stderr:  /lib64/libpthread.so.0+0x0000000000012dbf

与经典的 ceph-osd 不同,Crimson 在处理致命信号(如 SIGSEGVSIGABRT)时不会打印人类可读的堆栈跟踪。对于 stripped binary(去除了符号表的二进制文件)来说,情况也更复杂。因此,我们没有在 Crimson 中植入这些信号的信号处理程序,而是可以使用 script/ceph-debug-docker.sh 来映射堆栈跟踪中的地址

# assuming you are under the source tree of ceph
$ ./src/script/ceph-debug-docker.sh  --flavor crimson master:27e237c137c330ebb82627166927b7681b20d0aa centos:8
....
[root@3deb50a8ad51 ~]# wget -q https://raw.githubusercontent.com/scylladb/seastar/master/scripts/seastar-addr2line
[root@3deb50a8ad51 ~]# dnf install -q -y file
[root@3deb50a8ad51 ~]# python3 seastar-addr2line -e /usr/bin/crimson-osd
# paste the backtrace here

代码演练

目录

由 Ceph 基金会为您呈现

Ceph 文档是由非营利性 Ceph 基金会 资助和托管的社区资源。如果您希望支持这项工作和我们的其他努力,请考虑 立即加入