Skip to content

Commit 7dda682

Browse files
authored
Adopt device type (#167)
* Adopt device type * reduce #chunk on data to be 60000 * limit HS to below 6.3 * update conan with tilde constraint Signed-off-by: Xiaoxi Chen <[email protected]>
1 parent 033d673 commit 7dda682

File tree

8 files changed

+152
-29
lines changed

8 files changed

+152
-29
lines changed

conanfile.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
class HomeObjectConan(ConanFile):
1111
name = "homeobject"
12-
version = "1.0.16"
12+
version = "2.0.1"
1313
homepage = "https://github.com/eBay/HomeObject"
1414
description = "Blob Store built on HomeReplication"
1515
topics = ("ebay")
@@ -40,8 +40,8 @@ def build_requirements(self):
4040
self.build_requires("gtest/1.14.0")
4141

4242
def requirements(self):
43-
self.requires("homestore/[>=6.2, include_prerelease=True]@oss/master")
44-
self.requires("sisl/[>=12.1, include_prerelease=True]@oss/master")
43+
self.requires("homestore/[~6.2, include_prerelease=True]@oss/master")
44+
self.requires("sisl/[~12.1, include_prerelease=True]@oss/master")
4545
self.requires("lz4/1.9.4", override=True)
4646

4747
def validate(self):

src/include/homeobject/homeobject.hpp

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,44 @@
66
#include <string>
77

88
#include "common.hpp"
9+
#include <sisl/utility/enum.hpp>
910

1011
namespace homeobject {
1112

1213
class BlobManager;
1314
class PGManager;
1415
class ShardManager;
16+
ENUM(DevType, uint8_t, AUTO_DETECT = 1, HDD, NVME, UNSUPPORTED);
17+
struct device_info_t {
18+
explicit device_info_t(std::string name, DevType dtype = DevType::AUTO_DETECT) :
19+
path{std::filesystem::canonical(name)}, type{dtype} {}
20+
device_info_t() = default;
21+
bool operator==(device_info_t const& rhs) const { return path == rhs.path && type == rhs.type; }
22+
friend std::istream& operator>>(std::istream& input, device_info_t& di) {
23+
std::string i_path, i_type;
24+
std::getline(input, i_path, ':');
25+
std::getline(input, i_type);
26+
di.path = std::filesystem::canonical(i_path);
27+
if (i_type == "HDD") {
28+
di.type = DevType::HDD;
29+
} else if (i_type == "NVME") {
30+
di.type = DevType::NVME;
31+
} else {
32+
di.type = DevType::AUTO_DETECT;
33+
}
34+
return input;
35+
}
36+
std::filesystem::path path;
37+
DevType type;
38+
};
1539

1640
class HomeObjectApplication {
1741
public:
1842
virtual ~HomeObjectApplication() = default;
1943

2044
virtual bool spdk_mode() const = 0;
2145
virtual uint32_t threads() const = 0;
22-
virtual std::list< std::filesystem::path > devices() const = 0;
46+
virtual std::list< device_info_t > devices() const = 0;
2347

2448
// Callback made after determining if a SvcId exists or not during initialization, will consume response
2549
virtual peer_id_t discover_svcid(std::optional< peer_id_t > const& found) const = 0;
@@ -52,3 +76,36 @@ class HomeObject {
5276
extern std::shared_ptr< HomeObject > init_homeobject(std::weak_ptr< HomeObjectApplication >&& application);
5377

5478
} // namespace homeobject
79+
//
80+
81+
namespace fmt {
82+
template <>
83+
struct formatter< homeobject::device_info_t > {
84+
template < typename ParseContext >
85+
constexpr auto parse(ParseContext& ctx) {
86+
return ctx.begin();
87+
}
88+
89+
template < typename FormatContext >
90+
auto format(homeobject::device_info_t const& device, FormatContext& ctx) {
91+
std::string type;
92+
switch (device.type) {
93+
case homeobject::DevType::HDD:
94+
type = "HDD";
95+
break;
96+
case homeobject::DevType::NVME:
97+
type = "NVME";
98+
break;
99+
case homeobject::DevType::UNSUPPORTED:
100+
type = "UNSUPPORTED";
101+
break;
102+
case homeobject::DevType::AUTO_DETECT:
103+
type = "AUTO_DETECT";
104+
break;
105+
default:
106+
type = "UNKNOWN";
107+
}
108+
return fmt::format_to(ctx.out(), "Path: {}, Type: {}", device.path.string(), type);
109+
}
110+
};
111+
} // namespace fmt

src/lib/homestore_backend/hs_homeobject.cpp

Lines changed: 60 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,13 @@ class HSReplApplication : public homestore::ReplApplication {
9797
//
9898
// This should assert if we can not initialize HomeStore.
9999
//
100+
DevType HSHomeObject::get_device_type(string const& devname) {
101+
const iomgr::drive_type dtype = iomgr::DriveInterface::get_drive_type(devname);
102+
if (dtype == iomgr::drive_type::block_hdd || dtype == iomgr::drive_type::file_on_hdd) { return DevType::HDD; }
103+
if (dtype == iomgr::drive_type::file_on_nvme || dtype == iomgr::drive_type::block_nvme) { return DevType::NVME; }
104+
return DevType::UNSUPPORTED;
105+
}
106+
100107
void HSHomeObject::init_homestore() {
101108
auto app = _application.lock();
102109
RELEASE_ASSERT(app, "HomeObjectApplication lifetime unexpected!");
@@ -115,9 +122,27 @@ void HSHomeObject::init_homestore() {
115122
LOGI("Initialize and start HomeStore with app_mem_size = {}", homestore::in_bytes(app_mem_size));
116123

117124
std::vector< homestore::dev_info > device_info;
118-
for (auto const& path : app->devices()) {
119-
device_info.emplace_back(std::filesystem::canonical(path).string(), homestore::HSDevType::Data);
125+
bool has_data_dev = false;
126+
bool has_fast_dev = false;
127+
for (auto const& dev : app->devices()) {
128+
auto input_dev_type = dev.type;
129+
auto detected_type = get_device_type(dev.path.string());
130+
LOGD("Device {} detected as {}", dev.path.string(), detected_type);
131+
auto final_type = (dev.type == DevType::AUTO_DETECT) ? detected_type : input_dev_type;
132+
if (final_type == DevType::UNSUPPORTED) {
133+
LOGW("Device {} is not supported, skipping", dev.path.string());
134+
continue;
135+
}
136+
if (input_dev_type != DevType::AUTO_DETECT && detected_type != final_type) {
137+
LOGW("Device {} detected as {}, but input type is {}, using input type", dev.path.string(), detected_type,
138+
input_dev_type);
139+
}
140+
auto hs_type = (final_type == DevType::HDD) ? homestore::HSDevType::Data : homestore::HSDevType::Fast;
141+
if (hs_type == homestore::HSDevType::Data) { has_data_dev = true; }
142+
if (hs_type == homestore::HSDevType::Fast) { has_fast_dev = true; }
143+
device_info.emplace_back(std::filesystem::canonical(dev.path).string(), hs_type);
120144
}
145+
RELEASE_ASSERT(device_info.size() != 0, "No supported devices found!");
121146

122147
chunk_selector_ = std::make_shared< HeapChunkSelector >();
123148
using namespace homestore;
@@ -134,17 +159,39 @@ void HSHomeObject::init_homestore() {
134159
RELEASE_ASSERT(!_our_id.is_nil(), "Received no SvcId and need FORMAT!");
135160
LOGW("We are starting for the first time on [{}], Formatting!!", to_string(_our_id));
136161

137-
HomeStore::instance()->format_and_start({
138-
{HS_SERVICE::META, hs_format_params{.size_pct = 5.0}},
139-
{HS_SERVICE::LOG, hs_format_params{.size_pct = 10.0, .chunk_size = 32 * Mi}},
140-
{HS_SERVICE::REPLICATION,
141-
hs_format_params{.size_pct = 79.0,
142-
.num_chunks = 65000,
143-
.block_size = _data_block_size,
144-
.alloc_type = blk_allocator_type_t::append,
145-
.chunk_sel_type = chunk_selector_type_t::CUSTOM}},
146-
{HS_SERVICE::INDEX, hs_format_params{.size_pct = 5.0}},
147-
});
162+
if (has_data_dev && has_fast_dev) {
163+
// Hybrid mode
164+
LOGD("Has both Data and Fast, running with Hybrid mode");
165+
HomeStore::instance()->format_and_start({
166+
{HS_SERVICE::META, hs_format_params{.dev_type = HSDevType::Fast, .size_pct = 9.0, .num_chunks = 64}},
167+
{HS_SERVICE::LOG,
168+
hs_format_params{.dev_type = HSDevType::Fast, .size_pct = 45.0, .chunk_size = 32 * Mi}},
169+
{HS_SERVICE::INDEX, hs_format_params{.dev_type = HSDevType::Fast, .size_pct = 45.0, .num_chunks = 128}},
170+
{HS_SERVICE::REPLICATION,
171+
hs_format_params{.dev_type = HSDevType::Data,
172+
.size_pct = 99.0,
173+
.num_chunks = 60000,
174+
.block_size = _data_block_size,
175+
.alloc_type = blk_allocator_type_t::append,
176+
.chunk_sel_type = chunk_selector_type_t::CUSTOM}},
177+
});
178+
} else {
179+
auto run_on_type = has_fast_dev ? homestore::HSDevType::Fast : homestore::HSDevType::Data;
180+
LOGD("Running with Single mode, all service on {}", run_on_type);
181+
HomeStore::instance()->format_and_start({
182+
// FIXME: this is to work around the issue in HS that varsize allocator doesnt work with small chunk size.
183+
{HS_SERVICE::META, hs_format_params{.dev_type = run_on_type, .size_pct = 5.0, .num_chunks = 1}},
184+
{HS_SERVICE::LOG, hs_format_params{.dev_type = run_on_type, .size_pct = 10.0, .chunk_size = 32 * Mi}},
185+
{HS_SERVICE::INDEX, hs_format_params{.dev_type = run_on_type, .size_pct = 5.0, .num_chunks = 1}},
186+
{HS_SERVICE::REPLICATION,
187+
hs_format_params{.dev_type = run_on_type,
188+
.size_pct = 79.0,
189+
.num_chunks = 60000,
190+
.block_size = _data_block_size,
191+
.alloc_type = blk_allocator_type_t::append,
192+
.chunk_sel_type = chunk_selector_type_t::CUSTOM}},
193+
});
194+
}
148195

149196
// Create a superblock that contains our SvcId
150197
auto svc_sb = homestore::superblk< svc_info_superblk_t >(_svc_meta_name);

src/lib/homestore_backend/hs_homeobject.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,9 @@ class HSHomeObject : public HomeObjectImpl {
304304

305305
void persist_pg_sb();
306306

307+
// helpers
308+
DevType get_device_type(string const& devname);
309+
307310
public:
308311
using HomeObjectImpl::HomeObjectImpl;
309312
HSHomeObject();

src/lib/homestore_backend/tests/homeobj_fixture.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class HomeObjectFixture : public ::testing::Test {
3232
std::default_random_engine rnd_engine{rnd()};
3333

3434
void SetUp() override {
35-
app = std::make_shared< FixtureApp >();
35+
app = std::make_shared< FixtureApp >(true /* is_hybrid */);
3636
_obj_inst = homeobject::init_homeobject(std::weak_ptr< homeobject::HomeObjectApplication >(app));
3737
}
3838

src/lib/tests/fixture_app.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,17 @@ SISL_LOGGING_INIT(HOMEOBJECT_LOG_MODS)
1616

1717
SISL_OPTIONS_ENABLE(logging, homeobject, test_home_object)
1818

19-
FixtureApp::FixtureApp() {
19+
FixtureApp::FixtureApp(bool is_hybrid) : is_hybrid_(is_hybrid) {
2020
clean();
21-
LOGWARN("creating device {} file with size {} ", path_, 10 * Gi);
22-
std::ofstream ofs{path_, std::ios::binary | std::ios::out | std::ios::trunc};
23-
std::filesystem::resize_file(path_, 10 * Gi);
21+
LOGWARN("creating HDD device {} file with size {} ", path_hdd_, 10 * Gi);
22+
std::ofstream ofs{path_hdd_, std::ios::binary | std::ios::out | std::ios::trunc};
23+
std::filesystem::resize_file(path_hdd_, 10 * Gi);
24+
25+
if (is_hybrid_) {
26+
LOGWARN("creating SSD device {} file with size {} ", path_ssd_, 10 * Gi);
27+
std::ofstream ofs{path_ssd_, std::ios::binary | std::ios::out | std::ios::trunc};
28+
std::filesystem::resize_file(path_ssd_, 10 * Gi);
29+
}
2430
}
2531

2632
homeobject::peer_id_t FixtureApp::discover_svcid(std::optional< homeobject::peer_id_t > const& p) const {

src/lib/tests/fixture_app.hpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,30 @@ using homeobject::blob_id_t;
1919
using homeobject::peer_id_t;
2020

2121
class FixtureApp : public homeobject::HomeObjectApplication {
22-
std::string path_{"/tmp/homeobject_test.data"};
22+
std::string path_hdd_{"/tmp/homeobject_test.hdd"};
23+
std::string path_ssd_{"/tmp/homeobject_test.ssd"};
24+
bool is_hybrid_{false};
2325

2426
public:
25-
FixtureApp();
27+
FixtureApp(bool is_hybrid=false);
2628
~FixtureApp() = default;
2729

2830
bool spdk_mode() const override { return false; }
2931
uint32_t threads() const override { return 2; }
3032

3133
void clean() {
32-
if (std::filesystem::exists(path_)) std::filesystem::remove(path_);
34+
if (std::filesystem::exists(path_hdd_)) std::filesystem::remove(path_hdd_);
35+
if (std::filesystem::exists(path_ssd_)) std::filesystem::remove(path_ssd_);
3336
}
3437

35-
std::list< std::filesystem::path > devices() const override {
36-
auto device_info = std::list< std::filesystem::path >();
37-
device_info.emplace_back(std::filesystem::canonical(path_));
38+
std::list< homeobject::device_info_t > devices() const override {
39+
auto device_info = std::list< homeobject::device_info_t >();
40+
// add HDD
41+
device_info.emplace_back(path_hdd_, homeobject::DevType::HDD);
42+
if (is_hybrid_) {
43+
// add SSD
44+
device_info.emplace_back(path_ssd_, homeobject::DevType::NVME);
45+
}
3846
return device_info;
3947
}
4048

test_package/test_package.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ class TestApp : public homeobject::HomeObjectApplication {
1111
public:
1212
bool spdk_mode() const override { return false; }
1313
uint32_t threads() const override { return 1; }
14-
std::list< std::filesystem::path > devices() const override { return std::list< std::filesystem::path >(); }
14+
std::list< homeobject::device_info_t > devices() const override {
15+
return std::list< homeobject::device_info_t >();
16+
}
1517
homeobject::peer_id_t discover_svcid(std::optional< homeobject::peer_id_t > const& p) const override {
1618
return boost::uuids::random_generator()();
1719
}

0 commit comments

Comments
 (0)