Skip to content

Commit

Permalink
perf(cluster): Optimize target/LARGEST lookups
Browse files Browse the repository at this point in the history
If `ClusterProvider.supportsMinimalClusters()` is true, we can now sort and
filter on the set of unexpanded server groups.

Only the actual LARGEST server group will be expanded.

This offers significant savings for target/LARGEST lookups on
clusters with > 1 server group, particularly those containing _many_
instances.

A target/LARGEST lookup commonly occurs when doing a clone operation
with `useSourceCapacity` set to `true`.
  • Loading branch information
ajordens committed Nov 2, 2017
1 parent dca9784 commit 6e9e04c
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,14 @@ class AmazonClusterProvider implements ClusterProvider<AmazonCluster> {
}
instances.get(it)
} ?: []

if (!serverGroup.instances && serverGroupEntry.attributes.instances) {
// has no direct instance relationships but we can partially populate instances based on attributes.instances
serverGroup.instances = serverGroupEntry.attributes.instances.collect {
new AmazonInstance(((Map) it) + [name: it.instanceId])
}
}

[(serverGroupEntry.id) : serverGroup]
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,12 @@ interface ClusterProvider<T extends Cluster> {
* Determines whether or not optimizations can be made by retrieving minimal or unexpanded clusters.
*
* This primarily affects how server groups are loaded for a cluster (@see com.netflix.spinnaker.clouddriver.controllers.ClusterController}.
*
* Minimal cluster support requires that server groups contained within a cluster be populated with:
* - creation time stamps
* - region / zone details
* - disabled status
* - instance counts (fully populated instances are not necessary)
*/
boolean supportsMinimalClusters()
}
Original file line number Diff line number Diff line change
Expand Up @@ -234,10 +234,6 @@ class ClusterController {
)
}

def expandServerGroups = { List<ServerGroup> serverGroups ->
return sortedServerGroups.collect { expandServerGroup(it) }
}

switch (tsg) {
case TargetServerGroup.CURRENT:
return expandServerGroup(sortedServerGroups.get(0))
Expand All @@ -254,10 +250,10 @@ class ClusterController {
return expandServerGroup(sortedServerGroups.last())
case TargetServerGroup.LARGEST:
// Choose the server group with the most instances, falling back to newest in the case of a tie.
return expandServerGroups(sortedServerGroups).sort { lhs, rhs ->
return expandServerGroup(sortedServerGroups.sort { lhs, rhs ->
rhs.instances.size() <=> lhs.instances.size() ?:
rhs.createdTime <=> lhs.createdTime
}.get(0)
rhs.createdTime <=> lhs.createdTime
}.get(0))
case TargetServerGroup.FAIL:
if (sortedServerGroups.size() > 1) {
throw new NotFoundException("More than one target found (scope: ${scope}, serverGroups: ${sortedServerGroups*.name})")
Expand Down

0 comments on commit 6e9e04c

Please sign in to comment.