【工作日常】推荐策略V3 优化
由于原有逻辑中有个很大的问题,就是是在内存中使用洗牌算法对list进行排序,数据量少的情况可以这么处理,当数据量大的时候就会造成很大的消耗,一方面是 数据库io 读写会多,会查询大量的数据 ,一方面jvm堆内存也会占用很多。所以进行整体的优化。之前的逻辑如下:
整体优化如下:
-
用户池数据存储 : Mysql 数据表 -> Es 索引,字段区分日期数据 -> 索引名称区分日期数据 user_pool_20201112
-
数据筛选:数据库条件筛选 , 内存洗牌 -> Es 筛选,随机搜索
-
数据过滤:sql 条件过滤 -> 内存查询数据 ,内存过滤数据
-
数据补充:sql 连表查询 -> 内存list分组,多线程并发查询(futureTask),转为Map,循环getMap
//切割list,分成10批
ExecutorService executorService = Executors.newFixedThreadPool(10);
List<Future<Map<String, Integer>>> futureTaskList = new ArrayList<>();
Map<String, Integer> chatStatusType = new HashMap<>();
try {
List<List<UserPoolEsDTO>> partition = Lists.partition(list, 10);
for (List<UserPoolEsDTO> userPoolEsDTOS : partition) {
Future<Map<String, Integer>> submit = executorService.submit(() -> {
Example example = new Example(DatingImSession.class);
List<String> toIds = userPoolEsDTOS.stream().map(item -> item.userId).collect(Collectors.toList());
example.createCriteria().andEqualTo("fromId", userId).andIn("toId", toIds);
List<DatingImSession> datingImSessions = datingImSessionMapper.selectByExample(example);
// 转成 key userId , value chatStatus 的 map
// LOGGER.info("查询数据");
return datingImSessions.stream()
.collect(Collectors.toMap(DatingImSession::getToId, item -> Integer.valueOf(item.getType())));
});
futureTaskList.add(submit);
}
for (Future<Map<String, Integer>> mapFuture : futureTaskList) {
Map<String, Integer> stringObjectMap = mapFuture.get();
chatStatusType.putAll(stringObjectMap);
}
return chatStatusType;

浙公网安备 33010602011771号