Skip to content

Commit

Permalink
perf(amazon): optimize target group loading for /loadBalancers (#2610)
Browse files Browse the repository at this point in the history
  • Loading branch information
anotherchrisberry authored May 8, 2018
1 parent 29c78d9 commit 917c8d2
Show file tree
Hide file tree
Showing 8 changed files with 43 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ class Keys implements KeyParser {
break
case Namespace.TARGET_GROUPS.ns:
def names = Names.parseName(parts[4])
String vpcId = parts.length > 5 ? (parts[5] ?: null) : null
result << [account: parts[2], region: parts[3], targetGroup: parts[4], vpcId: vpcId, application: names.app?.toLowerCase(), stack: names.stack, detail: names.detail]
String vpcId = parts.length > 6 ? (parts[6] ?: null) : null
result << [account: parts[2], region: parts[3], targetGroup: parts[4], vpcId: vpcId, application: names.app?.toLowerCase(), stack: names.stack, detail: names.detail, targetType: parts[5]]
break
case Namespace.CLUSTERS.ns:
def names = Names.parseName(parts[4])
Expand Down Expand Up @@ -170,8 +170,8 @@ class Keys implements KeyParser {
return key
}

static String getTargetGroupKey(String targetGroupName, String account, String region, String vpcId) {
"${ID}:${Namespace.TARGET_GROUPS}:${account}:${region}:${targetGroupName}:${vpcId}"
static String getTargetGroupKey(String targetGroupName, String account, String region, String targetGroupType, String vpcId) {
"${ID}:${Namespace.TARGET_GROUPS}:${account}:${region}:${targetGroupName}:${targetGroupType}:${vpcId}"
}

static String getClusterKey(String clusterName, String application, String account) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,6 @@ class AmazonApplicationLoadBalancerCachingAgent extends AbstractAmazonLoadBalanc

Long start = useEdda ? null : System.currentTimeMillis()


// Get all the load balancers
List<LoadBalancer> allLoadBalancers = []
DescribeLoadBalancersRequest describeLoadBalancerRequest = new DescribeLoadBalancersRequest()
Expand Down Expand Up @@ -378,6 +377,10 @@ class AmazonApplicationLoadBalancerCachingAgent extends AbstractAmazonLoadBalanc
Map<String, CacheData> loadBalancers = CacheHelpers.cache()
Map<String, CacheData> targetGroups = CacheHelpers.cache()

Map<String, String> targetGroupNameToType = allTargetGroups.collectEntries {
[(it.targetGroupName): it.targetType]
}

for (LoadBalancer lb : allLoadBalancers) {
String loadBalancerKey = Keys.getLoadBalancerKey(lb.loadBalancerName, account.name, region, lb.vpcId, lb.type)

Expand Down Expand Up @@ -423,8 +426,9 @@ class AmazonApplicationLoadBalancerCachingAgent extends AbstractAmazonLoadBalanc
String targetGroupName = ArnUtils.extractTargetGroupName(action.targetGroupArn as String).get()
action.targetGroupName = targetGroupName
action.remove("targetGroupArn")
String type = targetGroupNameToType.get(targetGroupName)

allTargetGroupKeys.add(Keys.getTargetGroupKey(targetGroupName, account.name, region, vpcId))
allTargetGroupKeys.add(Keys.getTargetGroupKey(targetGroupName, account.name, region, type, vpcId))
}

// add the rules to the listener
Expand All @@ -439,8 +443,9 @@ class AmazonApplicationLoadBalancerCachingAgent extends AbstractAmazonLoadBalanc
String targetGroupName = ArnUtils.extractTargetGroupName(action.targetGroupArn).get()
action.targetGroupName = targetGroupName
action.remove("targetGroupArn")
String type = targetGroupNameToType.get(targetGroupName)

allTargetGroupKeys.add(Keys.getTargetGroupKey(targetGroupName, account.name, region, vpcId))
allTargetGroupKeys.add(Keys.getTargetGroupKey(targetGroupName, account.name, region, type, vpcId))
}

rules.push(ruleAttributes)
Expand All @@ -461,7 +466,7 @@ class AmazonApplicationLoadBalancerCachingAgent extends AbstractAmazonLoadBalanc

List<InstanceTargetGroupState> instanceTargetGroupStates = []
for (TargetGroup targetGroup : allTargetGroups) {
String targetGroupId = Keys.getTargetGroupKey(targetGroup.targetGroupName, account.name, region, targetGroup.vpcId)
String targetGroupId = Keys.getTargetGroupKey(targetGroup.targetGroupName, account.name, region, targetGroup.targetType, targetGroup.vpcId)
// Get associated load balancer keys
Collection<String> loadBalancerIds = targetGroup.loadBalancerArns.collect {
String lbName = ArnUtils.extractLoadBalancerName(it).get()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import com.amazonaws.services.cloudwatch.model.MetricAlarm
import com.amazonaws.services.ec2.AmazonEC2
import com.amazonaws.services.ec2.model.DescribeSubnetsRequest
import com.amazonaws.services.ec2.model.Subnet
import com.amazonaws.services.elasticloadbalancingv2.model.TargetTypeEnum
import com.fasterxml.jackson.annotation.JsonCreator
import com.fasterxml.jackson.annotation.JsonProperty
import com.fasterxml.jackson.core.type.TypeReference
Expand Down Expand Up @@ -723,7 +724,7 @@ class ClusterCachingAgent implements CachingAgent, OnDemandAgent, AccountAware,
} as Set).asImmutable()

targetGroupKeys = (targetGroupNames.collect {
Keys.getTargetGroupKey(it, account, region, vpcId)
Keys.getTargetGroupKey(it, account, region, TargetTypeEnum.Instance.toString(), vpcId)
} as Set).asImmutable()

instanceIds = (asg.instances.instanceId.collect { Keys.getInstanceKey(it, account, region) } as Set).asImmutable()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,15 @@ class AmazonLoadBalancerProvider implements LoadBalancerProvider<AmazonLoadBalan
List<AmazonLoadBalancerSummary> list() {
def searchKey = Keys.getLoadBalancerKey('*', '*', '*', null, null) + '*'
Collection<String> identifiers = cacheView.filterIdentifiers(LOAD_BALANCERS.ns, searchKey)
getSummaryForLoadBalancers(identifiers).values() as List
Map<String, Map<String, String>> targetGroupKeys = cacheView.getIdentifiers(TARGET_GROUPS.ns).collectEntries {
Map<String, String> parts = Keys.parse(it)
Map<String, String> summary = [
name: parts.targetGroup,
targetType: parts.targetType
]
return [(it): summary]
}
getSummaryForLoadBalancers(identifiers, targetGroupKeys).values() as List
}

AmazonLoadBalancerSummary get(String name) {
Expand All @@ -283,7 +291,7 @@ class AmazonLoadBalancerProvider implements LoadBalancerProvider<AmazonLoadBalan
def key = Keys.parse(it)
key.loadBalancer == name
}
getSummaryForLoadBalancers(identifiers).get(name)
getSummaryForLoadBalancers(identifiers, null).get(name)
}

List<Map> byAccountAndRegionAndName(String account,
Expand All @@ -309,11 +317,18 @@ class AmazonLoadBalancerProvider implements LoadBalancerProvider<AmazonLoadBalan
}
}

