Мне нужно как можно быстрее записать много данных в базу данных leveldb.
Периодически leveldb запускает «сжатие» для объединения файлов базы данных. Пока уплотнение выполняется, любые вызовы DB::Write
не будут возвращаться до тех пор, пока уплотнение не будет завершено, вызывая длинные паузы с регулярными интервалами.
Это не желаемый (или ожидаемый) результат, поскольку у меня сложилось впечатление, уплотнение происходит в отдельном потоке.
Это особенно плохо для меня, потому что я пишу в базу данных по всем доступным потокам, поэтому, когда возникают эти паузы, загрузка ЦП возрастает до 100%, даже если потоки просто ждут уплотнение до финиша sh. Это то, чего я хочу избежать, 100% использование от простого ожидания ...
Псевдокод:
//open database earlier in program
leveldb::DB *db;
leveldb::DB::Open(options, filePath, &db);
//...
//inside each worker thread, create data, put in write batch
leveldb::WriteBatch wb;
//...
//lots of data etc
wb.Put(sliceKey, sliceData);
//call write
leveldb::WriteOptions writeOptions;
writeOptions.sync = false;
db->Write(writeOptions, &wb); //HANGS ONLY IF COMPACTION IS RUNNING, can take 15+ seconds
Вещи, которые я пробовал:
- Установить
WriteOptions::sync
на false
(изначально было неверно, похоже, не действует) - Вызывается
DB::Put
вместо DB::Write
(иначе говоря, без использования WriteBatch
, та же проблема) - Отправлял любые вызовы
DB::Write
в одном потоке (не позволял использовать ЦП до 100%, но замедлял все это в 2 раза. Неприемлемо.) - Поиск в исходном коде leveldb, чтобы понять, почему это происходит (idk)
- Вызов
SuspendCompaction
, который удаляет паузы, но теперь не сжимает базу данных ...
Любое понимание этого вопроса было бы очень признательно!
ПРИМЕЧАНИЕ. Вот хорошая запись в блоге, в которой резюмируется, как уплотнение работает в фоновом потоке http://tonyz93.blogspot.com/2016/11/leveldb-source-reading-3-compaction.html