|
@@ -0,0 +1,91 @@
|
|
|
|
+package com.atguigu.tingshu.album.task;
|
|
|
|
+
|
|
|
|
+import cn.hutool.core.collection.CollUtil;
|
|
|
|
+import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
|
|
|
|
+import com.atguigu.tingshu.common.constant.RedisConstant;
|
|
|
|
+import com.atguigu.tingshu.common.constant.SystemConstant;
|
|
|
|
+import com.atguigu.tingshu.model.album.AlbumInfo;
|
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
|
+import org.redisson.api.RBloomFilter;
|
|
|
|
+import org.redisson.api.RedissonClient;
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
+import org.springframework.scheduling.annotation.Scheduled;
|
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
|
+
|
|
|
|
+import java.util.List;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ * @author: atguigu
|
|
|
|
+ * @create: 2025-03-21 09:21
|
|
|
|
+ */
|
|
|
|
+@Slf4j
|
|
|
|
+@Component
|
|
|
|
+public class RebuildBloomFilterTask {
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private AlbumInfoMapper albumInfoMapper;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private RedissonClient redissonClient;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ * 重建布隆过滤器 TODO 后续改为xxl-job 定时+手动调度
|
|
|
|
+ * 周期:每月1号凌晨2点执行
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+ @Scheduled(cron = "0 0 2 1 * ?")
|
|
|
|
+ public void rebuildBloomFilter() {
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ RBloomFilter<Long> oldBloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER);
|
|
|
|
+ long expectedInsertions = oldBloomFilter.getExpectedInsertions();
|
|
|
|
+ long count = oldBloomFilter.count();
|
|
|
|
+ double falseProbability = oldBloomFilter.getFalseProbability();
|
|
|
|
+ log.info("[专辑服务]触发重建布隆过滤器任务:现有期望数据规模:{},现有实际数据量:{}", expectedInsertions, count);
|
|
|
|
+
|
|
|
|
+ if (count >= expectedInsertions) {
|
|
|
|
+ log.info("[专辑服务]布隆过滤器扩容");
|
|
|
|
+
|
|
|
|
+ RBloomFilter<Long> newBloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER + ":new");
|
|
|
|
+ newBloomFilter.tryInit(expectedInsertions * 2, falseProbability);
|
|
|
|
+
|
|
|
|
+ this.addDataToBloomFilter(newBloomFilter);
|
|
|
|
+
|
|
|
|
+ oldBloomFilter.delete();
|
|
|
|
+
|
|
|
|
+ newBloomFilter.rename(RedisConstant.ALBUM_BLOOM_FILTER);
|
|
|
|
+ } else {
|
|
|
|
+ log.info("[专辑服务]布隆过滤器重建");
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ oldBloomFilter.delete();
|
|
|
|
+ RBloomFilter<Long> newBloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER);
|
|
|
|
+ newBloomFilter.tryInit(expectedInsertions, falseProbability);
|
|
|
|
+
|
|
|
|
+ this.addDataToBloomFilter(newBloomFilter);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ * 将审核通过专辑ID加入到布隆过滤器
|
|
|
|
+ *
|
|
|
|
+ * @param bloomFilter
|
|
|
|
+ */
|
|
|
|
+ private void addDataToBloomFilter(RBloomFilter<Long> bloomFilter) {
|
|
|
|
+
|
|
|
|
+ List<AlbumInfo> albumInfoList = albumInfoMapper
|
|
|
|
+ .selectList(
|
|
|
|
+ new LambdaQueryWrapper<AlbumInfo>().eq(AlbumInfo::getStatus, SystemConstant.ALBUM_STATUS_PASS)
|
|
|
|
+ .select(AlbumInfo::getId)
|
|
|
|
+ );
|
|
|
|
+ if (CollUtil.isNotEmpty(albumInfoList)) {
|
|
|
|
+
|
|
|
|
+ albumInfoList
|
|
|
|
+ .stream()
|
|
|
|
+ .map(AlbumInfo::getId)
|
|
|
|
+ .forEach(bloomFilter::add);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|