|
|
@ -1060,7 +1060,9 @@ int main(int argc, char** argv) { |
|
|
|
## 4. 性能测试: |
|
|
|
### 4.1 测试吞吐量和延迟 |
|
|
|
#### 测试内容: |
|
|
|
小 value 场景:value 大小为 10 字节左右 |
|
|
|
1. 并发,10个线程,全部读 |
|
|
|
|
|
|
|
leveldb结果: |
|
|
|
 |
|
|
|
|
|
|
@ -1070,10 +1072,10 @@ KV 分离结果: |
|
|
|
2. 并发,10个线程,全部写 |
|
|
|
|
|
|
|
leveldb结果: |
|
|
|
 |
|
|
|
 |
|
|
|
|
|
|
|
KV 分离结果: |
|
|
|
 |
|
|
|
 |
|
|
|
|
|
|
|
3. 并发,10个线程,一半读,一半写 |
|
|
|
|
|
|
@ -1084,6 +1086,29 @@ leveldb结果: |
|
|
|
KV 分离结果: |
|
|
|
|
|
|
|
 |
|
|
|
|
|
|
|
大 value 场景: value 大小为 4 KB |
|
|
|
|
|
|
|
1. 五个线程,每个线程有 20000 次写入: |
|
|
|
|
|
|
|
KV 分离结果: |
|
|
|
|
|
|
|
 |
|
|
|
|
|
|
|
leveldb 结果: |
|
|
|
|
|
|
|
 |
|
|
|
|
|
|
|
2. 五个线程,每个线程有 5000 次读数据: |
|
|
|
|
|
|
|
KV 分离结果: |
|
|
|
|
|
|
|
 |
|
|
|
|
|
|
|
leveldb 结果: |
|
|
|
|
|
|
|
 |
|
|
|
|
|
|
|
### 4.2 测试写放大 |
|
|
|
参数设置为: |
|
|
|
```` |
|
|
@ -1105,7 +1130,9 @@ CURRENT 内容为: MANIFEST-000008 |
|
|
|
 |
|
|
|
|
|
|
|
**总结:** |
|
|
|
虽然我们的 KV 分离实现与原本的 leveldb 相比读写性能提升不大,甚至有一定幅度的下降,但我们的实现能大幅度降低数据库的写放大。 |
|
|
|
通过上面的测试可以看出,当 value 设置的比较小时,我们的 KV 分离方案性能与原本的leveldb 相比,有一定程度的下降,并且读性能下降较多,是原本的 1/4;但当我们把 value 的大小设置为 4 KB 时,我们的 KV 分离方案性能与原本的 leveldb 相比,读写性能提升非常大,写性能由 13.9 ops/s 提升到 177 ops/s, 提升大概 12 倍,而 读性能由 19.3 ops/s 提升到 972 ops/s,提升更加明显。 |
|
|
|
|
|
|
|
综上所述,当 写入的 value 较小时,我们的 KV 分离方案读写性能比原始版本的 leveldb 要低;但当写入的 value 较大时,我们的 KV 分离版本性能会远远优于原始版本的 leveldb。 |
|
|
|
### 5. 实验中遇到的问题和解决方案 |
|
|
|
1. 对于每一次读取,用户线程先读取lsm tree中key的slot_num下标,然后到slot_page中读取对应的slot内容(**每一个slot都是定长的**),之后再在这个slot中读取value所在的vlog文件号和偏移量offset,之后到对应的vlog文件中读取value。 但是这又带来了一个问题,我们该如何管理slot_page这个文件?当插入新的kv时,我们需要在这个slot_page中分配新的slot,在GC删除某个kv时,我们需要将对应的slot进行释放。 |
|
|
|
|
|
|
|