From 7d96557d457ce23d892e816a408ce83497333ef9 Mon Sep 17 00:00:00 2001
From: VirgilZhu <94546750@qq.com>
Date: Tue, 7 Jan 2025 09:44:17 +0800
Subject: [PATCH] update README
---
README.md | 49 ++++++++++++-----------------------------------
benchmarks/db_bench.cc | 2 +-
include/leveldb/options.h | 4 ++--
3 files changed, 15 insertions(+), 40 deletions(-)
diff --git a/README.md b/README.md
index 5cf21ab..97c0140 100755
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
小组成员:谷杰 10222140408 朱维清 10215300402
-
+[TOC]
## 项目概述
@@ -111,7 +111,7 @@
## KV 分离
-> KV 分离部分,由于我们小组最后定版设计为,使 VLog 代替原 LevelDB 中 WAL 的作用,同时具有从 LSM-Tree 中分离并保存超过某个 value 大小阈值(`separate_threshold`)的 kv 对数据的作用,关于 VLog 的读写类 `VlogReader/VlogWriter` 的实现参考了 `LogReader/LogWriter` 的部分内容,并能共享 `LogReader/LogWriter` 使用的所有读写接口(参见`env_posix.cc`,读写均为磁盘I/O)(去除了 CRC 校验功能)。
+> KV 分离部分,由于我们小组最后定版设计为,使 VLog 代替原 LevelDB 中 WAL 的作用,同时具有从 LSM-Tree 中分离并保存超过某个 value 大小阈值(`separate_threshold`)的 kv 对数据的作用,关于 VLog 的读写类 `VlogReader/VlogWriter` 的实现参考了 `LogReader/LogWriter` 的部分内容,并能共享 `LogReader/LogWriter` 使用的所有读写接口(参见`env_posix.cc`,读写均为磁盘I/O)。
>
> + **结构图/写入流程图**:
> 
@@ -407,7 +407,7 @@ Status VlogWriter::EmitPhysicalRecord(const char* ptr, size_t length,
}
```
-vlog_writer.cc文件中则是对于构造函数,AddRecord()以及EmitPhysicalRecord()。实现上与LogWriter基本一致,只是去除了Crc校验码的部分。对于EmitPhysicalRecord()函数,由于去除了校验码,则其header要从原本的8字节改为4字节,只保留length部分(4字节)。
+vlog_writer.cc文件中则是对于构造函数,AddRecord()以及EmitPhysicalRecord()。实现上与LogWriter基本一致。对于EmitPhysicalRecord()函数,由于去除了校验码,则其header要从原本的8字节改为4字节,只保留length部分(4字节)。
改完vlog_writer部分后,让我们重新来梳理一遍写入过程。
@@ -644,7 +644,7 @@ class SeparateManagement {
#### 介绍部分函数
+ `ConvertQueue`:
- 每次把 VLog 加入 GC 队列前需要更新数据库的 last_sequence,并确保所有 `need_updates_` 队列里的 VLog 都更新了 `last_sequence_`,以便对 VLog 中的有效 keys 重新插入新的 VLog 中:
+ 每次把 VLog 加入 GC 队列前需要更新数据库的 last_sequence,并确保所有 `need_updates_` 队列里的 VLog 都更新了 `last_sequence_`,以便对 VLog 中的有效 keys 重新插入数据库:
```C++
bool SeparateManagement::ConvertQueue(uint64_t& db_sequence) {
@@ -736,15 +736,14 @@ void SeparateManagement::CollectionMap(){
### GC 的具体实现
-> 1. 我们采用了类似 Compaction 的后台多线程调度机制来实现 GC;
+> 1. 我们采用了类似 Compaction 的后台线程调度机制来实现 GC;
> 2. 支持在线自动 GC,也支持离线手动触发 GC;
-> 3. GC 与 Snapshot 互相冲突:若数据库运行期间有 Snapshot 产生,则该 Snapshot 之后的所有数据不再进行任何在线 GC,直到该 Snapshot 被释放才会重启在线 GC;
->
-> **VLog 的 GC 的回收阈值: `Options::garbage_collection_threshold = max_value_log_size / 4 ( = 4MB)`**
+>
+>**VLog 的 GC 的回收阈值: `Options::garbage_collection_threshold = max_value_log_size / 4 ( = 4MB)`**
+ 所有 GC 流程都由 `SeparateManagement *DBImpl::garbage_collection_management_` 进行管理,并向所有 VLogs 的 `ValueLogInfo` 更新 GC 的结果。
-#### 后台多线程调度机制
+#### 后台线程调度机制
参考 Compaction 线程互斥锁的实现与后台调度机制:
@@ -880,7 +879,7 @@ Status DBImpl::OutLineGarbageCollection(){
} else if (!bg_error_.ok()) {
// Already got an error; no more changes
} else {
- // 设置调度变量,通过 detach 线程调度; detach 线程即使主线程退出,依然可以正常执行完成
+ // 设置调度变量
background_GarbageCollection_scheduled_ = true;
env_->ScheduleForGarbageCollection(&DBImpl::GarbageCollectionBGWork, this);
}
@@ -1002,31 +1001,9 @@ Status DBImpl::OutLineGarbageCollection(){
---
-#### GC 与 Snapshot 的冲突机制
-
-```c++
-const Snapshot* DBImpl::GetSnapshot() {
- MutexLock l(&mutex_);
- // 建立快照,对快照之后的信息不用进行 GC
- finish_back_garbage_collection_ = true;
- return snapshots_.New(versions_->LastSequence());
-}
-
-void DBImpl::ReleaseSnapshot(const Snapshot* snapshot) {
- MutexLock l(&mutex_);
- snapshots_.Delete(static_cast(snapshot));
- // 没有快照,重新进行后台 GC
- if (snapshots_.empty()) {
- finish_back_garbage_collection_ = false;
- }
-}
-```
-
----
-
## 断电恢复
-> 实现断电恢复的主要函数为 `DBImpl::Recover()`、`DBImpl::RecoverLogFile`、`DB::Open()`;
+> 实现断电恢复的主要函数为 `DBImpl::Recover()`、`DBImpl::RecoverLogFile()`、`DB::Open()`;
### 大致恢复流程
@@ -1487,7 +1464,7 @@ fillsync : 985.150 micros/op; 0.0 MB/s (100 ops)
fillrandom : 4.337 micros/op; 4.0 MB/s
overwrite : 4.503 micros/op; 3.8 MB/s
fillgivenseq : 4.472 micros/op; 3.6 MB/s
-fillgivenrandom : 9.076 micros/op; 1.8 MB/s
+fillgivenrandom : 9.076 micros/op; 1.8 MB/s
```
+ kv分离:
@@ -1498,7 +1475,7 @@ fillsync : 1005.810 micros/op; 0.0 MB/s (100 ops)
fillrandom : 4.374 micros/op; 3.9 MB/s
overwrite : 4.461 micros/op; 3.8 MB/s
fillgivenseq : 4.503 micros/op; 3.6 MB/s
-fillgivenrandom : 4.789 micros/op; 3.4 MB/s
+fillgivenrandom : 4.789 micros/op; 3.4 MB/s
```
#### 分析结论
@@ -1516,7 +1493,6 @@ readrandom : 2.460 micros/op; (86501 of 100000 found)
readrandom : 2.096 micros/op; (86354 of 100000 found)
readseq : 0.258 micros/op; 188.5 MB/s
readreverse : 1.250 micros/op; 38.9 MB/s
-findkeysbyfield : 1474764.000 micros/op; (3873 of 10000 found)
```
+ kv分离:
@@ -1526,7 +1502,6 @@ readrandom : 13.775 micros/op; (86501 of 100000 found)
readrandom : 9.095 micros/op; (86354 of 100000 found)
readseq : 0.231 micros/op; 90.2 MB/s
readreverse : 0.950 micros/op; 22.0 MB/s
-findkeysbyfield : 231171.000 micros/op; (0 of 10000 found)
```
#### 分析结论
diff --git a/benchmarks/db_bench.cc b/benchmarks/db_bench.cc
index eb1c40b..3543300 100644
--- a/benchmarks/db_bench.cc
+++ b/benchmarks/db_bench.cc
@@ -85,7 +85,7 @@ static int FLAGS_num_fields = 10000;
static int FLAGS_threads = 1;
// Size of each value
-static int FLAGS_value_size = 100;
+static int FLAGS_value_size = 1000;
// Arrange to generate values that shrink to this fraction of
// their original size after compression
diff --git a/include/leveldb/options.h b/include/leveldb/options.h
index 7832b2b..a397e07 100644
--- a/include/leveldb/options.h
+++ b/include/leveldb/options.h
@@ -114,7 +114,7 @@ struct LEVELDB_EXPORT Options {
// compactions and hence longer latency/performance hiccups.
// Another reason to increase this parameter might be when you are
// initially populating a large database.
- size_t max_file_size = 2 * 1024 * 1024;
+ size_t max_file_size = 64 * 1024 * 1024;
// Compress blocks using the specified compression algorithm. This
// parameter can be changed dynamically.
@@ -149,7 +149,7 @@ struct LEVELDB_EXPORT Options {
/* 注释:重要的 VLog 与 GC 设置 */
// value log 的文件大小
- uint64_t max_value_log_size = 16 * 1024 * 1024;
+ uint64_t max_value_log_size = 64 * 1024 * 1024;
// VLog 的 gc 的回收阈值。
uint64_t garbage_collection_threshold = max_value_log_size / 4;
// gc 后台回收时重新 put 的时候,默认的 kv 分离的值。