Skip to content

Commit

Permalink
Dev load balancer (#2)
Browse files Browse the repository at this point in the history
* ✨ new operational mode - percent with CPU

* 🐛 syntax errors

* 🐛 cherry pick duplicate

* 🐛 prevent divide by zero

* 📝 improve log message

* 📝 improve log message

* 🐛 incorrect type

* 📝 improve log message

* 📝 improve log message

* 📝 improve log message

* 📝 improve log message

* Dev cpufactor (#1)

* new operational mode - percent with CPU

* 🐛 fix print of str type

* remove comment

* modify character choice for new flag

* document new integrated estimation flag usage

* ✨ create CPU factor option flag

* document new integrated estimation flag usage

* 📝 CPU factor is optional, improve description

* capture docs in template rather than README directly
  • Loading branch information
spacetourist authored Jun 10, 2024
1 parent 2026185 commit ffead20
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 7 deletions.
35 changes: 34 additions & 1 deletion modules/load_balancer/doc/load_balancer_admin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,35 @@ modparam("load_balancer", "cluster_sharing_tag", "vip")
</example>
</section>

<section id="param_use_cpu_factor" xreflabel="use_cpu_factor">
<title><varname>use_cpu_factor</varname> (integer)</title>
<para>
This is only relevant for "integrated estimation" mode.
</para>
<para>
If enabled, the CPU factor collected in the most recent heartbeat
will be used to reduce the capacity of each FreeSWITCH instance.
</para>
<para>
When disabled, no CPU factor will be applied in the calculation.
</para>
<para>

</para>

<emphasis>
Default value is <quote>empty (disabled)</quote>.
</emphasis>
<example>
<title>Set <varname>use_cpu_factor</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("load_balancer", "use_cpu_factor", 1)
...
</programlisting>
</example>
</section>

</section>


Expand Down Expand Up @@ -592,8 +621,12 @@ modparam("load_balancer", "cluster_sharing_tag", "vip")
performed using the most recent heartbeat data and a
counter of all sessions allocated since the last heartbeat.
Profile counting is unused in the calculation. The reported
CPU load value is used to reduce session load on systems
CPU load value is optionally used to reduce session load on systems
with high CPU utilisation. Mutually exclusive with flag "r".

This is well suited to high performance systems where many calls
may arrive within the heartbeat period (which should be set to the
minimum value 1s when used with this algorithm).
</para>
</listitem>
<listitem>
Expand Down
15 changes: 11 additions & 4 deletions modules/load_balancer/lb_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
/* dialog stuff */
extern struct dlg_binds lb_dlg_binds;

extern int use_cpu_factor;
extern int fetch_freeswitch_stats;
extern int initial_fs_load;
extern struct fs_binds fs_api;
Expand Down Expand Up @@ -429,11 +430,17 @@ static int get_dst_load(struct lb_resource **res, unsigned int res_no,
if( dst->rmap[l].max_load )
av = 100 - (100 * lb_dlg_binds.get_profile_size(res[k]->profile, &dst->profile_id) / dst->rmap[l].max_load);
} else if( flags & LB_FLAGS_PERCENT_WITH_CPU ) {
/* generate score based on the percentage of channels occupied, reduced by CPU idle factor */
if( dst->rmap[l].max_sessions ) {
av = ( 100 - ( 100 * ( dst->rmap[l].current_sessions + dst->rmap[l].sessions_since_last_heartbeat ) / dst->rmap[l].max_sessions ) ) * dst->rmap[l].cpu_idle;
LM_DBG("destination %d <%.*s> availability score %d (sessions=%d since_last_hb=%d max_sess=%d cpu_idle=%.2f)", dst->id, dst->uri.len, dst->uri.s, av, dst->rmap[l].current_sessions, dst->rmap[l].sessions_since_last_heartbeat, dst->rmap[l].max_sessions, dst->rmap[l].cpu_idle);
}
if(use_cpu_factor) {
/* generate score based on the percentage of channels occupied, reduced by CPU idle factor */
av = ( 100 - ( 100 * ( dst->rmap[l].current_sessions + dst->rmap[l].sessions_since_last_heartbeat ) / dst->rmap[l].max_sessions ) ) * dst->rmap[l].cpu_idle;
LM_DBG("destination %d <%.*s> availability score %d (sessions=%d since_last_hb=%d max_sess=%d cpu_idle=%.2f)", dst->id, dst->uri.len, dst->uri.s, av, dst->rmap[l].current_sessions, dst->rmap[l].sessions_since_last_heartbeat, dst->rmap[l].max_sessions, dst->rmap[l].cpu_idle);
} else {
/* generate score based on the percentage of channels occupied */
av = 100 - ( 100 * ( dst->rmap[l].current_sessions + dst->rmap[l].sessions_since_last_heartbeat ) / dst->rmap[l].max_sessions );
LM_DBG("destination %d <%.*s> availability score %d (sessions=%d since_last_hb=%d max_sess=%d)", dst->id, dst->uri.len, dst->uri.s, av, dst->rmap[l].current_sessions, dst->rmap[l].sessions_since_last_heartbeat, dst->rmap[l].max_sessions);
}
}
} else {
av = dst->rmap[l].max_load - lb_dlg_binds.get_profile_size(res[k]->profile, &dst->profile_id);
}
Expand Down
8 changes: 6 additions & 2 deletions modules/load_balancer/load_balancer.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ str lb_probe_from = str_init("sip:prober@localhost");
static int* probing_reply_codes = NULL;
static int probing_codes_no = 0;

int use_cpu_factor;

int fetch_freeswitch_stats;
int initial_fs_load = 1000;

Expand Down Expand Up @@ -173,6 +175,7 @@ static const param_export_t mod_params[]={
{ "cluster_id", INT_PARAM, &lb_cluster_id },
{ "cluster_sharing_tag", STR_PARAM, &lb_cluster_shtag },
{ "fetch_freeswitch_stats", INT_PARAM, &fetch_freeswitch_stats },
{ "use_cpu_factor", INT_PARAM, &use_cpu_factor },
{ "initial_freeswitch_load", INT_PARAM, &initial_fs_load },
{ 0,0,0 }
};
Expand Down Expand Up @@ -299,7 +302,7 @@ static void lb_inherit_state(struct lb_data *old_data,struct lb_data *new_data)
strncasecmp(new_dst->uri.s, old_dst->uri.s, old_dst->uri.len)==0) {
LM_DBG("DST %d/<%.*s> found in old set, copying state\n",
new_dst->group, new_dst->uri.len,new_dst->uri.s);
/* first reset the existing flags (only the flags related
/* first reset the existing flags (only the flags related
* to state!!!) */
new_dst->flags &=
~(LB_DST_STAT_DSBL_FLAG|LB_DST_STAT_NOEN_FLAG);
Expand Down Expand Up @@ -569,7 +572,7 @@ static int w_lb_start(struct sip_msg *req, int *grp_no,
return -5;
}
flags |= LB_FLAGS_PERCENT_WITH_CPU;
LM_DBG("using integrated estimation (percentage of max sessions with CPU factor estimation) \n");
LM_DBG("using integrated estimation (percentage of max sessions used, tracing real time allocations) \n");
break;
case 'n':
flags |= LB_FLAGS_NEGATIVE;
Expand Down Expand Up @@ -807,6 +810,7 @@ static void lb_update_max_loads(unsigned int ticks, void *param)
dst->rmap[ri].resource->profile, &dst->profile_id);
old = dst->rmap[ri].max_load;

// if ( flags & LB_FLAGS_PERCENT_WITH_CPU ) { todo flags not avavilable here
/*
* In LB_FLAGS_PERCENT_WITH_CPU mode we capture the raw values and use these in each LB calculation. This
* means we do not use profile counting in the load calculation. This is suitable for
Expand Down

0 comments on commit ffead20

Please sign in to comment.