RE: [PATCH 0/1] Introduce 'NOROOM' status for srv_state metric

2023-09-06 Thread Cedric Paillet
Hi,

Tanks for you feedbacks.

> Indeed, so actually you found a pretty valid use case to the edge case I was 
> seeing as rare enough not to be of much interest :-)

Just to provide some background, which might help in understanding our needs:

In our real-life scenarios, servers do not have uniform performance. Our 
haproxy "servers", in our context, are typically containers. These containers 
can reside on very diverse hardware, depending on the age of the server. We 
attempt to mitigate these discrepancies with server weights, but that's not 
always sufficient; not all servers respond at the same speed. The performance 
can also be compromised by "noisy" neighbors co-hosted on the same server. 
Sometimes we even have instances that fail because the underlying code is 
poorly written.
I don't know if it's common with others, but when a backend starts to become 
overloaded, it happens gradually, and during the initial days, the first 
symptoms are a few servers becoming FULL during peak hours.


> Yes that's it. For this specific use case, watching the queue is much simpler 
> and provides more than just a boolean

Your discussion about queues is very interesting, and I believe we will 
incorporate those into our metrics.

My idea is not to present a boolean, but a percentage of FULL servers by 
backend.

We believe it's more illustrative to see that around 7 a.m., all servers are 
functioning, but by 7:10 a.m., 10% of the servers begin to be "FULL" due to the 
increase in traffic. By 7:30 a.m., it's 50%, and by 8 a.m., it's 100%.

We think this curve is simpler to grasp than just seeing, at 8 a.m., a queue 
beginning to grow, while all these servers still seem OK 
(haproxy_backend_agg_check_status=L7OK, and 
haproxy_backend_agg_server_status="UP").

Currently, we compute this metric using this Prometheus calculation:
count by (proxy, instance) (haproxy_server_current_sessions > 180)
(even though we have a maxconn set at 200).

This calculation has several issues:
- maxconn cannot be retrieved; it has to be hardcoded in Prometheus.
- it forces us to use "/metrics?scope=server", which scrapes all server 
metrics, something we're trying to avoid, because it consumes a lot of 
resources to aggragate on prometheus.

With my patch, we can achieve the same with count by (proxy, instance) 
(haproxy_backend_agg_server_status="FULL"), just by using 
/metrics?scope=backend.

The main question I'm asking myself is whether my calculation method will work, 
because a server that starts to saturate will "oscillate" between FULL and OK. 
We risk missing it, not necessarily capturing the value at the right time.

Cedric

-Message d'origine-----
De : Willy Tarreau  
Envoyé : mercredi 6 septembre 2023 10:36
À : Cedric Paillet 
Cc : haproxy@formilux.org
Objet : Re: [PATCH 0/1] Introduce 'NOROOM' status for srv_state metric

Hi Cedric,

On Tue, Sep 05, 2023 at 01:40:14PM +, Cedric Paillet wrote:
> We are using Prometheus to provide feedback to our users about the 
> status of backend servers. Currently, we have no means of informing 
> them if a server exceeds the maxconn limit, and consequently why it's 
> no longer receiving new requests.
> 
> Therefore, we would like to be able to display when a server surpasses 
> the maxconn limit and is in the "noroom" state. I have prepared a 
> patch specifically for Prometheus, but it might be better to include a 
> boolean directly in the server structure indicating whether the server 
> was considered to have no room the last time server_has_room was 
> called. However, this change seems to have a significant impact on other 
> parts of the code.

I think that it might be more suitable to use the term "FULL" that we already 
use for the listeners, and that also matches what's used at a few places in the 
doc in association with servers or backends being "full".

