Add an option to autobalance a HA cluster automatically
This commit is contained in:
@@ -90,6 +90,11 @@ struct private_ha_segments_t {
|
|||||||
* Timeout for heartbeats received from other node
|
* Timeout for heartbeats received from other node
|
||||||
*/
|
*/
|
||||||
int heartbeat_timeout;
|
int heartbeat_timeout;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interval to check for autobalance, 0 to disable
|
||||||
|
*/
|
||||||
|
int autobalance;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -374,6 +379,54 @@ static void start_heartbeat(private_ha_segments_t *this)
|
|||||||
this, NULL, (callback_job_cancel_t)return_false, JOB_PRIO_CRITICAL));
|
this, NULL, (callback_job_cancel_t)return_false, JOB_PRIO_CRITICAL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take a segment if we are handling less than half of segments
|
||||||
|
*/
|
||||||
|
static job_requeue_t autobalance(private_ha_segments_t *this)
|
||||||
|
{
|
||||||
|
int i, active = 0;
|
||||||
|
|
||||||
|
this->mutex->lock(this->mutex);
|
||||||
|
|
||||||
|
for (i = 1; i <= this->count; i++)
|
||||||
|
{
|
||||||
|
if (this->active & SEGMENTS_BIT(i))
|
||||||
|
{
|
||||||
|
active++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (active < this->count / 2)
|
||||||
|
{
|
||||||
|
for (i = 1; i <= this->count; i++)
|
||||||
|
{
|
||||||
|
if (!(this->active & SEGMENTS_BIT(i)))
|
||||||
|
{
|
||||||
|
DBG1(DBG_CFG, "autobalancing HA (%d/%d active), taking %d",
|
||||||
|
active, this->count, i);
|
||||||
|
enable_disable(this, i, TRUE, TRUE);
|
||||||
|
/* we claim only one in each interval */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this->mutex->unlock(this->mutex);
|
||||||
|
|
||||||
|
return JOB_RESCHEDULE(this->autobalance);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedule autobalancing
|
||||||
|
*/
|
||||||
|
static void start_autobalance(private_ha_segments_t *this)
|
||||||
|
{
|
||||||
|
DBG1(DBG_CFG, "scheduling HA autobalance every %ds", this->autobalance);
|
||||||
|
lib->scheduler->schedule_job(lib->scheduler,
|
||||||
|
(job_t*)callback_job_create_with_prio((callback_job_cb_t)autobalance,
|
||||||
|
this, NULL, (callback_job_cancel_t)return_false, JOB_PRIO_CRITICAL),
|
||||||
|
this->autobalance);
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(ha_segments_t, is_active, bool,
|
METHOD(ha_segments_t, is_active, bool,
|
||||||
private_ha_segments_t *this, u_int segment)
|
private_ha_segments_t *this, u_int segment)
|
||||||
{
|
{
|
||||||
@@ -421,6 +474,8 @@ ha_segments_t *ha_segments_create(ha_socket_t *socket, ha_kernel_t *kernel,
|
|||||||
.heartbeat_timeout = lib->settings->get_int(lib->settings,
|
.heartbeat_timeout = lib->settings->get_int(lib->settings,
|
||||||
"%s.plugins.ha.heartbeat_timeout", DEFAULT_HEARTBEAT_TIMEOUT,
|
"%s.plugins.ha.heartbeat_timeout", DEFAULT_HEARTBEAT_TIMEOUT,
|
||||||
charon->name),
|
charon->name),
|
||||||
|
.autobalance = lib->settings->get_int(lib->settings,
|
||||||
|
"%s.plugins.ha.autobalance", 0, charon->name),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (monitor)
|
if (monitor)
|
||||||
@@ -430,6 +485,10 @@ ha_segments_t *ha_segments_create(ha_socket_t *socket, ha_kernel_t *kernel,
|
|||||||
start_heartbeat(this);
|
start_heartbeat(this);
|
||||||
start_watchdog(this);
|
start_watchdog(this);
|
||||||
}
|
}
|
||||||
|
if (this->autobalance)
|
||||||
|
{
|
||||||
|
start_autobalance(this);
|
||||||
|
}
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user