MXS-1777: Add an EMAverage to the server struct, and a new slave selection criteria.

This is to support calculating the average from a session, and the slave selection criteria to be able to route based on averages. This commit, like the next one, have TODOs which you should feel free to comment on. Undecided things.
This commit is contained in:
Niclas Antti 2018-07-26 10:21:39 +03:00
parent cdea8aa7be
commit 1e6509423a
6 changed files with 60 additions and 8 deletions

View File

@ -159,6 +159,9 @@ typedef struct server
* by rwsplit. TODO: Move to rwsplit */
bool warn_ssl_not_enabled; /**< SSL not used for an SSL enabled server */
MxsDiskSpaceThreshold* disk_space_threshold; /**< Disk space thresholds */
// TODO, this is a plain ptr to a C++ class. Soonish, when the server is new/deleted
// this will become a std::unique ptr. But not in this commit.
maxbase::EMAverage* response_time; /**< for calculating average response time */
} SERVER;
/**
@ -444,6 +447,17 @@ json_t* server_list_to_json(const char* host);
*/
bool server_set_disk_space_threshold(SERVER *server, const char *disk_space_threshold);
/**
* @brief Add a response average to the server response average.
*
* @param server The server.
* @param ave Average.
* @param num_samples Number of samples the average consists of.
*
*/
void server_add_response_average(SERVER *server, double ave, int num_samples);
extern int server_free(SERVER *server);
extern SERVER *server_find_by_unique_name(const char *name);
extern int server_find_by_unique_names(char **server_names, int size, SERVER*** output);
extern SERVER *server_find(const char *servname, unsigned short port);
@ -455,7 +469,8 @@ extern void server_transfer_status(SERVER *dest_server, const SERVER *source_ser
extern void server_add_mon_user(SERVER *server, const char *user, const char *passwd);
extern size_t server_get_parameter(const SERVER *server, const char *name, char* out, size_t size);
extern void server_update_credentials(SERVER *server, const char *user, const char *passwd);
extern DCB* server_get_persistent(SERVER *server, const char *user, const char* ip, const char *protocol, int id);
extern DCB* server_get_persistent(SERVER *server, const char *user, const char* ip, const char *protocol,
int id);
extern void server_update_address(SERVER *server, const char *address);
extern void server_update_port(SERVER *server, unsigned short port);
extern uint64_t server_map_status(const char *str);

View File

@ -62,7 +62,9 @@ void CumulativeAverage::reset()
}
EMAverage::EMAverage(double min_alpha, double max_alpha, int sample_max) :
m_min_alpha{min_alpha}, m_max_alpha{max_alpha}, m_sample_max{sample_max}
m_min_alpha{min_alpha},
m_max_alpha{max_alpha},
m_sample_max{sample_max}
{
}

View File