Also, a more accurate metric that is generally watched is the queue (both 
server and backend): instead of being a boolean, it directly indicates how many 
additional servers are needed to improve the processing time. Persistent 
requests are placed into the server's queue but all other requests go into the 
backend queue. So if you have a total capacity of 4 servers * 100 connections = 
400 outstanding requests, and you see a queue of 200, you know that you'd need 
two extra servers to process these without queuing, and you can even predict 
that the total processing time will decrease by 200*the average queue time, so 
this allows to even add just the required number of servers to keep response 
time below a certain limit.

The only case where a server will be full without having any queue is when the 
total number of outstanding requests on a backend is exactly equal to the sum 
of t

Re: [PATCH 0/1] Introduce 'NOROOM' status for srv_state metric

2023-09-06 Thread Willy Tarreau
On Wed, Sep 06, 2023 at 12:44:56PM +, Cedric Paillet wrote:
> >I think that it might be more suitable to use the term "FULL"
> Ok, no problem with that. (Perhaps we can also rename server_has_room to 
> !server_is_full ?)

You're right, it might be clearer!

> > Also, a more accurate metric that is generally watched is the queue (both 
> > server and backend): 
> 
> My first use case is to detect/display one or more server(s) with problems,
> not to determine if the entire backend is undersized.
> As I understand it, if just one server in the pool is very slow (and the load
> balancing method is round-robin), the number of sessions on this server will
> increase until it reaches maxconn. At this juncture, the server will no
> longer be selected, and requests will be routed to the other servers. Then,
> no queue (either backend or server) will start to fill up, correct? But the
> slow server will cease receiving requests until its session count drops below
> maxconn, right?

Indeed, so actually you found a pretty valid use case to the edge case I
was seeing as rare enough not to be of much interest :-)

> The second use case, as you've outlined, is to detect if a backend is
> undersized. My understanding is that if the backend is "nearly" undersized,
> the first symptom will be some servers reporting "FULL". Only when ALL
> servers are reporting "FULL" will the backend queue start to grow, correct?

Yes that's it. For this specific use case, watching the queue is much
simpler and provides more than just a boolean. But to be clear, the
situation between one server full and all server full is very unstable,
as queuing is an exponential function of response time by definition,
so once a server is full, you can be certain that all other ones are
about to be full as well, and between the two you'll have a lot of
noise where servers are randomly full then ready depending on the
load. Let's say you're having 40 servers processing 1 requests
per second with a maxconn 50. That's a total capacity of 2000
outstanding requests (and as many concurrent connections). This
means requests will last on average 200ms at saturation. At 196 ms
response time you'll have 1960 outstanding requests, hence 49 per
server, thus no server marked full. At 200ms all will be full. At 198ms,
half of the servers will be marked full, and that changes for every
single request, i.e. 250 times per second per server. Now you can see
how sampling such a boolean only once every few seconds when it changes
250 times per second will be useless for scalability purposes, you're
just sampling a random value. On the opposite, retrieving the queue
length is more stable since it's for the whole backend and not just
per server, plus it reports more than a boolean.

Hoping this helps,
Willy



RE: [PATCH 0/1] Introduce 'NOROOM' status for srv_state metric

2023-09-06 Thread Cedric Paillet
Thanks for your review.

>I think that it might be more suitable to use the term "FULL"
Ok, no problem with that. (Perhaps we can also rename server_has_room to 
!server_is_full ?)


> Also, a more accurate metric that is generally watched is the queue (both 
> server and backend): 

My first use case is to detect/display one or more server(s) with problems, not 
to determine if the entire backend is undersized.
As I understand it, if just one server in the pool is very slow (and the load 
balancing method is round-robin), the number of sessions on this server will 
increase until it reaches maxconn. At this juncture, the server will no longer 
be selected, and requests will be routed to the other servers. Then, no queue 
(either backend or server) will start to fill up, correct? But the slow server 
will cease receiving requests until its session count drops below maxconn, 
right?

The second use case, as you've outlined, is to detect if a backend is 
undersized. My understanding is that if the backend is "nearly" undersized, the 
first symptom will be some servers reporting "FULL". Only when ALL servers are 
reporting "FULL" will the backend queue start to grow, correct?

