记一次关于查重逻辑的优化及流程、效果

作者: admin 分类: 应用技巧 发布时间: 2020-12-14 15:32  阅读: 662 views

背景

1000多个老师整理试题,分不同学科。估计初始阶段题量有10w左右。通过word形式导入到程序系统中。

但是,在制作试题的过程中,可能会出现重复的情况,造成其他影响。所以,需要做一个查重功能解决这个问题。

方案

首先‘查重’要考虑效果、效率的问题。

  • 效果:
    不是简单的字符串匹配,这个效果有点不好。采用了SimHash算法。通过去噪、去杂、分词、hash等过程,达到一个比较理想的对比效果。

  • 效率:
    题量少的时候,查询效率正常。当达到十万、百万级时,可能就会有效率问题。所以要加缓存或者MongoDB/ ES之类的,加快查询效率。最后采用最小堆算法处理最相近的5道题

处理逻辑

SimHash处理相关资料

效率处理逻辑

效率测试效果

下列是存到NoSql数据库中的数据结构,id为题号,hash为SimHash。循环比较当前题和哪些题最相近。

{   
    "subjectId":1,
    "crList":"[
        {\"id\":5984840,\"hash\":8065260974767954229},
        {\"id\":5989000,\"hash\":10746764603123134457},
        {\"id\":5989007,\"hash\":10746764603123134457},
        {\"id\":5990047,\"hash\":8065260974767954229}
    ]"
}

注:这个json数据有个优化点,可以将id、hash替换为 k、v 减少存储的数据量。
10w条数据可以减少 100000 * 4 个存储空间。

本来刚开始是使用Redis进行存储的。针对于每个subjectId分A、B两块Redis缓存。A是某刻全量数据,B是最近500条新增、修改的数据。按照一定的规则\时间将B合并到A。防止A的频繁修改。

预估每个redis对象小于40MB,但是运维的要求是redis对象不能超过200KB。所以,就不能用redis了。换到了MongoDB。

MongoDB本地测试 (单条Document最大值只能存16MB)

单个知识点的数据(题+hash存储)

数据量 MongDB单文档大小 删除时间 插入时间 读取时间 hash比较处理
400,000 15.5MB 1s 14s 8s 1~2s
200,000 7.7MB 1s内 7s 1s 1~2s
10,000 0.38MB 14 448 65 97

估计50,000,000个数据 占用小于 2个G。

再优化

  • 增加caffeine本地缓存。
  • 参数配置提取(
    • 本地缓存时间
    • SimHash规则(去除html、去除无效词[的、得、地等]、相似阈值等)
    • 全量数据更新规则
      )

后续

根据线上的使用情况,在进行后续调整


   原创文章,转载请标明本文链接: 记一次关于查重逻辑的优化及流程、效果

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

发表评论

电子邮件地址不会被公开。 必填项已用*标注