Add a new lbaas agent Scheduler, LeastPoolAgentScheduler
LeastPoolAgentScheduler assigns a pool to an lbaas-agent with the least number of pools. When there are multiple lbaas-agents on multiple nodes, pools will be evenly distributed over the agents. Thus this scheduler helps the scalability of lbaas-agents serving large number of pools. At the moment only available lbaas-agent scheduler is ChanceScheduler. Co-Authored-By: Adam Harwell <flux.adam@gmail.com> Change-Id: I0b920a8bb5b2918dd5f47ef2a81d3009896af47d
This commit is contained in:
parent
6caf97596e
commit
96afcd6879
|
@ -1,6 +1,7 @@
|
||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
# =========== items for agent scheduler extension =============
|
# =========== items for agent scheduler extension =============
|
||||||
# loadbalancer_pool_scheduler_driver = neutron.services.loadbalancer.agent_scheduler.ChanceScheduler
|
# loadbalancer_pool_scheduler_driver = neutron.services.loadbalancer.agent_scheduler.ChanceScheduler
|
||||||
|
# loadbalancer_pool_scheduler_driver = neutron.services.loadbalancer.agent_scheduler.LeastPoolAgentScheduler
|
||||||
# loadbalancer_scheduler_driver = neutron.agent_scheduler.ChanceScheduler
|
# loadbalancer_scheduler_driver = neutron.agent_scheduler.ChanceScheduler
|
||||||
|
|
||||||
[quotas]
|
[quotas]
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import random
|
import random
|
||||||
|
import sys
|
||||||
|
|
||||||
from neutron.common import constants
|
from neutron.common import constants
|
||||||
from neutron.db import agents_db
|
from neutron.db import agents_db
|
||||||
|
@ -26,6 +27,7 @@ import sqlalchemy as sa
|
||||||
from sqlalchemy import orm
|
from sqlalchemy import orm
|
||||||
from sqlalchemy.orm import joinedload
|
from sqlalchemy.orm import joinedload
|
||||||
|
|
||||||
|
from abc import abstractmethod
|
||||||
from neutron_lbaas.extensions import lbaas_agentscheduler
|
from neutron_lbaas.extensions import lbaas_agentscheduler
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
@ -80,6 +82,11 @@ class LbaasAgentSchedulerDbMixin(agentschedulers_db.AgentSchedulerDbMixin,
|
||||||
else:
|
else:
|
||||||
return {'pools': []}
|
return {'pools': []}
|
||||||
|
|
||||||
|
def num_of_pools_on_lbaas_agent(self, context, id):
|
||||||
|
query = context.session.query(PoolLoadbalancerAgentBinding.pool_id)
|
||||||
|
query = query.filter_by(agent_id=id)
|
||||||
|
return query.count()
|
||||||
|
|
||||||
def get_lbaas_agent_candidates(self, device_driver, active_agents):
|
def get_lbaas_agent_candidates(self, device_driver, active_agents):
|
||||||
candidates = []
|
candidates = []
|
||||||
for agent in active_agents:
|
for agent in active_agents:
|
||||||
|
@ -89,8 +96,7 @@ class LbaasAgentSchedulerDbMixin(agentschedulers_db.AgentSchedulerDbMixin,
|
||||||
return candidates
|
return candidates
|
||||||
|
|
||||||
|
|
||||||
class ChanceScheduler(object):
|
class SchedulerBase(object):
|
||||||
"""Allocate a loadbalancer agent for a vip in a random way."""
|
|
||||||
|
|
||||||
def schedule(self, plugin, context, pool, device_driver):
|
def schedule(self, plugin, context, pool, device_driver):
|
||||||
"""Schedule the pool to an active loadbalancer agent if there
|
"""Schedule the pool to an active loadbalancer agent if there
|
||||||
|
@ -118,7 +124,8 @@ class ChanceScheduler(object):
|
||||||
device_driver)
|
device_driver)
|
||||||
return
|
return
|
||||||
|
|
||||||
chosen_agent = random.choice(candidates)
|
chosen_agent = self._schedule(candidates, plugin, context)
|
||||||
|
|
||||||
binding = PoolLoadbalancerAgentBinding()
|
binding = PoolLoadbalancerAgentBinding()
|
||||||
binding.agent = chosen_agent
|
binding.agent = chosen_agent
|
||||||
binding.pool_id = pool['id']
|
binding.pool_id = pool['id']
|
||||||
|
@ -128,3 +135,29 @@ class ChanceScheduler(object):
|
||||||
{'pool_id': pool['id'],
|
{'pool_id': pool['id'],
|
||||||
'agent_id': chosen_agent['id']})
|
'agent_id': chosen_agent['id']})
|
||||||
return chosen_agent
|
return chosen_agent
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def _schedule(self, candidates, plugin, context):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ChanceScheduler(SchedulerBase):
|
||||||
|
|
||||||
|
def _schedule(self, candidates, plugin, context):
|
||||||
|
"""Allocate a loadbalancer agent for a vip in a random way."""
|
||||||
|
return random.choice(candidates)
|
||||||
|
|
||||||
|
|
||||||
|
class LeastPoolAgentScheduler(SchedulerBase):
|
||||||
|
|
||||||
|
def _schedule(self, candidates, plugin, context):
|
||||||
|
"""Pick an agent with least number of pools from candidates"""
|
||||||
|
current_min_pool_num = sys.maxint
|
||||||
|
# SchedulerBase.schedule() already checks for empty candidates
|
||||||
|
for tmp_agent in candidates:
|
||||||
|
tmp_pool_num = plugin.num_of_pools_on_lbaas_agent(
|
||||||
|
context, tmp_agent['id'])
|
||||||
|
if current_min_pool_num > tmp_pool_num:
|
||||||
|
current_min_pool_num = tmp_pool_num
|
||||||
|
chosen_agent = tmp_agent
|
||||||
|
return chosen_agent
|
||||||
|
|
|
@ -73,7 +73,7 @@ class LBaaSAgentSchedulerTestCase(test_agent.AgentDBTestMixIn,
|
||||||
service_plugins = {
|
service_plugins = {
|
||||||
'lb_plugin_name': test_db_loadbalancer.DB_LB_PLUGIN_KLASS}
|
'lb_plugin_name': test_db_loadbalancer.DB_LB_PLUGIN_KLASS}
|
||||||
|
|
||||||
#default provider should support agent scheduling
|
# default provider should support agent scheduling
|
||||||
cfg.CONF.set_override(
|
cfg.CONF.set_override(
|
||||||
'service_provider',
|
'service_provider',
|
||||||
[('LOADBALANCER:lbaas:neutron_lbaas.services.'
|
[('LOADBALANCER:lbaas:neutron_lbaas.services.'
|
||||||
|
@ -217,3 +217,15 @@ class LBaaSAgentSchedulerTestCase(test_agent.AgentDBTestMixIn,
|
||||||
'fake_id',
|
'fake_id',
|
||||||
expected_code=exc.HTTPForbidden.code,
|
expected_code=exc.HTTPForbidden.code,
|
||||||
admin_context=False)
|
admin_context=False)
|
||||||
|
|
||||||
|
|
||||||
|
class LeastPoolAgentSchedulerTestCase(LBaaSAgentSchedulerTestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
# Setting LeastPoolAgentScheduler as scheduler
|
||||||
|
cfg.CONF.set_override(
|
||||||
|
'loadbalancer_pool_scheduler_driver',
|
||||||
|
'neutron_lbaas.services.loadbalancer.'
|
||||||
|
'agent_scheduler.LeastPoolAgentScheduler')
|
||||||
|
|
||||||
|
super(LeastPoolAgentSchedulerTestCase, self).setUp()
|
||||||
|
|
|
@ -48,6 +48,7 @@ loadbalancer_schedulers =
|
||||||
neutron_lbaas.agent_scheduler.ChanceScheduler = neutron_lbaas.agent_scheduler:ChanceScheduler
|
neutron_lbaas.agent_scheduler.ChanceScheduler = neutron_lbaas.agent_scheduler:ChanceScheduler
|
||||||
pool_schedulers =
|
pool_schedulers =
|
||||||
neutron.services.loadbalancer.agent_scheduler.ChanceScheduler = neutron_lbaas.services.loadbalancer.agent_scheduler:ChanceScheduler
|
neutron.services.loadbalancer.agent_scheduler.ChanceScheduler = neutron_lbaas.services.loadbalancer.agent_scheduler:ChanceScheduler
|
||||||
|
neutron.services.loadbalancer.agent_scheduler.LeastPoolAgentScheduler = neutron_lbaas.services.loadbalancer.agent_scheduler:LeastPoolAgentScheduler
|
||||||
|
|
||||||
[build_sphinx]
|
[build_sphinx]
|
||||||
all_files = 1
|
all_files = 1
|
||||||
|
|
Loading…
Reference in New Issue