private Map<String, AmazonLoadBalancerSummary> getSummaryForLoadBalancers(Collection<String> loadBalancerKeys) {
private Map<String, Map<String, String>> getTargetGroupSummariesForLoadBalancer(Collection<CacheData> loadBalancerData) {
Collection<CacheData> targetGroupData = resolveRelationshipDataForCollection(loadBalancerData, TARGET_GROUPS.ns)
return targetGroupData.collectEntries {
[(it.id): [ name: it.attributes.targetGroupName, targetType: it.attributes.targetType ]]
}
}

private Map<String, AmazonLoadBalancerSummary> getSummaryForLoadBalancers(Collection<String> loadBalancerKeys, Map<String, Map<String, String>> targetGroupMap) {
Map<String, AmazonLoadBalancerSummary> map = [:]
Collection<CacheData> loadBalancerData = cacheView.getAll(LOAD_BALANCERS.ns, loadBalancerKeys, RelationshipCacheFilter.include(TARGET_GROUPS.ns))
Map<String, CacheData> loadBalancers = loadBalancerData.collectEntries { [(it.id): it] }
Map<String, CacheData> targetGroups = resolveRelationshipDataForCollection(loadBalancerData, TARGET_GROUPS.ns).collectEntries { [(it.id): it] }
targetGroupMap = targetGroupMap ?: getTargetGroupSummariesForLoadBalancer(loadBalancerData)

for (lb in loadBalancerKeys) {
CacheData loadBalancerFromCache = loadBalancers[lb]
Expand Down Expand Up @@ -345,15 +360,7 @@ class AmazonLoadBalancerProvider implements LoadBalancerProvider<AmazonLoadBalan
// provider type.
if (loadBalancerFromCache.relationships[TARGET_GROUPS.ns]) {
loadBalancer.targetGroups = loadBalancerFromCache.relationships[TARGET_GROUPS.ns].findResults {
def targetGroup = targetGroups[it]
if (!targetGroup) {
return null
}

return [
name: targetGroup.attributes.targetGroupName,
targetType: targetGroup.attributes.targetType
]
targetGroupMap[it]
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public EcsTargetGroupCacheClient(Cache cacheView, ObjectMapper objectMapper) {
}

public List<EcsTargetGroup> findAll() {
String searchKey = Keys.getTargetGroupKey("*", "*", "*", "*") + "*";
String searchKey = Keys.getTargetGroupKey("*", "*", "*", "*", "*") + "*";
Collection<String> targetGroupKeys = cacheView.filterIdentifiers(TARGET_GROUPS.getNs(), searchKey);

Set<Map<String, Object>> targetGroupAttributes = fetchLoadBalancerAttributes(targetGroupKeys);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.netflix.spinnaker.clouddriver.ecs.cache

import com.amazonaws.services.elasticloadbalancingv2.model.TargetTypeEnum
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.ObjectMapper
import com.netflix.spinnaker.cats.cache.Cache
Expand Down Expand Up @@ -45,7 +46,7 @@ class EcsLoadbalancerCacheClientSpec extends Specification {
def targetGroupName = 'test-target-group'

def loadbalancerKey = Keys.getLoadBalancerKey(loadBalancerName, account, region, vpcId, loadBalancerType)
def targetGroupKey = Keys.getTargetGroupKey(targetGroupName, account, region, vpcId)
def targetGroupKey = Keys.getTargetGroupKey(targetGroupName, account, region, TargetTypeEnum.Instance.toString(), vpcId)

def givenEcsLoadbalancer = new EcsLoadBalancerCache(
account: account,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.netflix.spinnaker.clouddriver.ecs.cache

import com.amazonaws.services.elasticloadbalancingv2.model.TargetTypeEnum
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.ObjectMapper
import com.netflix.spinnaker.cats.cache.Cache
Expand Down Expand Up @@ -44,7 +45,7 @@ class EcsTargetGroupCacheClientSpec extends Specification {
def targetGroupName = 'test-target-group'

def loadbalancerKey = Keys.getLoadBalancerKey(loadBalancerName, account, region, vpcId, loadBalancerType)
def targetGroupKey = Keys.getTargetGroupKey(targetGroupName, account, region, vpcId)
def targetGroupKey = Keys.getTargetGroupKey(targetGroupName, account, region, TargetTypeEnum.Instance.toString(), vpcId)

def givenEcsTargetGroup = new EcsTargetGroup(
loadBalancerNames: [loadBalancerName],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.netflix.spinnaker.clouddriver.titus.caching.agents

import com.amazonaws.services.elasticloadbalancingv2.model.TargetTypeEnum
import com.fasterxml.jackson.annotation.JsonCreator
import com.fasterxml.jackson.annotation.JsonProperty
import com.fasterxml.jackson.databind.ObjectMapper
Expand All @@ -32,6 +33,7 @@ import com.netflix.spinnaker.cats.cache.DefaultCacheData
import com.netflix.spinnaker.cats.cache.RelationshipCacheFilter
import com.netflix.spinnaker.cats.provider.ProviderCache
import com.netflix.spinnaker.clouddriver.aws.data.ArnUtils
import com.netflix.spinnaker.clouddriver.aws.data.Keys as AwsKeys
import com.netflix.spinnaker.clouddriver.cache.CustomScheduledAgent
import com.netflix.spinnaker.clouddriver.cache.OnDemandAgent
import com.netflix.spinnaker.clouddriver.cache.OnDemandMetricsSupport
Expand Down Expand Up @@ -480,7 +482,7 @@ class TitusClusterCachingAgent implements CachingAgent, CustomScheduledAgent, On
} as Set).asImmutable()

targetGroupKeys = (targetGroupNames.collect {
com.netflix.spinnaker.clouddriver.aws.data.Keys.getTargetGroupKey(it, getAwsAccountId(account, region), region, getAwsVpcId(account, region))
AwsKeys.getTargetGroupKey(it, getAwsAccountId(account, region), region, TargetTypeEnum.Ip.toString(), getAwsVpcId(account, region))
} as Set).asImmutable()

}
Expand Down

0 comments on commit 917c8d2

Please sign in to comment.