V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
godloveplay
V2EX  ›  程序员

请问厂里面一物一码的二维码重复校验,一般怎么做?

  •  
  •   godloveplay · 247 天前 · 3570 次点击
    这是一个创建于 247 天前的主题,其中的信息可能已经有所发展或是发生改变。

    老板要做一个二维码去重的功能。我们厂生产的每个包装盒上都会喷上一个唯一的二维码,为了防止二维码重复,计划在流水线上加装摄像头进行数据采集。

    目前构想是这样的:每个托盘有 200 个盒子,二维码朝上采集一板货可能分 4 个区域采集。一次会有 50 个二维码上传到服务器进行校验,如果发现有重复的二维码,服务器会返回重复的二维码,然后设备会对重复的盒子定位并标记。

    每批货物有一个码包,每个码包有 50 万个二维码。如果考虑历史码包,数据量可能会更大。

    码包是客户用加密压缩文件给的,之前的系统是,收到条码之后导入 mysql 数据,用临时表校验重复,数据库用一段时间就变得贼大,要定时删历史数据。不用考虑剔除,所以对校验时长没有要求。

    我有两个问题想请教大家:

    1. 如果只对几个码包进行验重,千万数量级的二维码,使用 Redis 是否可行?
    2. 如果需要考虑历史码包进行验重,有没有什么好的方案?能保证验重接口的响应时间在 3 秒以内?
    第 1 条附言  ·  247 天前
    1. 二维码是客户提供,固定网址+末尾的变量 规则不知,码包的意思是一个大码段
    2. 有一个码管理系统,条码都会导入系统,然后通过系统生成 txt 文件 下发给喷码机。

    后续准备喷完码,开始制作前再过一遍机器,做一遍重复校验。防止变成成品后才发现重复(人为原因这个悲剧已经发生了,暂时加在末端)就是原帖里的方案。应该只用校验最近几个码报,不到千万的数量。

    条码生产前导入系统时,只对同一个工单使用的几个码报做了校验。
    如果要扩展到同款产品 1 年内的历史码包校验。数据量就会很大,想请教大家有什么去重思路/方案。
    第 2 条附言  ·  247 天前
    谢谢大家的帮助,祝大家身体健康,笑口常开。

    单个产品年度的条码数量将近亿数量,每次从客户处获取码包导入“条码系统” 时与一年内该产品的历史条码数据做比对校验重复。这块有什么好的实现方式呀?
    32 条回复    2024-03-12 23:32:58 +08:00
    xjpicism
        1
    xjpicism  
       247 天前
    布隆过滤器?
    aliyun2017
        2
    aliyun2017  
       247 天前
    对于第一个问题,使用 Redis 可行。Redis 是一个高性能的键值存储系统,可以用于缓存、数据结构存储和消息传递等多种场景。在你的情况下,可以使用 Redis 来存储已经验证过的二维码,通过对已存储的二维码进行对比来判断是否重复。Redis 的速度非常快,适合处理大量的数据。你可以将每个二维码作为键存储在 Redis 中,当需要进行校验时,通过查询 Redis 来判断二维码是否重复。这样可以有效地减少数据库的负载,提高验证的效率。

    对于第二个问题,如果需要考虑历史码包进行验重,并且要求响应时间在 3 秒以内,可以考虑使用分布式数据库和查询优化等技术来处理。以下是一种可能的方案:

    1 、使用分布式数据库,如 Apache HBase 、Cassandra 或 MongoDB ,来存储历史码包的数据。这些数据库可以水平扩展,具有良好的查询性能和高可用性,适合处理大规模数据。

    2 、对于历史码包的验重,可以将数据分片存储在不同的节点上,避免单一节点的负载过重。并采用合适的数据建模和索引设计,以提高查询的效率。

    3 、使用查询优化技术,如索引、分区、缓存等,来提高查询的性能。通过合理的查询计划和数据存储方式,可以减少查询的响应时间。

    4 、可以考虑使用异步处理和批量处理的方式,将二维码的验证任务分解为多个子任务进行处理,以提高整体的处理效率。例如,可以将待验证的二维码按批次发送到后台进行验证,再将验证结果返回给前端。

    总的来说,使用分布式数据库和查询优化等技术,结合合理的数据存储和查询策略,可以满足对历史码包进行验重并保证响应时间在 3 秒以内的需求。具体的方案可以根据你的具体业务和技术要求进行进一步的调研和评估
    aliyun2017
        3
    aliyun2017  
       247 天前
    @aliyun2017 来自 Ai 回复
    tomSoSleepy
        4
    tomSoSleepy  
       247 天前
    转成数学题问问 AI?
    vus520
        5
    vus520  
       247 天前
    1. 千万级的数据 redis 完全可以,直接使用 hash 或者 kv 就可以搞定,不要使用 bitmap
    2. 不知道具体逻辑,在 redis 场景内,验重接口超过 500ms 就算慢了
    edward1987
        6
    edward1987  
       247 天前
    如果 redis 成本过高,用 mongodb 的 uniq key 插入也是可以的 一般 1s 内就能返回
    tool2d
        7
    tool2d  
       247 天前   ❤️ 2
    千万数量级的二维码,听起来很唬人,其实就是一堆 int 整形数字去重算法。

    本地内存建立一个 hash 表去重,都能直接搞定。
    ytmsdy
        8
    ytmsdy  
       247 天前
    我觉得还不如直接修改修改二维码生成算法来的方便,时间戳搞成毫秒级别,我就不信这还能再重复了!
    jgh004
        9
    jgh004  
       247 天前
    数据存到 san 上,服务器内存搞大点,条码表建索引,千万级别很快的,亿级也没事。
    lmshl
        10
    lmshl  
       247 天前
    把二维码的位数搞大一点,比如 128-bit 不就不会重复了么?🤔
    为啥要设计的这么复杂?
    UUID 也就 128-bit, 100 万亿 UUID 中重复一次的概率是百万分之一。
    买双色球都没中过头奖,不如直接用 UUID 编码到二维码了
    BeiChuanAlex
        11
    BeiChuanAlex  
       247 天前   ❤️ 4
    为什么要查重,直接用时间+随机数生成不就行了
    xulihang
        12
    xulihang  
       247 天前
    扫码用的是什么库?扫这么多码准确吗
    xyfan
        13
    xyfan  
       247 天前
    为什么不在喷二维码之前进行校验,要生产完成之后流水线加摄像头,这不是舍近求远吗?
    你们的二维码是自己的算法生成的吗?是的话加一个时间戳\年月日\自增的生产批号相关的项不就能直接保证不重复。如果二维码是客户给的,你们只负责喷印,也应该在喷印之前对数据进行去重,效率应该更高。
    Rang666
        14
    Rang666  
       247 天前 via iPhone
    编码规则有吗,一般来说 sfc 这种都有工厂信息时间这些,根据时间不能筛出去一部分吗?
    另外,码包是啥,单纯用来去重还是从里面取数生成新的,场景不是很理解
    svnware
        15
    svnware  
       247 天前
    生成算法保证不会重复就好了,不需要查重呀
    CHchenkeyi
        16
    CHchenkeyi  
       247 天前
    @xyfan 舍近求远用的好,感觉一开始流程设计就有问题,既然是自己生产的,直接时间戳加一个批次号不就好了。怎么会想着还用摄像头采集再去重
    lodinglog
        17
    lodinglog  
       247 天前
    Redis 可行。题外话.生成算法能保证不重复,但是没人敢打包票印刷厂那边的喷码/打印机那边打印不重。该有的重复验证还是需要有。
    iosyyy
        18
    iosyyy  
       247 天前
    千万级别才多大 redis 完全够用
    stinkytofu
        19
    stinkytofu  
       247 天前
    @xyfan #13 你没仔细审题, 码包是客户给的, 客户那边的生成唯一性没办法保证, 而且应该也出现过重复的, 不然老板不会提这样的要求!
    2020beBetter
        20
    2020beBetter  
       247 天前
    一物一码,好熟悉的名词。刚入行就是做一物一码相关的项目。
    1.redis 完全可行。
    2.放到 redis 里面做

    重复现在是出现在哪里?是喷到包装盒上重复了(你们机器的问题)。客户给的码包(原始问题)
    2020beBetter
        21
    2020beBetter  
       247 天前
    1.入口 对客户发来的码包进行逐条验证,与历史数据比较。
    2.出口 对包装盒喷涂完成后进行验证,这个成本较大(可以考虑进行部分验证)
    tool2d
        22
    tool2d  
       247 天前
    "2. 有一个码管理系统,条码都会导入系统,然后通过系统生成 txt 文件 下发给喷码机。"

    既然能拿到原始数据,何必用摄像头识别二维码。txt 就直接过滤了。
    lenmore
        23
    lenmore  
       247 天前
    没必要 redis 。几千万数据,建好索引,MySQL 没有任何问题。
    yshtcn
        24
    yshtcn  
       247 天前
    码包是客户给的没关系,你在喷码之前就查重就可以了。虽然帖子比较乱,不知道是历史查重还是同一包查重。但是只要你把码给解析成数据,那就是个查重算法解决的问题。
    yshtcn
        25
    yshtcn  
       247 天前
    可以说不需要任何的数据库或者高并发,实习生/GPT 都会写
    yshtcn
        26
    yshtcn  
       247 天前
    昂,其实楼主已经做了,是我没认真看。其实问题已经转化为一批/一个新的数据如何在每批几十万,累计千万的数据库中查重的问题了。一批的话,我觉得速度不是问题。但是单个再校验就要求速度了。
    我认为 GPT 提出的结合哈希表(散列表)或者布隆过滤器、数据库索引优化应该就可以了。最多会出现假阳性的检测结果。
    unco020511
        27
    unco020511  
       247 天前
    @stinkytofu 拿到码包第一时间就可以去重啊,为啥还要到最后的流程去重
    dode
        28
    dode  
       247 天前
    历史条码严格递增,不允许变小
    dode
        29
    dode  
       247 天前
    按二维码的前缀或后缀分库分表,压缩包复制 N 份,各自解压按分表规则导入查重
    tek
        30
    tek  
       247 天前
    md5 + hash
    lmshl
        31
    lmshl  
       247 天前
    如果不能改变上游的话,最简单的方法就是搞一个 bloom filter index ,postgresql 原生支持这种 index 。
    如果只能用 mysql 的话,也可以在 mysql 里自己维护实现 bloom filter ,不是很难。
    然后做分级索引,合并成一个大的 bloom 。

    虽然会有 false positive ,只要控制在 1%以内,你就可以以极高的效率查出哪个码从来没出现过。仅在命中 bloom 的时候去做二次校检。
    rekulas
        32
    rekulas  
       247 天前
    这个直接分表不是很简单么,mysql 一表一亿基本几毫秒就返回了

    其实更好的方式是找个 kv 库, 不需要 redis 直接本地磁盘就行了, 1 年亿级数据太小了压根不用担心效率,一天 1 亿的数据库对 kv 来说也没啥影响

    提供个参考, 之前 rocketdb, 40 亿数据情况下普通 ssh 硬盘读取查询 5-10 万并发,平均时间几毫秒
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5799 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 06:21 · PVG 14:21 · LAX 22:21 · JFK 01:21
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.