Skip to content

Commit ff2d2a2

Browse files
authored
Merge pull request ceph#56975 from aclamk/wip-aclamk-bs-compression-recompression
os/bluestore: Recompression, part 4. Scanner, Estimator and core recompression.
2 parents 0712c11 + 117a2d9 commit ff2d2a2

File tree

17 files changed

+1528
-50
lines changed

17 files changed

+1528
-50
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
roles:
2+
- [mon.a, mgr.x, osd.0, osd.1, client.0]
3+
openstack:
4+
- volumes: # attached to each instance
5+
count: 2
6+
size: 10 # GB
7+
tasks:
8+
- install:
9+
- exec:
10+
client.0:
11+
- mkdir $TESTDIR/archive/ostest && cd $TESTDIR/archive/ostest && ulimit -Sn 16384 && CEPH_ARGS="--no-log-to-stderr --log-file $TESTDIR/archive/ceph_test_objectstore.log --debug-bluestore 5" ceph_test_objectstore --gtest_filter=*/1:*Matrix*:-*Matrix*Compression* --gtest_catch_exceptions=0 --bluestore_write_v2=true
12+
- rm -rf $TESTDIR/archive/ostest
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
roles:
2+
- [mon.a, mgr.x, osd.0, osd.1, client.0]
3+
openstack:
4+
- volumes: # attached to each instance
5+
count: 2
6+
size: 10 # GB
7+
tasks:
8+
- install:
9+
- exec:
10+
client.0:
11+
- mkdir $TESTDIR/archive/ostest && cd $TESTDIR/archive/ostest && ulimit -Sn 16384 && CEPH_ARGS="--no-log-to-stderr --log-file $TESTDIR/archive/ceph_test_objectstore.log --debug-bluestore 5" ceph_test_objectstore --gtest_filter=*Matrix*Compression* --gtest_catch_exceptions=0 --bluestore_write_v2=true
12+
- rm -rf $TESTDIR/archive/ostest

src/common/options/global.yaml.in

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4777,6 +4777,21 @@ options:
47774777
flags:
47784778
- runtime
47794779
with_legacy: true
4780+
- name: bluestore_recompression_min_gain
4781+
type: float
4782+
level: advanced
4783+
desc: Required estimated gain for accepting extents for recompressing.
4784+
long_desc: Partial writes over compressed blobs have high cost. New data requires
4785+
new allocation units, but whole old blob must remain. To combat it BlueStore
4786+
looks around write position to find blobs that will make it profitable to read
4787+
and recompress.
4788+
fmt_desc: A float value, (size_exact_released / size_expected_after_compression).
4789+
default: 1.2
4790+
see_also:
4791+
- bluestore_compression_max_blob_size
4792+
flags:
4793+
- runtime
4794+
with_legacy: true
47804795
# Specifies minimum expected amount of saved allocation units
47814796
# per single blob to enable compressed blobs garbage collection
47824797
- name: bluestore_gc_enable_blob_threshold

src/common/subsys.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ SUBSYS(throttle, 1, 1)
7373
SUBSYS(refs, 0, 0)
7474
SUBSYS(compressor, 1, 5)
7575
SUBSYS(bluestore, 1, 5)
76+
SUBSYS(bluestore_compression, 1, 5)
7677
SUBSYS(bluefs, 1, 5)
7778
SUBSYS(bdev, 1, 3)
7879
SUBSYS(kstore, 1, 5)

src/crimson/os/alienstore/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@ set(alien_store_srcs
6060
${PROJECT_SOURCE_DIR}/src/os/bluestore/StupidAllocator.cc
6161
${PROJECT_SOURCE_DIR}/src/os/bluestore/BitmapAllocator.cc
6262
${PROJECT_SOURCE_DIR}/src/os/bluestore/Writer.cc
63+
${PROJECT_SOURCE_DIR}/src/os/bluestore/Compression.cc
6364
${PROJECT_SOURCE_DIR}/src/os/bluestore/BlueStore_debug.cc
65+
${PROJECT_SOURCE_DIR}/src/os/bluestore/BlueAdmin.cc
6466
${PROJECT_SOURCE_DIR}/src/os/memstore/MemStore.cc)
6567

