|
@@ -33,6 +33,30 @@ void set_max_sql_connections_per_thread(int max)
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
+float tune_n_sql_connections(int& nc_to_tune, std::string http_req, int port, int max, int nprocs) {
|
|
|
+
|
|
|
+ std::cout << std::endl << "Benchmark " << http_req << std::endl;
|
|
|
+
|
|
|
+ float max_req_per_s = 0;
|
|
|
+ int best_nconn = 2;
|
|
|
+ for (int nc : {1, 2, 4, 8, 32, 64, 128})
|
|
|
+ {
|
|
|
+ if (nc*nprocs >= max) break;
|
|
|
+ nc_to_tune = nc;
|
|
|
+ float req_per_s = http_benchmark(256, 1, 300, port, http_req);
|
|
|
+ std::cout << nc << " -> " << req_per_s << " req/s." << std::endl;
|
|
|
+ if (req_per_s > max_req_per_s)
|
|
|
+ {
|
|
|
+ max_req_per_s = req_per_s;
|
|
|
+ best_nconn = nc;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ std::cout << "best: " << best_nconn << " (" << max_req_per_s << " req/s)."<< std::endl;
|
|
|
+
|
|
|
+ return best_nconn;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
int main(int argc, char* argv[]) {
|
|
|
|
|
|
if (argc != 3)
|
|
@@ -48,17 +72,12 @@ int main(int argc, char* argv[]) {
|
|
|
auto sql_db =
|
|
|
mysql_database(s::host = argv[1], s::database = "hello_world", s::user = "benchmarkdbuser",
|
|
|
s::password = "benchmarkdbpass", s::port = 3306, s::charset = "utf8");
|
|
|
- int mysql_max_connection = 256;
|
|
|
- li::max_mysql_connections_per_thread = (mysql_max_connection / nprocs);
|
|
|
- std::cout << "Using " << li::max_mysql_connections_per_thread << " connections per thread. " << nprocs << " threads." << std::endl;
|
|
|
-
|
|
|
+ int sql_max_connection = sql_db.connect()("SELECT @@GLOBAL.max_connections;").template read<int>() - 10;
|
|
|
#elif TFB_PGSQL
|
|
|
auto sql_db =
|
|
|
pgsql_database(s::host = argv[1], s::database = "hello_world", s::user = "benchmarkdbuser",
|
|
|
s::password = "benchmarkdbpass", s::port = 5432, s::charset = "utf8");
|
|
|
- int pgsql_max_connection = 256;
|
|
|
- li::max_pgsql_connections_per_thread = (pgsql_max_connection / nprocs);
|
|
|
- std::cout << "Using " << li::max_pgsql_connections_per_thread << " connections per thread. " << nprocs << " threads." << std::endl;
|
|
|
+ int sql_max_connection = atoi(sql_db.connect()("SHOW max_connections;").template read<std::string>().c_str()) - 10;
|
|
|
#endif
|
|
|
|
|
|
auto fortunes = sql_orm_schema(sql_db, "Fortune").fields(
|
|
@@ -69,6 +88,12 @@ int main(int argc, char* argv[]) {
|
|
|
s::id(s::auto_increment, s::primary_key) = int(),
|
|
|
s::randomNumber = int());
|
|
|
|
|
|
+
|
|
|
+ int db_nconn = 64;
|
|
|
+ int queries_nconn = 64;
|
|
|
+ int fortunes_nconn = 64;
|
|
|
+ int updates_nconn = 64;
|
|
|
+
|
|
|
http_api my_api;
|
|
|
|
|
|
my_api.get("/plaintext") = [&](http_request& request, http_response& response) {
|
|
@@ -80,18 +105,18 @@ int main(int argc, char* argv[]) {
|
|
|
response.write_json(s::message = "Hello, World!");
|
|
|
};
|
|
|
my_api.get("/db") = [&](http_request& request, http_response& response) {
|
|
|
- set_max_sql_connections_per_thread(64 / nprocs);
|
|
|
- response.write_json(random_numbers.connect(request.yield).find_one(s::id = 1234).value());
|
|
|
+ set_max_sql_connections_per_thread(db_nconn);
|
|
|
+ response.write_json(random_numbers.connect(request.fiber).find_one(s::id = 1234).value());
|
|
|
};
|
|
|
|
|
|
my_api.get("/queries") = [&](http_request& request, http_response& response) {
|
|
|
- set_max_sql_connections_per_thread(1);
|
|
|
+ set_max_sql_connections_per_thread(queries_nconn);
|
|
|
std::string N_str = request.get_parameters(s::N = std::optional<std::string>()).N.value_or("1");
|
|
|
int N = atoi(N_str.c_str());
|
|
|
|
|
|
N = std::max(1, std::min(N, 500));
|
|
|
|
|
|
- auto c = random_numbers.connect(request.yield);
|
|
|
+ auto c = random_numbers.connect(request.fiber);
|
|
|
std::vector<decltype(random_numbers.all_fields())> numbers(N);
|
|
|
for (int i = 0; i < N; i++)
|
|
|
numbers[i] = c.find_one(s::id = 1 + rand() % 10000).value();
|
|
@@ -100,14 +125,14 @@ int main(int argc, char* argv[]) {
|
|
|
};
|
|
|
|
|
|
my_api.get("/updates") = [&](http_request& request, http_response& response) {
|
|
|
- set_max_sql_connections_per_thread(1);
|
|
|
+ set_max_sql_connections_per_thread(updates_nconn);
|
|
|
std::string N_str = request.get_parameters(s::N = std::optional<std::string>()).N.value_or("1");
|
|
|
int N = atoi(N_str.c_str());
|
|
|
N = std::max(1, std::min(N, 500));
|
|
|
std::vector<decltype(random_numbers.all_fields())> numbers(N);
|
|
|
|
|
|
{
|
|
|
- auto c = random_numbers.connect(request.yield);
|
|
|
+ auto c = random_numbers.connect(request.fiber);
|
|
|
auto& raw_c = c.backend_connection();
|
|
|
|
|
|
|
|
@@ -144,12 +169,12 @@ int main(int argc, char* argv[]) {
|
|
|
};
|
|
|
|
|
|
my_api.get("/fortunes") = [&](http_request& request, http_response& response) {
|
|
|
- set_max_sql_connections_per_thread(64 / nprocs);
|
|
|
+ set_max_sql_connections_per_thread(fortunes_nconn);
|
|
|
|
|
|
typedef decltype(fortunes.all_fields()) fortune;
|
|
|
std::vector<fortune> table;
|
|
|
|
|
|
- auto c = fortunes.connect(request.yield);
|
|
|
+ auto c = fortunes.connect(request.fiber);
|
|
|
c.forall([&] (auto f) { table.emplace_back(f); });
|
|
|
table.emplace_back(0, "Additional fortune added at request time.");
|
|
|
|
|
@@ -172,8 +197,24 @@ int main(int argc, char* argv[]) {
|
|
|
response.write(ss.to_string_view());
|
|
|
};
|
|
|
|
|
|
- http_serve(my_api, port, s::nthreads = nprocs);
|
|
|
+ // Tune the number of sql connections.
|
|
|
+ int tunning_port = port+1;
|
|
|
+ std::thread server_thread([&] {
|
|
|
+ http_serve(my_api, tunning_port, s::nthreads = nprocs);
|
|
|
+ });
|
|
|
+ usleep(3e5);
|
|
|
+
|
|
|
+ tune_n_sql_connections(db_nconn, "GET /db HTTP/1.1\r\n\r\n", tunning_port, sql_max_connection, nprocs);
|
|
|
+ tune_n_sql_connections(queries_nconn, "GET /queries?N=20 HTTP/1.1\r\n\r\n", tunning_port, sql_max_connection, nprocs);
|
|
|
+ tune_n_sql_connections(fortunes_nconn, "GET /fortunes HTTP/1.1\r\n\r\n", tunning_port, sql_max_connection, nprocs);
|
|
|
+ tune_n_sql_connections(updates_nconn, "GET /updates?N=20 HTTP/1.1\r\n\r\n", tunning_port, sql_max_connection, nprocs);
|
|
|
|
|
|
- return 0;
|
|
|
+ li::quit_signal_catched = true;
|
|
|
+ server_thread.join();
|
|
|
+ li::quit_signal_catched = false;
|
|
|
+
|
|
|
+ // Start the server for the Techempower benchmark.
|
|
|
+ http_serve(my_api, port, s::nthreads = nprocs);
|
|
|
|
|
|
+ return 0;
|
|
|
}
|