@ -3608,6 +3608,11 @@ int create_new_server(CONFIG_CONTEXT *obj)
}
}
// nantti, TODO. Decide whether to expose some of this in config, or if the values
// can be calculated at runtime. The "500" or sample_max affects how often a
// session should updates this stat. sample_max should be slightly lower than max sample
// rate (which is less than qps due to the noise filter).
server->response_time = new (std::nothrow) maxbase::EMAverage(0.04, 0.35, 500);
}
else
{
@ -4615,7 +4620,7 @@ bool get_suffixed_size(const char* value, uint64_t* dest)
}
bool config_parse_disk_space_threshold(MxsDiskSpaceThreshold* pDisk_space_threshold,
const char* zDisk_space_threshold)
const char* zDisk_space_threshold)
{
mxb_assert(pDisk_space_threshold);
mxb_assert(zDisk_space_threshold);

View File

@ -28,6 +28,9 @@
#include <string>
#include <list>
#include <mutex>
#include <sstream>
#include <maxbase/stopwatch.hh>
#include <maxscale/config.h>
#include <maxscale/service.h>
@ -228,6 +231,7 @@ void server_free(Server* server)
}
delete server->disk_space_threshold;
delete server->response_time;
delete server;
}
@ -551,6 +555,18 @@ dprintServer(DCB *dcb, const SERVER *server)
dcb_printf(dcb, "\tCurrent no. of conns: %d\n", server->stats.n_current);
dcb_printf(dcb, "\tCurrent no. of operations: %d\n", server->stats.n_current_ops);
dcb_printf(dcb, "\tNumber of routed packets: %lu\n", server->stats.packets);
std::ostringstream ave_os;
if (server->response_time->num_samples())
{
maxbase::Duration dur(server->response_time->average());
ave_os << dur;
}
else
{
ave_os << "not available";
}
dcb_printf(dcb, "\tAverage response time: %s\n", ave_os.str().c_str());
if (server->persistpoolmax)
{
dcb_printf(dcb, "\tPersistent pool size: %d\n", server->stats.n_persistent);
@ -1491,3 +1507,10 @@ bool server_set_disk_space_threshold(SERVER *server, const char *disk_space_thre
return rv;
}
void server_add_response_average(SERVER *server, double ave, int num_samples)
{
spinlock_acquire(&server->lock);
server->response_time->add(ave, num_samples);
spinlock_release(&server->lock);
}

View File

@ -86,14 +86,15 @@ static bool rwsplit_process_router_options(Config& config, char **options)
select_criteria_t c = GET_SELECT_CRITERIA(value);
mxb_assert(c == LEAST_GLOBAL_CONNECTIONS ||
c == LEAST_ROUTER_CONNECTIONS || c == LEAST_BEHIND_MASTER ||
c == LEAST_CURRENT_OPERATIONS || c == UNDEFINED_CRITERIA);
c == LEAST_CURRENT_OPERATIONS || c == LOWEST_RESPONSE_TIME ||
c == UNDEFINED_CRITERIA);
if (c == UNDEFINED_CRITERIA)
{
MXS_ERROR("Unknown slave selection criteria \"%s\". "
"Allowed values are LEAST_GLOBAL_CONNECTIONS, "
"LEAST_ROUTER_CONNECTIONS, LEAST_BEHIND_MASTER,"
"and LEAST_CURRENT_OPERATIONS.",
"LEAST_ROUTER_CONNECTIONS, LEAST_BEHIND_MASTER, "
"LEAST_CURRENT_OPERATIONS and LOWEST_RESPONSE_TIME.",
STRCRITERIA(config.slave_selection_criteria));
success = false;
}

View File

@ -66,7 +66,7 @@ enum select_criteria_t
LEAST_ROUTER_CONNECTIONS, /**< connections established by this router */
LEAST_BEHIND_MASTER,
LEAST_CURRENT_OPERATIONS,
DEFAULT_CRITERIA = LEAST_CURRENT_OPERATIONS,
LOWEST_RESPONSE_TIME,
LAST_CRITERIA /**< not used except for an index */
};
@ -103,6 +103,7 @@ static const MXS_ENUM_VALUE slave_selection_criteria_values[] =
{"LEAST_ROUTER_CONNECTIONS", LEAST_ROUTER_CONNECTIONS},
{"LEAST_BEHIND_MASTER", LEAST_BEHIND_MASTER},
{"LEAST_CURRENT_OPERATIONS", LEAST_CURRENT_OPERATIONS},
{"LOWEST_RESPONSE_TIME", LOWEST_RESPONSE_TIME},
{NULL}
};
@ -134,7 +135,9 @@ static const MXS_ENUM_VALUE master_failure_mode_values[] =
strncmp(s,"LEAST_ROUTER_CONNECTIONS", strlen("LEAST_ROUTER_CONNECTIONS")) == 0 ? \
LEAST_ROUTER_CONNECTIONS : ( \
strncmp(s,"LEAST_CURRENT_OPERATIONS", strlen("LEAST_CURRENT_OPERATIONS")) == 0 ? \
LEAST_CURRENT_OPERATIONS : UNDEFINED_CRITERIA))))
LEAST_CURRENT_OPERATIONS : ( \
strncmp(s,"LOWEST_RESPONSE_TIME", strlen("LOWEST_RESPONSE_TIME")) == 0 ? \
LOWEST_RESPONSE_TIME : UNDEFINED_CRITERIA)))))
#define BACKEND_TYPE(b) (server_is_master((b)->backend_server) ? BE_MASTER : \
(server_is_slave((b)->backend_server) ? BE_SLAVE : BE_UNDEFINED));
@ -337,6 +340,9 @@ static inline const char* select_criteria_to_str(select_criteria_t type)
case LEAST_CURRENT_OPERATIONS:
return "LEAST_CURRENT_OPERATIONS";
case LOWEST_RESPONSE_TIME:
return "LOWEST_RESPONSE_TIME";
default:
return "UNDEFINED_CRITERIA";
}