Quellcode durchsuchen

Merge branch '20260526_feature_fjy_add_v' of algorithm/ad-engine into master

fanjinyang vor 1 Tag
Ursprung
Commit
112634752f

+ 85 - 0
ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/helper/CreativeKFinalDataHelper.java

@@ -0,0 +1,85 @@
+package com.tzld.piaoquan.ad.engine.commons.helper;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+import java.text.SimpleDateFormat;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+@Slf4j
+@Component
+public class CreativeKFinalDataHelper {
+
+    @Resource(name = "newAdRedisTemplate")
+    private RedisTemplate<String, String> newAdRedisTemplate;
+
+    private static final String CREATIVE_CODE_SET_KEY_FORMAT = "ad:addv:cost:current:creative:code:%s";
+    private static final String CREATIVE_K_KEY_FORMAT = "ad:addv:cost:k:%s";
+
+    private volatile static Map<String, Double> creativeKFinalMap = Collections.emptyMap();
+
+    // 服务启动时初始化数据
+    @PostConstruct
+    public void init() {
+        Map<String, Double> map = updateCreativeKFinalMap();
+        creativeKFinalMap = Collections.unmodifiableMap(map);
+    }
+
+    // 每1分钟更新一次数据
+    @Scheduled(fixedRate = 60 * 1000)
+    public void scheduledUpdate() {
+        Map<String, Double> map = updateCreativeKFinalMap();
+        creativeKFinalMap = Collections.unmodifiableMap(map);
+    }
+
+    public static Double getKFinal(String creativeCode) {
+        if (creativeCode != null && creativeKFinalMap != null) {
+            return creativeKFinalMap.get(creativeCode);
+        }
+        return null;
+    }
+
+    private Map<String, Double> updateCreativeKFinalMap() {
+        Map<String, Double> tmpMap = new HashMap<>();
+        try {
+            String today = new SimpleDateFormat("yyyyMMdd").format(new Date());
+            String setKey = String.format(CREATIVE_CODE_SET_KEY_FORMAT, today);
+            Set<String> creativeCodes = newAdRedisTemplate.opsForSet().members(setKey);
+            if (CollectionUtils.isEmpty(creativeCodes)) {
+                log.info("creative kFinal: code set is empty for date={}", today);
+                return tmpMap;
+            }
+            for (String creativeCode : creativeCodes) {
+                try {
+                    String kKey = String.format(CREATIVE_K_KEY_FORMAT, creativeCode);
+                    String value = newAdRedisTemplate.opsForValue().get(kKey);
+                    if (StringUtils.isNotBlank(value)) {
+                        JSONObject jsonObject = JSON.parseObject(value);
+                        Double kFinal = jsonObject.getDouble("kFinal");
+                        if (kFinal != null) {
+                            tmpMap.put(creativeCode, kFinal);
+                        }
+                    }
+                } catch (Exception e) {
+                    log.error("update creative kFinal error creativeCode={}", creativeCode, e);
+                }
+            }
+            log.info("update creative kFinal map success size={}", tmpMap.size());
+        } catch (Exception e) {
+            log.error("update creative kFinal map error", e);
+        }
+        return tmpMap;
+    }
+}

+ 20 - 0
ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/redis/RedisTemplateConfig.java

@@ -68,6 +68,26 @@ public class RedisTemplateConfig {
         return new LettuceConnectionFactory(adRedisConfig, lettuceClientConfiguration);
     }
 