6668
add_library(crimson-alienstore STATIC

src/os/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ if(WITH_BLUESTORE)
2727
bluestore/Btree2Allocator.cc
2828
bluestore/HybridAllocator.cc
2929
bluestore/Writer.cc
30+
bluestore/Compression.cc
31+
bluestore/BlueAdmin.cc
3032
)
3133
endif(WITH_BLUESTORE)
3234

src/os/bluestore/BlueAdmin.cc

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2+
// vim: ts=8 sw=2 smarttab
3+
4+
#include "BlueAdmin.h"
5+
#include "Compression.h"
6+
#include "common/pretty_binary.h"
7+
#include "common/debug.h"
8+
#include <asm-generic/errno-base.h>
9+
#include <vector>
10+
#include <limits>
11+
12+
#define dout_subsys ceph_subsys_bluestore
13+
#define dout_context store.cct
14+
15+
using ceph::bufferlist;
16+
using ceph::Formatter;
17+
using ceph::common::cmd_getval;
18+
19+
BlueStore::SocketHook::SocketHook(BlueStore& store)
20+
: store(store)
21+
{
22+
AdminSocket *admin_socket = store.cct->get_admin_socket();
23+
if (admin_socket) {
24+
int r = admin_socket->register_command(
25+
"bluestore collections",
26+
this,
27+
"list all collections");
28+
if (r != 0) {
29+
dout(1) << __func__ << " cannot register SocketHook" << dendl;
30+
return;
31+
}
32+
r = admin_socket->register_command(
33+
"bluestore list "
34+
"name=collection,type=CephString,req=true "
35+
"name=start,type=CephString,req=false "
36+
"name=max,type=CephInt,req=false",
37+
this,
38+
"list objects in specific collection");
39+
ceph_assert(r == 0);
40+
r = admin_socket->register_command(
41+
"bluestore onode metadata "
42+
"name=object_name,type=CephString,req=true",
43+
this,
44+
"print object internals");
45+
ceph_assert(r == 0);
46+
r = admin_socket->register_command(
47+
"bluestore compression stats "
48+
"name=collection,type=CephString,req=false",
49+
this,
50+
"print compression stats, per collection");
51+
ceph_assert(r == 0);
52+
}
53+
}
54+
55+
BlueStore::SocketHook::~SocketHook()
56+
{
57+
AdminSocket *admin_socket = store.cct->get_admin_socket();
58+
if (admin_socket) {
59+
admin_socket->unregister_commands(this);
60+
}
61+
}
62+
63+
int BlueStore::SocketHook::call(
64+
std::string_view command,
65+
const cmdmap_t& cmdmap,
66+
const bufferlist& inbl,
67+
Formatter *f,
68+
std::ostream& ss,
69+
bufferlist& out)
70+
{
71+
int r = 0;
72+
if (command == "bluestore collections") {
73+
std::vector<coll_t> collections;
74+
store.list_collections(collections);
75+
std::stringstream result;
76+
for (const auto& c : collections) {
77+
result << c << std::endl;
78+
}
79+
out.append(result.str());
80+
return 0;
81+
} else if (command == "bluestore list") {
82+
std::string coll;
83+
std::string start;
84+
int64_t max;
85+
cmd_getval(cmdmap, "collection", coll);
86+
cmd_getval(cmdmap, "start", start);
87+
if (!cmd_getval(cmdmap, "max", max)) {
88+
max = 100;
89+
}
90+
if (max == 0) {
91+
max = std::numeric_limits<int>::max();
92+
}
93+
coll_t c;
94+
if (c.parse(coll) == false) {
95+
ss << "Cannot parse collection" << std::endl;
96+
return -EINVAL;
97+
}
98+
BlueStore::CollectionRef col = store._get_collection(c);
99+
if (!col) {
100+
ss << "No such collection" << std::endl;
101+
return -ENOENT;
102+
}
103+
ghobject_t start_object;
104+
if (start.length() > 0) {
105+
if (start_object.parse(start) == false) {
106+
ss << "Cannot parse start object";
107+
return -EINVAL;
108+
}
109+
}
110+
std::vector<ghobject_t> list;
111+
{
112+
std::shared_lock l(col->lock);
113+
r = store._collection_list(col.get(), start_object, ghobject_t::get_max(),
114+
max, false, &list, nullptr);
115+
}
116+
if (r != 0) {
117+
return 0;
118+
}
119+
std::stringstream result;
120+
for (auto& obj : list) {
121+
result << obj << std::endl;
122+
}
123+
out.append(result.str());
124+
return 0;
125+
} else if (command == "bluestore onode metadata") {
126+
std::string object_name;
127+
cmd_getval(cmdmap, "object_name", object_name);
128+
ghobject_t object;
129+
if (!object.parse(object_name)) {
130+
ss << "Cannot parse object" << std::endl;
131+
return -EINVAL;
132+
}
133+
std::shared_lock l(store.coll_lock);
134+
for (const auto& cp : store.coll_map) {
135+
if (cp.second->contains(object)) {
136+
std::shared_lock l(cp.second->lock);
137+
OnodeRef o = cp.second->get_onode(object, false);
138+
if (!o || !o->exists) {
139+
ss << "Object not found" << std::endl;
140+
return -ENOENT;
141+
}
142+
o->extent_map.fault_range(store.db, 0, 0xffffffff);
143+
using P = BlueStore::printer;
144+
std::stringstream result;
145+
result << o->print(P::PTR + P::DISK + P::USE + P::BUF + P::CHK + P::ATTRS) << std::endl;
146+
out.append(result.str());
147+
return 0;
148+
}
149+
}
150+
r = -ENOENT;
151+
ss << "No collection that can hold such object" << std::endl;
152+
} else if (command == "bluestore compression stats") {
153+
std::vector<CollectionRef> copied;
154+
{
155+
std::shared_lock l(store.coll_lock);
156+
copied.reserve(store.coll_map.size());
157+
for (const auto& c : store.coll_map) {
158+
copied.push_back(c.second);
159+
}
160+
}
161+
std::string coll;
162+
cmd_getval(cmdmap, "collection", coll);
163+
f->open_array_section("compression");
164+
for (const auto& c : copied) {
165+
std::shared_lock l(c->lock);
166+
if ((coll.empty() && bool(c->estimator))
167+
|| coll == c->get_cid().c_str()) {
168+
f->open_object_section("collection");
169+
f->dump_string("cid", c->get_cid().c_str());
170+
f->open_object_section("estimator");
171+
if (c->estimator) {
172+
c->estimator->dump(f);
173+
}
174+
f->close_section();
175+
f->close_section();
176+
}
177+
}
178+
f->close_section();
179+
return 0;
180+
} else {
181+
ss << "Invalid command" << std::endl;
182+
r = -ENOSYS;
183+
}
184+
return r;
185+
}

src/os/bluestore/BlueAdmin.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2+
// vim: ts=8 sw=2 smarttab
3+
4+
#ifndef CEPH_OSD_BLUEADMIN_H
5+
#define CEPH_OSD_BLUEADMIN_H
6+
7+
8+
#include "BlueStore.h"
9+
#include "common/admin_socket.h"
10+
11+
using std::string;
12+
using std::to_string;
13+
14+
using ceph::bufferlist;
15+
using ceph::Formatter;
16+
17+
class BlueStore::SocketHook : public AdminSocketHook {
18+
BlueStore& store;
19+
20+
public:
21+
SocketHook(BlueStore& store);
22+
virtual ~SocketHook();
23+
int call(std::string_view command,
24+
const cmdmap_t& cmdmap,
25+
const bufferlist& inbl,
26+
Formatter *f,
27+
std::ostream& ss,
28+
bufferlist& out) override;
29+
};
30+
#endif

0 commit comments

Comments
 (0)