1
0
mirror of http://git.haproxy.org/git/haproxy.git/ synced 2025-04-07 01:31:35 +00:00

MINOR: stktable: implement "recv-only" table option

When "recv-only" keyword is added on a stick table declaration (in peers
or proxy section), haproxy considers that the table is only used for
data retrieval from a remote location and not used to perform local
updates. As such, it enables the retrieval of local-only values such
as conn_cur that are ignored by default. This can be useful in some
contexts where we want to know about local-values such are conn_cur
from a remote peer.

To do this, add stktable struct flags  which default to NONE and enable
the RECV_ONLY flag on the table then "recv-only" keyword is found in the
table declaration. Then, when in peer_treat_updatemsg(), when handling
table updates, don't ignore data updates for local-only values if the flag
is set.
This commit is contained in:
Aurelien DARRAGON 2024-12-05 10:28:50 +01:00
parent 3c239b2f80
commit 1f73d3524d
4 changed files with 43 additions and 11 deletions

View File

@ -4714,13 +4714,19 @@ user <username> [password|insecure-password <password>]
It is possible to propagate entries of any data-types in stick-tables between
several HAProxy instances over TCP connections in a multi-master fashion. Each
instance pushes its local updates and insertions to remote peers. The pushed
values overwrite remote ones without aggregation. As an exception, the data
type "conn_cur" is never learned from peers, as it is supposed to reflect local
values. Earlier versions used to synchronize it and to cause negative values in
active-active setups, and always-growing values upon reloads or active-passive
values overwrite remote ones without aggregation.
One exception is the data type "conn_cur" which is never learned from peers by
default as it is supposed to reflect local values. Earlier versions used to
synchronize it by default which was known to cause negative values in active-
active setups, and always-growing values upon reloads or active-passive
switches because the local value would reflect more connections than locally
present. This information, however, is pushed so that monitoring systems can
watch it.
present. However there are some setups where it could be relevant to learn
this value from peers, for instance when the table is a passive remote table
solely used to learn/monitor data from it without relying on it for write-
oriented operations or updates. To achieve this, the "recv-only" keyword can
be added on the table declaration. In any case, the "conn_cur" info is always
pushed so that monitoring systems can watch it.
Interrupted exchanges are automatically detected and recovered from the last
known point. In addition, during a soft restart, the old process connects to
@ -4845,6 +4851,7 @@ shards <shards>
table <tablename> type {ip | integer | string [len <length>] | binary [len <length>]}
size <size> [expire <expire>] [write-to <wtable>] [nopurge] [store <data_type>]*
[recv-only]
Configure a stickiness table for the current section. This line is parsed
exactly the same way as the "stick-table" keyword in others section, except
@ -12879,6 +12886,7 @@ stick store-request <pattern> [table <table>] [{if | unless} <condition>]
stick-table type {ip | integer | string [len <length>] | binary [len <length>]}
size <size> [expire <expire>] [nopurge] [peers <peersect>] [srvkey <srvkey>]
[write-to <wtable>] [store <data_type>]* [brates-factor <factor>]
[recv-only]
Configure the stickiness table for the current section
May be used in the following contexts: tcp, http
@ -13007,6 +13015,18 @@ stick-table type {ip | integer | string [len <length>] | binary [len <length>]}
defined period. The factor must be greater than 0 and lower or
equal to 1024.
[recv-only] indicates that we don't intent to use the table to perform
updates on it, but thay we only plan on using the table to
retrieve data from a remote peer which we are interested in.
Indeed, the use of this keyword enables the retrieval of
local-only values such as conn_cur that are not learned by
default as they would conflict with local updates performed
on the table by the local peer. Use of this option is only
relevant for tables that are not involved in tracking rules or
methods that perform update operations on the table, or put
simpler: remote tables that are only used to retrieve
information.
The data types that can be stored with an entry are the following :
- server_id : this is an integer which holds the numeric ID of the server a
request was assigned to. It is used by the "stick match", "stick store",

View File

@ -155,6 +155,10 @@ struct stksess {
/* WARNING! do not put anything after <keys>, it's used by the key */
};
#define STK_FL_NONE 0x00
#define STK_FL_RECV_ONLY 0x01 /* table is assumed to be remotely updated only
* (never updated locally)
*/
/* stick table */
struct stktable {
@ -197,6 +201,8 @@ struct stktable {
void *ptr; /* generic ptr to check if set or not */
} write_to; /* updates received on the source table will also update write_to */
uint16_t flags;
THREAD_ALIGN(64);
struct {

View File

@ -1823,12 +1823,14 @@ static int peer_treat_updatemsg(struct appctx *appctx, struct peer *p, int updt,
if (!((1ULL << data_type) & st->remote_data))
continue;
/* We shouldn't learn local-only values. Also, when handling the
* write_to table we must ignore types that can be processed
* so we don't interfere with any potential arithmetic logic
* performed on them (ie: cumulative counters).
/* We shouldn't learn local-only values unless the table is
* considered as "recv-only". Also, when handling the write_to
* table we must ignore types that can be processed so we don't
* interfere with any potential arithmetic logic performed on
* them (ie: cumulative counters).
*/
if (stktable_data_types[data_type].is_local ||
if ((stktable_data_types[data_type].is_local &&
!(table->flags & STK_FL_RECV_ONLY)) ||
(table != st->table && !stktable_data_types[data_type].as_is))
ignore = 1;

View File

@ -1373,6 +1373,10 @@ int parse_stick_table(const char *file, int linenum, char **args,
}
idx++;
}
else if (strcmp(args[idx], "recv-only") == 0) {
t->flags |= STK_FL_RECV_ONLY;
idx++;
}
else if (strcmp(args[idx], "write-to") == 0) {
char *write_to;