Files
scylladb/test/perf/perf_cache_eviction.cc
Botond Dénes 86ed627fc4 compaction: move code to namespace compaction
The namespace usage in this directory is very inconsistent, with files
and classes scattered in:
* global namespace
* namespace compaction
* namespace sstables

With cases, where all three used in the same file. This code used to
live in sstables/ and some of it still retains namespace sstables as a
heritage of that time. The mismatch between the dir (future module) and
the namespace used is confusing, so finish the migration and move all
code in compaction/ to namespace compaction too.

This patch, although large, is mechanic and only the following kind of
changes are made:
* replace namespace sstable {} with namespace compaction {}
* add namespace compaction {}
* drop/add sstables::
* drop/add compaction::
* move around forward-declarations so they are in the correct namespace
  context

This refactoring revealed some awkward leftover coupling between
sstables and compaction, in sstables/sstable_set.cc, where the
make_sstable_set() methods of compaction strategies are implemented.
2025-09-25 15:03:56 +03:00

179 lines
7.1 KiB
C++

/*
* Copyright (C) 2017-present ScyllaDB
*/
/*
* SPDX-License-Identifier: LicenseRef-ScyllaDB-Source-Available-1.0
*/
#include <fmt/ranges.h>
#include "seastarx.hh"
#include "test/lib/simple_schema.hh"
#include "test/lib/cql_test_env.hh"
#include "test/lib/log.hh"
#include <seastar/core/app-template.hh>
#include "replica/database.hh"
#include "db/config.hh"
#include "db/commitlog/commitlog.hh"
#include "partition_slice_builder.hh"
#include "utils/int_range.hh"
#include "utils/div_ceil.hh"
#include <seastar/core/reactor.hh>
#include <seastar/util/defer.hh>
static thread_local bool cancelled = false;
using namespace std::chrono_literals;
template<typename T>
class monotonic_counter {
std::function<T()> _getter;
T _prev;
public:
monotonic_counter(std::function<T()> getter)
: _getter(std::move(getter)) {
_prev = _getter();
}
// Return change in value since the last call to change() or rate().
auto change() {
auto now = _getter();
return now - std::exchange(_prev, now);
}
};
int main(int argc, char** argv) {
namespace bpo = boost::program_options;
app_template app;
app.add_options()
("trace", "Enables trace-level logging for the test actions")
("no-reads", "Disable reads during the test")
("seconds", bpo::value<unsigned>()->default_value(60), "Duration [s] after which the test terminates with a success")
;
return app.run(argc, argv, [&app] {
if (smp::count != 1) {
throw std::runtime_error("This test has to be run with --smp=1");
}
if (app.configuration().contains("trace")) {
testlog.set_level(seastar::log_level::trace);
}
auto cfg_ptr = make_shared<db::config>();
auto& cfg = *cfg_ptr;
cfg.enable_commitlog(false);
cfg.enable_cache(true);
return do_with_cql_env_thread([&app] (cql_test_env& env) {
auto reads_enabled = !app.configuration().contains("no-reads");
auto seconds = app.configuration()["seconds"].as<unsigned>();
auto stop_test = defer([] {
cancelled = true;
});
timer<> completion_timer;
completion_timer.set_callback([&] {
testlog.info("Test done.");
cancelled = true;
});
completion_timer.arm(std::chrono::seconds(seconds));
env.execute_cql("CREATE TABLE ks.cf (pk text, ck int, v text, PRIMARY KEY (pk, ck)) WITH CLUSTERING ORDER BY (ck DESC)").get();
replica::database& db = env.local_db();
auto s = db.find_schema("ks", "cf");
replica::column_family& cf = db.find_column_family(s->id());
cf.set_compaction_strategy(compaction::compaction_strategy_type::null);
uint64_t mutations = 0;
uint64_t reads = 0;
utils::estimated_histogram reads_hist;
utils::estimated_histogram writes_hist;
auto& tracker = env.local_db().row_cache_tracker();
timer<> stats_printer;
monotonic_counter<uint64_t> reads_ctr([&] { return reads; });
monotonic_counter<uint64_t> mutations_ctr([&] { return mutations; });
monotonic_counter<uint64_t> pmerges_ctr([&] { return tracker.get_stats().partition_merges; });
monotonic_counter<uint64_t> eviction_ctr([&] { return tracker.get_stats().row_evictions; });
monotonic_counter<uint64_t> miss_ctr([&] { return tracker.get_stats().reads_with_misses; });
stats_printer.set_callback([&] {
auto MB = 1024 * 1024;
std::cout << format("rd/s: {:d}, wr/s: {:d}, ev/s: {:d}, pmerge/s: {:d}, miss/s: {:d}, cache: {:d}/{:d} [MB], LSA: {:d}/{:d} [MB], std free: {:d} [MB]",
reads_ctr.change(),
mutations_ctr.change(),
eviction_ctr.change(),
pmerges_ctr.change(),
miss_ctr.change(),
tracker.region().occupancy().used_space() / MB,
tracker.region().occupancy().total_space() / MB,
logalloc::shard_tracker().region_occupancy().used_space() / MB,
logalloc::shard_tracker().region_occupancy().total_space() / MB,
seastar::memory::stats().free_memory() / MB) << "\n\n";
auto print_percentiles = [] (const utils::estimated_histogram& hist) {
return format("min: {:-6d}, 50%: {:-6d}, 90%: {:-6d}, 99%: {:-6d}, 99.9%: {:-6d}, max: {:-6d} [us]",
hist.percentile(0),
hist.percentile(0.5),
hist.percentile(0.9),
hist.percentile(0.99),
hist.percentile(0.999),
hist.percentile(1.0)
);
};
std::cout << "reads : " << print_percentiles(reads_hist) << "\n";
std::cout << "writes: " << print_percentiles(writes_hist) << "\n";
std::cout << "\n";
reads_hist.clear();
writes_hist.clear();
});
stats_printer.arm_periodic(1s);
auto make_pkey = [s] (sstring pk) {
auto key = partition_key::from_single_value(*s, serialized(pk));
return dht::decorate_key(*s, key);
};
auto pkey = make_pkey("key1");
sstring value = uninitialized_string(1024);
using clock = std::chrono::steady_clock;
auto reader = seastar::async([&] {
if (!reads_enabled) {
return;
}
auto id = env.prepare("select * from ks.cf where pk = 'key1' limit 10;").get();
while (!cancelled) {
auto t0 = clock::now();
env.execute_prepared(id, {}).get();
reads_hist.add(std::chrono::duration_cast<std::chrono::microseconds>(clock::now() - t0).count());
++reads;
sleep(100ms).get(); // So that reads don't overwhelm the CPU
}
});
auto mutator = seastar::async([&] {
int32_t ckey_seq = 0;
while (!cancelled) {
mutation m(s, pkey);
auto ck = clustering_key::from_single_value(*s, serialized(ckey_seq++));
auto&& col = *s->get_column_definition(to_bytes("v"));
m.set_clustered_cell(ck, col, atomic_cell::make_live(*col.type, api::new_timestamp(), serialized(value)));
auto t0 = clock::now();
db.apply(s, freeze(m), tracing::trace_state_ptr(), db::commitlog::force_sync::no, db::no_timeout).get();
writes_hist.add(std::chrono::duration_cast<std::chrono::microseconds>(clock::now() - t0).count());
++mutations;
}
});
mutator.get();
reader.get();
stats_printer.cancel();
completion_timer.cancel();
}, cfg_ptr);
});
}