|
|
@ -584,7 +584,7 @@ InsertOneField:只插一条特定数据的测试(让key<=0, 和批量写入 |
|
|
|
DeleteOneField:只删一条特定数据的测试,功能与单条插入相似,主要用来测试delete。 |
|
|
|
GetOneField:只读一条特定数据的测试,与上面两条对应。 |
|
|
|
|
|
|
|
对于所有涉及随机性的函数,传参一个随机种子。只要随机种子一致,随机生成的内容就一致,相应的读需要和相应的写、删保持一致。此外测试的数据量也是可以修改的。 |
|
|
|
对于所有涉及随机性的函数,传参一个随机种子。只要随机种子一致,随机生成的内容就一致,相应的读需要和相应的写、删保持一致。此外测试的数据量也是可以修改的。需要注意的是,之前项目使用的srand线程不安全,使用std::mt19937可以保证多线程时随机序列也一致。 |
|
|
|
|
|
|
|
InsertFieldData:批量写入,按照上面提到的测试规则生成kv,并调用putfields。检查返回状态是否ok。同时对于生成的字段,如果是address为shanghai或age为20,统计入相应的set。 |
|
|
|
|
|
|
@ -612,7 +612,8 @@ TestLab1流程: 批量写 -> 必须读到 -> findkeysbycity -> 批量删 -> |
|
|
|
|
|
|
|
TestLab2流程:批量写 -> 创索引address,age -> 索引查询address,age -> 删索引address -> 索引查询address(haveindex=false) -> 索引查询age -> 批量删 -> 索引查询age(索引还在能查,但返回的key数量为0) -> write -> 必须读到 -> 索引查询age。 |
|
|
|
|
|
|
|
至此,上面的流程基本覆盖了我们数据库的每个基础功能。 |
|
|
|
至此,上面的流程基本覆盖了我们数据库的每个基础功能。 |
|
|
|
 |
|
|
|
|
|
|
|
#### 3.1.2 并发测试 |
|
|
|
相关代码在`parallel_test.cc`中 |
|
|
@ -631,7 +632,8 @@ TestPutDelete:创索引 -> 并发:两线程写0、1种子数据,两线程 |
|
|
|
TestWrite(在之前基础上并发所有,并加入write):创索引address、批量写种子2 -> 并发:线程0创索引age,其他线程忙等至开始创建,线程1批量写种子0,线程2write种子1, 线程3删索引age -> 检测:种子012所有数据都应被读到,一致性, age索引被删除。 |
|
|
|
这里的测试也可以加入delete,或不删索引age检测age的一致性,具体见注释。 |
|
|
|
|
|
|
|
至此,上面的流程基本覆盖了我们数据库的每个基础功能之间的并发。 |
|
|
|
至此,上面的流程基本覆盖了我们数据库的每个基础功能之间的并发。 |
|
|
|
 |
|
|
|
|
|
|
|
#### 3.1.2 恢复测试 |
|
|
|
相关代码在`recover_test.cc`中 |
|
|
@ -641,13 +643,31 @@ TestNormalRecover:创索引、批量写、此时之前测试都检测过能被 |
|
|
|
|
|
|
|
TestParalRecover**该测试比较特别,需要运行两次**:创索引 -> 并发:线程0批量写,线程1write,线程2delete,线程3 在单条插入后,deletedb。线程3导致了其他线程错误,测试会终止(模拟数据库崩溃),这会导致各线程在各种奇怪的时间点崩溃。此时注释掉上半部分代码,运行下半部分:单条写入能被读到,并检测一致性。 |
|
|
|
这里我们运行了几十次,前半部分的崩溃报错有多种,但后半部分的运行都是成功的。同时也追踪了恢复的运行过程,确实有数据从metadb中被正确解析。 |
|
|
|
 |
|
|
|
|
|
|
|
### 3.2 性能测试 |
|
|
|
测试、分析、优化 |
|
|
|
|
|
|
|
## 4. 问题与解决 |
|
|
|
1. 我们对并发的写入请求进行了合并,但在测试中发现了一个问题:之前提到,putfield和delete都需要先读一次原来的数据,但他们读不到合并在一起的请求中,之前的那个数据。这就导致了不一致(e.g. 将对于同一个key的putfield和delete请求合并,处理putfield时本次处理要写kv和index,处理delete时先读,发现数据库原来的数据中字段没有索引,于是删kv但没有删index)。我们的解决方式是,对于并发的写入只处理第一个相同的key。这同样提高了处理请求的效率。 |
|
|
|
|
|
|
|
## 5. 潜在优化点 |
|
|
|
1. 使用一些高性能并发设计模式,如reactor来优化多线程写入时由于锁竞争导致的性能问题 |
|
|
|
2. 采用一些高性能的库,如dpdk等 |
|
|
|
3. `GetHandleInterval`中选择一段request时,设置一个上限(综合考量max_batchsize和索引写入开销),和子数据库的批量写对齐。 |
|
|
|
4. 创删索引时会先产生中间结果,再向indexdb批量写。设置一个单次写的上限,分批次写入中间结果。 |
|
|
|
5. 涵盖复杂的数据库故障问题,比如硬件故障、恢复文件丢失等。 |
|
|
|
|
|
|
|
|
|
|
|
## 6. 分工 |
|
|
|
功能 | 完成日期 | 分工 |
|
|
|
:------|:---------|:------ |
|
|
|
value序列化、lab1功能实现|11.19|李度 |
|
|
|
fieldDb接口框架|11.25|陈胤遒 |
|
|
|
lab1整体+测试|11.30|李度、陈胤遒、高宇菲 |
|
|
|
fieldDb功能实现(没有并发和恢复)|12.10|李度、陈胤遒 |
|
|
|
并发框架|12.15|陈胤遒 |
|
|
|
lab2测试、并发完成|12.20|李度 |
|
|
|
恢复|12.25|李度、陈胤遒 |
|
|
|
整体系统整合+测试|12.28|李度、陈胤遒、高宇菲 |
|
|
|
性能测试|1.1|李度、陈胤遒、高宇菲 |