Support priority reading for readonly servers through weight which is suitable for WAN

This commit is contained in:
wangbin 2022-09-01 10:53:15 +08:00
parent 71ac2a6936
commit d82b8b0366
3 changed files with 73 additions and 8 deletions

View File

@ -2511,9 +2511,10 @@ show_proxy_read_only_backend_address(gpointer param) {
if(old_backend && old_backend->type == BACKEND_TYPE_RO
&& old_backend->state != BACKEND_STATE_DELETED && old_backend->state != BACKEND_STATE_MAINTAINING) {
free_str = g_string_append(free_str, old_backend->address->str);
if(old_backend->server_group && old_backend->server_group->len) {
free_str = g_string_append(free_str, "@");
free_str = g_string_append(free_str, old_backend->server_group->str);
if (old_backend->server_weight) {
free_str = g_string_append(free_str, "#");
free_str = g_string_append_c(
free_str, '0' + old_backend->server_weight);
}
free_str = g_string_append(free_str, ",");
}
@ -2542,10 +2543,12 @@ show_proxy_backend_addresses(gpointer param) {
if(old_backend && old_backend->type == BACKEND_TYPE_RW
&& old_backend->state != BACKEND_STATE_DELETED && old_backend->state != BACKEND_STATE_MAINTAINING) {
free_str = g_string_append(free_str, old_backend->address->str);
if(old_backend->server_group && old_backend->server_group->len) {
free_str = g_string_append(free_str, "@");
free_str = g_string_append(free_str, old_backend->server_group->str);
if (old_backend->server_weight) {
free_str = g_string_append(free_str, "#");
free_str = g_string_append_c(
free_str, '0' + old_backend->server_weight);
}
free_str = g_string_append(free_str, ",");
}
}

View File

@ -56,6 +56,7 @@ network_backend_new()
b->server_group = g_string_new(NULL);
b->address = g_string_new(NULL);
b->server_version = g_string_new(NULL);
b->server_weight = 0;
return b;
}
@ -211,7 +212,19 @@ network_backends_add(network_backends_t *bs, const gchar *address,
if (bs->is_partition_mode) {
network_backends_add_group(bs, NULL);
}
g_string_assign(new_backend->address, address);
/* Only valid for rw mode */
char *weight_p = NULL;
if ((weight_p = strrchr(address, '#')) != NULL) {
bs->priority_mode = 1;
new_backend->server_weight = atoi(weight_p + 1);
if (new_backend->server_weight > MAX_WEIGHT_VALUE) {
new_backend->server_weight = MAX_WEIGHT_VALUE;
}
g_string_assign_len(new_backend->address, address,
weight_p - address);
} else {
g_string_assign(new_backend->address, address);
}
}
if (0 != network_address_set_address(new_backend->addr, new_backend->address->str)) {
@ -538,9 +551,54 @@ network_group_update(network_group_t *gp)
g_list_free(backends);
}
/* round robin choose read only backend */
static int network_backends_get_ro_ndx_by_priority(network_backends_t *bs) {
GArray *active_ro_indices = g_array_sized_new(FALSE, TRUE, sizeof(int), 4);
int count = network_backends_count(bs);
int weight[MAX_WEIGHT_VALUE + 1];
int i;
memset(weight, 0, sizeof(int) * (MAX_WEIGHT_VALUE + 1));
for (i = 0; i < count; i++) {
network_backend_t *backend = network_backends_get(bs, i);
if ((backend->type == BACKEND_TYPE_RO) &&
(backend->state == BACKEND_STATE_UP ||
backend->state == BACKEND_STATE_UNKNOWN)) {
weight[backend->server_weight] = 1;
}
}
int max_weight = 0;
for (i = 0; i <= MAX_WEIGHT_VALUE; i++) {
if (weight[i]) {
max_weight = i;
}
}
for (i = 0; i < count; i++) {
network_backend_t *backend = network_backends_get(bs, i);
if ((backend->type == BACKEND_TYPE_RO) &&
(backend->state == BACKEND_STATE_UP ||
backend->state == BACKEND_STATE_UNKNOWN)) {
if (backend->server_weight == max_weight) {
g_array_append_val(active_ro_indices, i);
}
}
}
int num = active_ro_indices->len;
int result = -1;
if (num > 0) {
result = g_array_index(active_ro_indices, int, (bs->read_count++) % num);
}
g_array_free(active_ro_indices, TRUE);
return result;
}
int network_backends_get_ro_ndx(network_backends_t *bs)
{
if (bs->priority_mode) {
return network_backends_get_ro_ndx_by_priority(bs);
} else {
/* round robin choose read only backend */
GArray* active_ro_indices = g_array_sized_new(FALSE, TRUE, sizeof(int), 4);
int count = network_backends_count(bs);
int i = 0;
@ -558,6 +616,7 @@ int network_backends_get_ro_ndx(network_backends_t *bs)
}
g_array_free(active_ro_indices, TRUE);
return result;
}
}
int

View File

@ -42,6 +42,7 @@ typedef enum {
} backend_state_t;
#define NO_PREVIOUS_STATE -1
#define MAX_WEIGHT_VALUE 9
typedef enum {
BACKEND_TYPE_UNKNOWN,
@ -86,6 +87,7 @@ typedef struct {
time_t last_check_time;
int slave_delay_msec; /* valid if this is a ReadOnly slave */
int server_weight;
GString *server_version;
} network_backend_t;
@ -96,6 +98,7 @@ NETWORK_API int network_backend_init_extra(network_backend_t *b, chassis *chas);
typedef struct {
int is_partition_mode;
int priority_mode;
unsigned int ro_server_num;
unsigned int read_count;
GPtrArray *backends;