Skip to content

SST File Online Benchmark

rockeet edited this page Feb 28, 2024 · 8 revisions

SST 文件在线性能测试

db_bench 可以对 DB 进行多项测试,但是它的数据源是随机生成数据。

另一方面,普通的的性能测试,是在整个 DB 的层面进行全链路测试,无法细化深入到单个 SST。

之前,我们在 ToplingDB 的 WebView 增加了查看单个 SST 文件的内部结构的功能,支持 Topling 的各种 SST, 也支持 BlockBasedTable。

最近(2023-03-03)我们在 SST 文件的 WebView 上增加了在线 Benchmark 功能,可对 SST 进行多项性能测试。

image

| scan | rev scan | scan value | seek | seek value | rand value

从 SST 的 TableReader 创建 Iterator 进行测试,url 中 增添了以下参数:

参数名 类型 默认值 描述
bench enum 可选值有: {scan,seek}
repeat int 1 重复次数,整个 Benchmark 的重复次数,不是单个操作的重复次数
reverse bool 0 正向扫描或反向扫描,在 scan 和 seek 中均有效
rand bool 0 仅在 seek 时有效,先将整个 SST 的 Key 全部加载到一个 StrVec,然后随机 Shuffle 这个 StrVec,再顺序遍历 StrVec 并执行 Seek
point注1 bool 1 特殊参数,仅在 bench=seek, rand=1 且 fecth_value <= 1 时有效,并且仅对 ToplingZipTable 有意义
fetch_value int 0 bench=scan 时,类型为 bool,表示扫描时是否读取 value
bench=seek注2 且 rand 为 true 时,表示 seek 到一个位置之后,总共顺序读取多少个 KV

注1: point 参数,因为 ToplingZipTable 使用专利的 PForDelta 变体压缩 value 的 offset(value 长度为相邻 offset 求差),Iterator 按块解压 PForDelta,对于随机 Seek,解压出来的整个块中有效数据只有两条,该 PForDelta 变体可以高效地每次只解压两条数据,从而大幅提升点查的性能,point=1 时,将不会调用 iter->Seek,而是调用 iter->PointGet 以实现前述功能,PointGet 的默认行为是通过 Seek 实现的,从而适配 ToplingZipTable 之外的其它 SST

注2: 当 fetch_value > 1 时,seek 次数 = ${entries}\over{fetch\_value}$, 其中 entries 指该 SST 文件中总的 KV 数量, seek 之后,再根据 reverse 参数,前进(Next)或后退(Prev) fetch_value-1 次,总共访问 fetch_value 个 KV

bench=seek 且 rand=1 时,输出表格,其它情况下是简单文字输出

快捷方式

各个链接按钮是上述 url 参数的一些组合的快捷方式:

链接 参数组合 描述
scan bench=scan 顺序正向扫描,不取 value
rev scan bench=scan&reverse=1 顺序反向扫描,不取 value
scan value bench=scan&fetch_value=1 顺序正向扫描,读取 value
seek bench=seek seek, 不取 value
seek value bench=seek&fetch_value=1 seek, 读取 value
rand value bench=seek&fetch_value=1&rand=1 随机 point get

要测试 seek 到一个随机点,再正向/反向扫描若干步,需要自行输入 url 参数(可以用rand value链接作为模板进行修改)

BlockBasedTable 与 ToplingZipTable

该性能测试中 fetch_value 是通过 iter->PrepareValue() 实现的。

BlockBasedTable 的 PrepareValue 是按 Block 读取的:当 iter 位于一个 Block 的起始位置时,一次性读取/解压整个 Block,后续读到该 Block 的其它 value 时,就啥都不用做了。这种处理方式,会导致 fetch_value 阶段耗时接近于 0。

ToplingZipTable 的 PrepareValue 则忠实地读取每条 value

  • 如果没有压缩,就使用 Zero Copy 直接返回 SST 文件的 mmap 中该 value 对应的内存区间
  • 如果 value 是压缩的,则现场解压该 value,解压吞吐率一般在每秒 1GB 以上
    • 因为现场解压足够快,这种处理方式才是可行的,例如单条数据 500 字节,现场解压就只需要 500 纳秒

Topling 的其它 SST 都没有压缩,PrepareValue 都是 Zero Copy