-
Notifications
You must be signed in to change notification settings - Fork 6
SST File Online Benchmark
db_bench 可以对 DB 进行多项测试,但是它的数据源是随机生成数据。
另一方面,普通的的性能测试,是在整个 DB 的层面进行全链路测试,无法细化深入到单个 SST。
之前,我们在 ToplingDB 的 WebView 增加了查看单个 SST 文件的内部结构的功能,支持 Topling 的各种 SST, 也支持 BlockBasedTable。
最近(2023-03-03)我们在 SST 文件的 WebView 上增加了在线 Benchmark 功能,可对 SST 进行多项性能测试。
| 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 次数 = 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
链接作为模板进行修改)
该性能测试中 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