* seastar d59fcef...b924495 (2): > build: Fix protobuf generation rules > Merge "Restructure files" from Jesse Includes fixup patch from Jesse: " Update Seastar `#include`s to reflect restructure All Seastar header files are now prefixed with "seastar" and the configure script reflects the new locations of files. Signed-off-by: Jesse Haber-Kucharsky <jhaberku@scylladb.com> Message-Id: <5d22d964a7735696fb6bb7606ed88f35dde31413.1542731639.git.jhaberku@scylladb.com> "
187 lines
7.4 KiB
C++
187 lines
7.4 KiB
C++
/*
|
|
* Copyright (C) 2017 ScyllaDB
|
|
*/
|
|
|
|
/*
|
|
* This file is part of Scylla.
|
|
*
|
|
* Scylla is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Scylla is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with Scylla. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <boost/range/irange.hpp>
|
|
#include "seastarx.hh"
|
|
#include "tests/simple_schema.hh"
|
|
#include "tests/cql_test_env.hh"
|
|
#include <seastar/core/app-template.hh>
|
|
#include "database.hh"
|
|
#include "db/config.hh"
|
|
#include "partition_slice_builder.hh"
|
|
#include "utils/int_range.hh"
|
|
#include "utils/div_ceil.hh"
|
|
#include <seastar/core/reactor.hh>
|
|
|
|
logging::logger test_log("test");
|
|
|
|
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 (app.configuration().count("trace")) {
|
|
test_log.set_level(seastar::log_level::trace);
|
|
}
|
|
|
|
db::config cfg;
|
|
cfg.enable_commitlog(false);
|
|
cfg.enable_cache(true);
|
|
|
|
return do_with_cql_env_thread([&app] (cql_test_env& env) {
|
|
auto reads_enabled = !app.configuration().count("no-reads");
|
|
auto seconds = app.configuration()["seconds"].as<unsigned>();
|
|
|
|
engine().at_exit([] {
|
|
cancelled = true;
|
|
return make_ready_future();
|
|
});
|
|
|
|
timer<> completion_timer;
|
|
completion_timer.set_callback([&] {
|
|
test_log.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();
|
|
database& db = env.local_db();
|
|
auto s = db.find_schema("ks", "cf");
|
|
column_family& cf = db.find_column_family(s->id());
|
|
cf.set_compaction_strategy(sstables::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, data_value(pk).serialize());
|
|
return dht::global_partitioner().decorate_key(*s, key);
|
|
};
|
|
|
|
auto pkey = make_pkey("key1");
|
|
sstring value = sstring(sstring::initialized_later(), 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;").get0();
|
|
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, data_value(ckey_seq++).serialize());
|
|
auto&& col = *s->get_column_definition(to_bytes("v"));
|
|
m.set_clustered_cell(ck, col, atomic_cell::make_live(*col.type, api::new_timestamp(), data_value(value).serialize()));
|
|
auto t0 = clock::now();
|
|
db.apply(s, freeze(m)).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);
|
|
});
|
|
}
|