Cédric


-Message d'origine-
De : Willy Tarreau  
Envoyé : mercredi 6 septembre 2023 10:36
À : Cedric Paillet 
Cc : haproxy@formilux.org
Objet : Re: [PATCH 0/1] Introduce 'NOROOM' status for srv_state metric

Hi Cedric,

On Tue, Sep 05, 2023 at 01:40:14PM +, Cedric Paillet wrote:
> We are using Prometheus to provide feedback to our users about the 
> status of backend servers. Currently, we have no means of informing 
> them if a server exceeds the maxconn limit, and consequently why it's 
> no longer receiving new requests.
> 
> Therefore, we would like to be able to display when a server surpasses 
> the maxconn limit and is in the "noroom" state. I have prepared a 
> patch specifically for Prometheus, but it might be better to include a 
> boolean directly in the server structure indicating whether the server 
> was considered to have no room the last time server_has_room was 
> called. However, this change seems to have a significant impact on other 
> parts of the code.

I think that it might be more suitable to use the term "FULL" that we already 
use for the listeners, and that also matches what's used at a few places in the 
doc in association with servers or backends being "full".

Also, a more accurate metric that is generally watched is the queue (both 
server and backend): instead of being a boolean, it directly indicates how many 
additional servers are needed to improve the processing time. Persistent 
requests are placed into the server's queue but all other requests go into the 
backend queue. So if you have a total capacity of 4 servers * 100 connections = 
400 outstanding requests, and you see a queue of 200, you know that you'd need 
two extra servers to process these without queuing, and you can even predict 
that the total processing time will decrease by 200*the average queue time, so 
this allows to even add just the required number of servers to keep response 
time below a certain limit.

The only case where a server will be full without having any queue is when the 
total number of outstanding requests on a backend is exactly equal to the sum 
of the servers' maxconn values, so as you see, the extra metric covers very 
little compared to the queue itself. But there might be good use cases for 
this, I'm not denying it, I just wanted to make sure that you're going to 
monitor what's really relevant for your use case ;-)

Willy



Re: [PATCH 0/1] Introduce 'NOROOM' status for srv_state metric

2023-09-06 Thread Willy Tarreau
Hi Cedric,

On Tue, Sep 05, 2023 at 01:40:14PM +, Cedric Paillet wrote:
> We are using Prometheus to provide feedback to our users about the status of
> backend servers. Currently, we have no means of informing them if a server
> exceeds the maxconn limit, and consequently why it's no longer receiving new
> requests.
> 
> Therefore, we would like to be able to display when a server surpasses the
> maxconn limit and is in the "noroom" state. I have prepared a patch
> specifically for Prometheus, but it might be better to include a boolean
> directly in the server structure indicating whether the server was considered
> to have no room the last time server_has_room was called. However, this
> change seems to have a significant impact on other parts of the code.

I think that it might be more suitable to use the term "FULL" that we
already use for the listeners, and that also matches what's used at a
few places in the doc in association with servers or backends being
"full".

Also, a more accurate metric that is generally watched is the queue
(both server and backend): instead of being a boolean, it directly
indicates how many additional servers are needed to improve the
processing time. Persistent requests are placed into the server's
queue but all other requests go into the backend queue. So if you have
a total capacity of 4 servers * 100 connections = 400 outstanding
requests, and you see a queue of 200, you know that you'd need two extra
servers to process these without queuing, and you can even predict that
the total processing time will decrease by 200*the average queue time,
so this allows to even add just the required number of servers to keep
response time below a certain limit.

The only case where a server will be full without having any queue is
when the total number of outstanding requests on a backend is exactly
equal to the sum of the servers' maxconn values, so as you see, the
extra metric covers very little compared to the queue itself. But there
might be good use cases for this, I'm not denying it, I just wanted to
make sure that you're going to monitor what's really relevant for your
use case ;-)

Willy