Failed to use io_uring

206 views
Skip to first unread message

lhy

unread,
Aug 29, 2022, 10:58:09 PM8/29/22
to rocksdb
I'm currently using rocksdb 7.3.1 to test MultiGet API.
When I use db_bench, MultiGet(-multiread_batched=true) performs better than Get(-multiread_batched=false). Complete arguments are as follows.

./db_bench -use_existing_db=true --db=../../db_bench_test/mulitget_test -benchmarks="multireadrandom" -key_size=32 -value_size=512 -num=5000000 -batch_size=64 -multiread_batched=true -use_direct_reads=true -duration=60 -ops_between_duration_checks=1 -readonly=true -adaptive_readahead=true -threads=1 -cache_size=10485760000 -async_io=false -multiread_stride=40000

But when I write my own code to test MultiGet API, there is almost no difference in performance between MultiGet and Get. My simple test code is as follows.

#include <cassert>
#include <string>
#include <iostream>
#include "rocksdb/db.h"
#include "rocksdb/slice.h"
#include "rocksdb/options.h"
#include "rocksdb/table.h"

using ROCKSDB_NAMESPACE::Status;
using rocksdb::Slice;
using rocksdb::PinnableSlice;
using ROCKSDB_NAMESPACE::Options;
using ROCKSDB_NAMESPACE::ReadOptions;
using ROCKSDB_NAMESPACE::WriteOptions;

int main() {
        rocksdb::DB *db;
        rocksdb::Options options;
        options.create_if_missing = true;
        options.create_missing_column_families = true;
        rocksdb::BlockBasedTableOptions table_options;
        table_options.no_block_cache = true;
        options.table_factory.reset(NewBlockBasedTableFactory(table_options));
        rocksdb::Status status = rocksdb::DB::OpenForReadOnly(options, "DB", &db);
        assert(status.ok());

        Slice s[3] = {Slice("key1"), Slice("key2"), Slice("key3")};
        PinnableSlice values[3];
        Status stat[3];

        auto opt = ReadOptions();
        opt.adaptive_readahead = true;

        db->MultiGet(opt, db->DefaultColumnFamily(), 3, s, values, stat);

        for (int i = 0; i < 3; i++) {
                assert(stat[i].ok());
        }

        for (int i = 0; i < 3; i++) {
                std::cout << values[i].ToString() << std::endl;
        }

        delete db;

        return 0;
}


It seems that db_bench can properly initialize io_uring while my code can't. Let's focus on the function PosixRandomAccessFile::MultiRead in env/io_posix.cc in rocksdb v7.3.1, and here is part of the code in this function.

620 #if defined(ROCKSDB_IOURING_PRESENT)
621   struct io_uring* iu = nullptr;
622   if (thread_local_io_urings_) {
623     iu = static_cast<struct io_uring*>(thread_local_io_urings_->Get());
624     if (iu == nullptr) {
625       iu = CreateIOUring();
626       if (iu != nullptr) {
627         thread_local_io_urings_->Reset(iu);
628       }
629     }
630   }

When db_bench reached line 622, thread_local_io_urings_ is not a nullptr. When my code reached the same line, thread_local_io_urings_ is a nullptr. So actually my code didn't use io_uring. How can I solve this problem?
Thanks a lot!
Reply all
Reply to author
Forward
0 new messages