V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
phpfpm
V2EX  ›  问与答

百万级图像抓取去重存档技术方案

  •  
  •   phpfpm · 2020-04-29 10:53:47 +08:00 · 1363 次点击
    这是一个创建于 1452 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前情提要:

    https://www.v2ex.com/t/665885

    特别提醒,本文讨论的不是两张图片如何判断内容是否相似

    实现的目标

    抓取某论坛发布的主题和图片,根据图片特征判重标记。

    硬件

    云主机

    阿里云(2c2g)服务器一台:某些服务的管理的公网出口(rabbitmq, 路由器管理等),基本不使用

    阿里云 hk:proxy 出口

    vultr sg:proxy 出口

    物理机

    db: i5-5200u/8g/hdd: mysql, rabbitmq

    web:i5-4200u/8g/ssd: nginx/php/redis

    nas:N3150/16g/hdd*n: samba

    主要流程

    列表页-详情页-图片 item:触发抓取

    抓取:触发存储, 计算 md5 判重, 计算图片内容 hash

    存储-校验-标记完成

    计算 md5 判重-存储判重结果

    计算图片内容 hash-redis 建立索引-查找 hash 重复-计算内容判重-存储判重结果

    如何高效检索内容 hash 相近的图片

    算了一些 hash,考虑汉明距离<=3 以内的作为 hash 接近的图片。
    
    对于 128bit 的 hash,分为 4 组,如果汉明距离<=3, 至少有一组是完全一致的。
    
    因此,将图片的内容 hash 分为四段存入 redis,建立倒排索引。
    
    比如 id=123,hash=aaaabbbbccccdddd, 算法是 average,
    存储这么几个数据到 redis:
    sadd average:part1:aaaa => 123
    sadd average:part1:bbbb => 123
    sadd average:part1:cccc => 123
    sadd average:part1:dddd => 123
    
    这样下次搜索比如 aaaa000011112222 的判重的时候,就会命中
    average:part1:aaaa 这个集合,从中取出 id 搜索对应的 hash 继续判重。
    
    1M 量级的数据,四种 hash 算法,每种算法会分为 64k 个组,平均每个组 16 个 hash
    那么对于一个新的图片需要判重 4 种 * 4 个分片 * 16 = 256 个 hash 比对
    结合 redis 的读取时间,能压缩到几秒钟以内了。
    存量数据花了三四天清洗完了,增量准实时。
    
    

    剩下的结合索引优化等,继续提升效率。

    7 条回复    2020-05-03 23:30:37 +08:00
    wysnylc
        1
    wysnylc  
       2020-04-29 11:35:11 +08:00
    还是折腾 hash
    rrfeng
        2
    rrfeng  
       2020-04-29 13:51:42 +08:00
    请问『内容 hash 相近』有什么意义?
    fancy111
        3
    fancy111  
       2020-04-29 13:54:06 +08:00
    hash 相近==图片相近???
    你不如搞图像识别去重,还说得过去一点。
    imn1
        4
    imn1  
       2020-04-29 14:08:12 +08:00
    @rrfeng
    @fancy111
    LZ 说的“内容 hash”是 image hash 的简称,就是图像识别,不是传统意义的字节哈希,看他的上一帖
    rrfeng
        5
    rrfeng  
       2020-04-29 14:27:43 +08:00
    还是简单提一下好……用『图像指纹』代替 hash 就不会歧义了。

    所以本质上就是 100w * 128bit 的记录如何快速查汉明距离最短,分组是个简单有效的方法,但感觉应该有更好的算法。
    phpfpm
        6
    phpfpm  
    OP
       2020-04-29 14:34:00 +08:00
    @rrfeng 按照我现在的硬件这个查询效率我觉得差不多了,换一台好的服务器还能提高不少效率。
    更好的算法也得基于更好的硬件,比如显卡加入什么的,愿闻其详
    loadingimg
        7
    loadingimg  
       2020-05-03 23:30:37 +08:00
    dhash 去重效果不错
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2850 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 06:18 · PVG 14:18 · LAX 23:18 · JFK 02:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.