l3_ha_mode: call bulk _populate_mtu_and_subnets_for_ports

Based on the observation that a call to sync_routers can be very
slow (minutes) on some setup, and that profiling data show that
a significant amount of time is spent in many individual calls
of _process_sync_ha_data to _populate_mtu_and_subnets_for_ports for
a single interface, this change refactors _process_sync_ha_data to
call _populate_mtu_and_subnets_for_ports only once on a list of
interfaces instead of <n> times.

Said otherwise:
- before: O(#routers) SQL queries
          (one per network of an HA interface of a router)
- after : O(1) SQL queries
          (on the set of networks with an HA interface on a router)

A basic test shows a drastic improvements, from minutes to around
one second, in the processing of a sync_routers call with 256 routers.

Change-Id: I3a00c8fbb245ab3b6d93bdaa97f3435570992791
Related-Bug: 1692971
This commit is contained in:
Thomas Morin 2017-06-02 15:36:43 +02:00 committed by Kevin Benton
parent 0d866f1743
commit a08aa3bf2f
1 changed files with 4 additions and 1 deletions

View File

@ -644,10 +644,13 @@ class L3_HA_NAT_db_mixin(l3_dvr_db.L3_NAT_with_dvr_db_mixin,
router[constants.HA_INTERFACE_KEY] = port_dict
router[n_const.HA_ROUTER_STATE_KEY] = binding.state
interfaces = []
for router in routers_dict.values():
interface = router.get(constants.HA_INTERFACE_KEY)
if interface:
self._populate_mtu_and_subnets_for_ports(context, [interface])
interfaces.append(interface)
self._populate_mtu_and_subnets_for_ports(context, interfaces)
# If this is a DVR+HA router, but the agent is question is in 'dvr'
# mode (as opposed to 'dvr_snat'), then we want to always return it