improve dvr port update under large scale deployment

update port may takes an excessive number of seconds
to complete if dvr routers are running on more than 100
compute nodes. This patch tries to save some time by removing
unnecessary calls inside looping through hosts.

Change-Id: Ide740e0c5c43c2d2b842460a37c8ce125da12b28
Closes-Bug: #1830456
This commit is contained in:
shenjiatong 2019-05-27 11:26:49 +08:00 committed by 申嘉童
parent 3f837836f6
commit 00eb6f26f6
2 changed files with 17 additions and 12 deletions

View File

@ -13,6 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import collections
from neutron_lib.api.definitions import portbindings
from neutron_lib.api import extensions
from neutron_lib.callbacks import events
@ -141,19 +143,22 @@ class L3_DVRsch_db_mixin(l3agent_sch_db.L3AgentSchedulerDbMixin):
for router_id in router_ids:
hosts |= set(self.get_hosts_to_notify(context, router_id))
for host in hosts:
updated_routers = set()
for router_id in router_ids:
host_routers = collections.defaultdict(set)
for router_id in router_ids:
# avoid calling get_ports in host loop
subnet_ids = self.get_subnet_ids_on_router(
context.elevated(), router_id)
for host in hosts:
LOG.debug('DVR: Handle new service port, host %(host)s, '
'router ids %(router_id)s',
{'host': host, 'router_id': router_id})
if self._check_for_rtr_serviceable_ports(
context.elevated(), router_id, host):
updated_routers.add(router_id)
if self._check_dvr_serviceable_ports_on_host(
context.elevated(), host, subnet_ids):
host_routers[host].add(router_id)
if updated_routers:
self.l3_rpc_notifier.routers_updated_on_host(
context, updated_routers, host)
for host, router_ids in host_routers.items():
self.l3_rpc_notifier.routers_updated_on_host(
context, router_ids, host)
def get_dvr_snat_agent_list(self, context):
agent_filters = {'agent_modes': [n_const.L3_AGENT_MODE_DVR_SNAT]}
@ -358,7 +363,7 @@ class L3_DVRsch_db_mixin(l3agent_sch_db.L3AgentSchedulerDbMixin):
Port.device_owner.in_(
n_utils.get_other_dvr_serviced_device_owners()))
query = query.filter(owner_filter)
hosts = [item[0] for item in query]
hosts = [item[0] for item in query if item[0] != '']
return hosts
def _get_dvr_subnet_ids_on_host_query(self, context, host):

View File

@ -1331,9 +1331,9 @@ class L3DvrSchedulerTestCase(L3SchedulerBaseMixin,
return_value=[agent_on_host]) as get_l3_agents,\
mock.patch.object(
self.dut, 'get_hosts_to_notify',
return_value=['other_host']),\
return_value=['other_host', 'host1']),\
mock.patch.object(
self.dut, '_check_for_rtr_serviceable_ports',
self.dut, '_check_dvr_serviceable_ports_on_host',
return_value=True):
self.dut.dvr_handle_new_service_port(