URL去重怎么办,六种方法帮你搞定

URL去重的六种方法

去重思路

​ 在不考虑业务场景和数据量的情况下,我们可以使用以下的方案来实现URL的重复判断

  • 使用java的Set集合,根据添加时的结果来判断url是否重复(添加成功表示URL不重复)
  • 使用Redis中的Set集合,根据添加时的结果来判断URL是否重复
  • 把数据库中的URL设置为唯一索引,根据添加时的结果来判断URL是否重复
  • 使用Guava的布隆过滤器来实现URL判重
  • 使用Redis的布隆过滤器来实现URL判重

​ 接下来我们就分别分析下这六种判重的方法。

一、使用Java中Set集合

​ 由于Set集合具有不可重复性,因此我们可以通过添加Set集合时的结果来盘点URL是否重复

public class URLRepeat {
    
    
    // 待去重 URL
    public static final String[] URLS = {
    
    
            "https://blog.csdn.net/issunmingzhi",
            "www.baidu.com",
            "https://blog.csdn.net/issunmingzhi"
    };
    public static void main(String[] args) {
    
    
        Set<String> set = new HashSet();
        for (int i = 0; i < URLS.length; i++) {
    
    
            String url = URLS[i];
            boolean result = set.add(url);
            if (!result) {
    
    
                // 重复的 URL
                System.out.println("URL 已存在了:" + url);
            }
        }
    }
}

二、Redis Set 集合去重

​ 思路和第一种基本一致,利用Set的不可重复性

// 待去重 URL
public static final String[] URLS = {
    
                
    "https://blog.csdn.net/issunmingzhi",        
    "www.baidu.com",
    "https://blog.csdn.net/issunmingzhi"
};

@Autowired
RedisTemplate redisTemplate;

@RequestMapping("/url")
public void urlRepeat() {
    
    
    for (int i = 0; i < URLS.length; i++) {
    
    
        String url = URLS[i];
        Long result = redisTemplate.opsForSet().add("urlrepeat", url);
        if (result == 0) {
    
    
            // 重复的 URL
            System.out.println("URL 已存在了:" + url);
        }
    }
}

以上代码中我们借助了Spring Data中的RedisTemplate实现,所以在Spring Boot项目中要引入spring-boot-starter-data-redis 框架,配置信息如下:

<!-- 添加操作 RedisTemplate 引用 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

然后再配置Redis的连接信息:

spring.redis.host=127.0.0.1
spring.redis.port=6379
#spring.redis.password=123456 # Redis 服务器密码,有密码的话需要配置此项

三、唯一索引去重

​ 建表的时候创建唯一索引

四、Guava布隆过滤器去重

​ 布隆过滤器,实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。

​ 我们可以借助Guava框架来操作布隆过滤器,首先先在pom.xml中添加Guava的引用

<!-- 添加 Guava 框架 -->
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>28.2-jre</version>
</dependency>

URL判重代码

public class URLRepeat {
    
    
    // 待去重 URL
    public static final String[] URLS = {
    
    
            "https://blog.csdn.net/issunmingzhi",
            "www.baidu.com",
            "https://blog.csdn.net/issunmingzhi"
    };
    public static void main(String[] args) {
    
    
        // 创建一个布隆过滤器
        BloomFilter<String> filter = BloomFilter.create(
                Funnels.stringFunnel(Charset.defaultCharset()),
                10, // 期望处理的元素数量
                0.01); // 期望的误报概率
        for (int i = 0; i < URLS.length; i++) {
    
    
            String url = URLS[i];
            if (filter.mightContain(url)) {
    
    
                // 用重复的 URL
                System.out.println("URL 已存在了:" + url);
            } else {
    
    
                // 将 URL 存储在布隆过滤器中
                filter.put(url);
            }
        }
    }
}

五、Redis布隆过滤器

​ 除了 Guava 的布隆过滤器,我们还可以使用 Redis 的布隆过滤器来实现 URL 判重。在使用之前,我们先要确保 Redis 服务器版本大于 4.0(此版本以上才支持布隆过滤器),并且开启了 Redis 布隆过滤器功能才能正常使用。

​ Redis中,布隆过滤器的操作不多,主要包含以下几个:

  • bf.add:添加元素
  • bf.exists:判断某个元素是否存在
  • bf.madd:添加多个元素
  • bf.mexists:判断多个元素是否存在
  • bf.reserve:设置布隆过滤器的准确率

猜你喜欢

转载自blog.csdn.net/issunmingzhi/article/details/108769860