+
+    @Bean
+    @ConfigurationProperties(prefix = "spring.redis-ad-cache")
+    public RedisStandaloneConfiguration newAdRedisConfig() {
+        return new RedisStandaloneConfiguration();
+    }
+
+    @Bean("newAdRedisFactory")
+    public LettuceConnectionFactory newAdRedisFactory(GenericObjectPoolConfig<LettucePoolingClientConfiguration> config,@Qualifier("newAdRedisConfig") RedisStandaloneConfiguration adRedisConfig) {
+        LettuceClientConfiguration lettuceClientConfiguration = LettucePoolingClientConfiguration.builder().poolConfig(config).build();
+        return new LettuceConnectionFactory(adRedisConfig, lettuceClientConfiguration);
+    }
+
+    @Bean(name = "newAdRedisTemplate")
+    public RedisTemplate<String, String> newAdRedisTemplate(@Qualifier("newAdRedisFactory") RedisConnectionFactory adRedisFactory) {
+        return buildRedisTemplateByString(adRedisFactory);
+    }
+
+
+
     /**
      * 构建redisTemplate 使用string序列化
      *

+ 12 - 0
ad-engine-server/src/main/resources/application-dev.yml

@@ -46,6 +46,18 @@ spring:
         max-active: 1000 # 连接池最大连接数(使用负值表示没有限制) 默认 8
         max-idle: 20 # 连接池中的最大空闲连接 默认 8
         min-idle: 10 # 连接池中的最小空闲连接 默认 0
+
+  redis-ad-cache:
+    hostName: r-bp1ps6my7lzg8rdhwx682.redis.rds.aliyuncs.com
+    port: 6379
+    password: Wqsd@2019
+    timeout: 1000
+    lettuce:
+      pool:
+        max-active: 1000 # 连接池最大连接数(使用负值表示没有限制) 默认 8
+        max-idle: 20 # 连接池中的最大空闲连接 默认 8
+        min-idle: 10 # 连接池中的最小空闲连接 默认 0
+
   redis-algorithm:
     hostName: r-bp1ps6my7lzg8rdhwx682.redis.rds.aliyuncs.com
     port: 6379

+ 12 - 0
ad-engine-server/src/main/resources/application-pre.yml

@@ -45,6 +45,18 @@ spring:
         max-active: 50 # 连接池最大连接数(使用负值表示没有限制) 默认 8
         max-idle: 20 # 连接池中的最大空闲连接 默认 8
         min-idle: 10 # 连接池中的最小空闲连接 默认 0`
+
+  redis-ad-cache:
+    hostName: r-bp1wxi22yugkp044xa.redis.rds.aliyuncs.com
+    port: 6379
+    password: Wqsd@2019
+    timeout: 1000
+    lettuce:
+      pool:
+        max-active: 1000 # 连接池最大连接数(使用负值表示没有限制) 默认 8
+        max-idle: 20 # 连接池中的最大空闲连接 默认 8
+        min-idle: 10 # 连接池中的最小空闲连接 默认 0
+
   redis-algorithm:
     hostName: r-bp1fogs2mflr1ybfot.redis.rds.aliyuncs.com
     port: 6379

+ 12 - 0
ad-engine-server/src/main/resources/application-prod.yml

@@ -46,6 +46,18 @@ spring:
         max-active: 1000 # 连接池最大连接数(使用负值表示没有限制) 默认 8
         max-idle: 20 # 连接池中的最大空闲连接 默认 8
         min-idle: 10 # 连接池中的最小空闲连接 默认 0
+
+  redis-ad-cache:
+    hostName: r-bp1wxi22yugkp044xa.redis.rds.aliyuncs.com
+    port: 6379
+    password: Wqsd@2019
+    timeout: 1000
+    lettuce:
+      pool:
+        max-active: 1000 # 连接池最大连接数(使用负值表示没有限制) 默认 8
+        max-idle: 20 # 连接池中的最大空闲连接 默认 8
+        min-idle: 10 # 连接池中的最小空闲连接 默认 0
+
   redis-algorithm:
     hostName: r-bp1fogs2mflr1ybfot.redis.rds.aliyuncs.com
     port: 6379

+ 9 - 0
ad-engine-server/src/main/resources/application-test.yml

@@ -40,6 +40,15 @@ spring:
     port: 6379
     password: Wqsd@2019
     timeout: 1000
+
+  redis-ad-cache:
+    hostName: r-bp1ps6my7lzg8rdhwx682.redis.rds.aliyuncs.com
+    port: 6379
+    password: Wqsd@2019
+    timeout: 1000
+
+
+
   redis-algorithm:
     hostName: r-bp1ps6my7lzg8rdhwx682.redis.rds.aliyuncs.com
 #    hostName: r-bp1fogs2mflr1ybfot.redis.rds.aliyuncs.com

+ 18 - 0
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/strategy/RankStrategyBasic.java

@@ -7,6 +7,7 @@ import com.tzld.piaoquan.ad.engine.commons.dto.AdPlatformCreativeDTO;
 import com.tzld.piaoquan.ad.engine.commons.enums.CrowdLayerEnum;
 import com.tzld.piaoquan.ad.engine.commons.enums.FilterTypeEnum;
 import com.tzld.piaoquan.ad.engine.commons.enums.RedisPrefixEnum;
+import com.tzld.piaoquan.ad.engine.commons.helper.CreativeKFinalDataHelper;
 import com.tzld.piaoquan.ad.engine.commons.helper.LayerAgentFlowControlDataHelper;
 import com.tzld.piaoquan.ad.engine.commons.helper.LayerCustomerFlowControlDataHelper;
 import com.tzld.piaoquan.ad.engine.commons.param.RankRecommendRequestParam;
@@ -1385,6 +1386,8 @@ public abstract class RankStrategyBasic implements RankStrategy {
                     }
                 }
             }
+
+            calCreativeKFinalWeight("kFinal",items);
         } catch (Exception e) {
             log.error("cal rerank weight error", e);
         }
@@ -1435,6 +1438,21 @@ public abstract class RankStrategyBasic implements RankStrategy {
         }
     }
 
+
+    // 加V打压系数
+    protected void calCreativeKFinalWeight(String flowCtlType, List<AdRankItem> items) {
+        try {
+            for (AdRankItem item : items) {
+                Double kFinal = CreativeKFinalDataHelper.getKFinal(item.getCreativeCode());
+                if(kFinal != null){
+                    item.getScoreMap().put(flowCtlType, kFinal);
+                }
+            }
+        } catch (Exception e) {
+            log.error("calCreativeKFinalWeight weight error", e);
+        }
+    }
+
     private double getFlowControlWeight(Pair<Double, Double> pair,
                                         double cpmPow, double lowerCpmWeight, double upperCpmWeight,
                                         double flowPow, double lowerFlowWeight, double upperFlowWeight,

+ 2 - 1
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/strategy/RankStrategyBy851.java

@@ -413,13 +413,14 @@ public class RankStrategyBy851 extends RankStrategyBasic {
             // 控制流量权重
             double flowCtlC = item.getScoreMap().getOrDefault("flowCtlC", 1.0);
             double flowCtlA = item.getScoreMap().getOrDefault("flowCtlA", 1.0);
+            double kFinal = item.getScoreMap().getOrDefault("kFinal", 1.0);
 
             String layerAndCreativeWeightMapKey = getLayerAndCreativeWeightMapKey(peopleLayer, String.valueOf(item.getAdId()));
             // 人群分层&创意的权重
             double layerAndCreativeWeight = getLayerAndCreativeWeight(layerAndCreativeWeightMapKey);
             double scoreCoefficient = creativeScoreCoefficient.getOrDefault(item.getAdId(), 1d);
             double guaranteeScoreCoefficient = getGuaranteeScoreCoefficient(isGuaranteedFlow, item.getExt());
-            double score = flowCtlC * flowCtlA * h5Weight * expWeight * item.getLrScore() * bid * scoreCoefficient * guaranteeScoreCoefficient * layerAndCreativeWeight;
+            double score = flowCtlC * flowCtlA * h5Weight * expWeight * item.getLrScore() * bid * scoreCoefficient * guaranteeScoreCoefficient * layerAndCreativeWeight * kFinal;
             item.getScoreMap().put("guaranteeScoreCoefficient", guaranteeScoreCoefficient);
             item.getScoreMap().put("cpa", item.getCpa());
             item.getScoreMap().put("cpm", item.getCpm());