老板要做一个二维码去重的功能。我们厂生产的每个包装盒上都会喷上一个唯一的二维码,为了防止二维码重复,计划在流水线上加装摄像头进行数据采集。
目前构想是这样的:每个托盘有 200 个盒子,二维码朝上采集一板货可能分 4 个区域采集。一次会有 50 个二维码上传到服务器进行校验,如果发现有重复的二维码,服务器会返回重复的二维码,然后设备会对重复的盒子定位并标记。
每批货物有一个码包,每个码包有 50 万个二维码。如果考虑历史码包,数据量可能会更大。
码包是客户用加密压缩文件给的,之前的系统是,收到条码之后导入 mysql 数据,用临时表校验重复,数据库用一段时间就变得贼大,要定时删历史数据。不用考虑剔除,所以对校验时长没有要求。
我有两个问题想请教大家:
1
xjpicism 46 天前
布隆过滤器?
|
2
aliyun2017 46 天前
对于第一个问题,使用 Redis 可行。Redis 是一个高性能的键值存储系统,可以用于缓存、数据结构存储和消息传递等多种场景。在你的情况下,可以使用 Redis 来存储已经验证过的二维码,通过对已存储的二维码进行对比来判断是否重复。Redis 的速度非常快,适合处理大量的数据。你可以将每个二维码作为键存储在 Redis 中,当需要进行校验时,通过查询 Redis 来判断二维码是否重复。这样可以有效地减少数据库的负载,提高验证的效率。
对于第二个问题,如果需要考虑历史码包进行验重,并且要求响应时间在 3 秒以内,可以考虑使用分布式数据库和查询优化等技术来处理。以下是一种可能的方案: 1 、使用分布式数据库,如 Apache HBase 、Cassandra 或 MongoDB ,来存储历史码包的数据。这些数据库可以水平扩展,具有良好的查询性能和高可用性,适合处理大规模数据。 2 、对于历史码包的验重,可以将数据分片存储在不同的节点上,避免单一节点的负载过重。并采用合适的数据建模和索引设计,以提高查询的效率。 3 、使用查询优化技术,如索引、分区、缓存等,来提高查询的性能。通过合理的查询计划和数据存储方式,可以减少查询的响应时间。 4 、可以考虑使用异步处理和批量处理的方式,将二维码的验证任务分解为多个子任务进行处理,以提高整体的处理效率。例如,可以将待验证的二维码按批次发送到后台进行验证,再将验证结果返回给前端。 总的来说,使用分布式数据库和查询优化等技术,结合合理的数据存储和查询策略,可以满足对历史码包进行验重并保证响应时间在 3 秒以内的需求。具体的方案可以根据你的具体业务和技术要求进行进一步的调研和评估 |
3
aliyun2017 46 天前
@aliyun2017 来自 Ai 回复
|
![]() |
4
tomSoSleepy 46 天前
转成数学题问问 AI?
|
![]() |
5
vus520 46 天前
1. 千万级的数据 redis 完全可以,直接使用 hash 或者 kv 就可以搞定,不要使用 bitmap
2. 不知道具体逻辑,在 redis 场景内,验重接口超过 500ms 就算慢了 |
![]() |
6
edward1987 46 天前
如果 redis 成本过高,用 mongodb 的 uniq key 插入也是可以的 一般 1s 内就能返回
|
![]() |
7
tool2d 46 天前 ![]() 千万数量级的二维码,听起来很唬人,其实就是一堆 int 整形数字去重算法。
本地内存建立一个 hash 表去重,都能直接搞定。 |
![]() |
8
ytmsdy 46 天前
我觉得还不如直接修改修改二维码生成算法来的方便,时间戳搞成毫秒级别,我就不信这还能再重复了!
|
9
jgh004 46 天前
数据存到 san 上,服务器内存搞大点,条码表建索引,千万级别很快的,亿级也没事。
|
10
lmshl 46 天前
把二维码的位数搞大一点,比如 128-bit 不就不会重复了么?🤔
为啥要设计的这么复杂? UUID 也就 128-bit, 100 万亿 UUID 中重复一次的概率是百万分之一。 买双色球都没中过头奖,不如直接用 UUID 编码到二维码了 |
![]() |
11
BeiChuanAlex 46 天前 ![]() 为什么要查重,直接用时间+随机数生成不就行了
|
12
xulihang 46 天前
扫码用的是什么库?扫这么多码准确吗
|
![]() |
13
xyfan 46 天前
为什么不在喷二维码之前进行校验,要生产完成之后流水线加摄像头,这不是舍近求远吗?
你们的二维码是自己的算法生成的吗?是的话加一个时间戳\年月日\自增的生产批号相关的项不就能直接保证不重复。如果二维码是客户给的,你们只负责喷印,也应该在喷印之前对数据进行去重,效率应该更高。 |
14
Rang666 46 天前 via iPhone
编码规则有吗,一般来说 sfc 这种都有工厂信息时间这些,根据时间不能筛出去一部分吗?
另外,码包是啥,单纯用来去重还是从里面取数生成新的,场景不是很理解 |
15
svnware 46 天前
生成算法保证不会重复就好了,不需要查重呀
|
16
CHchenkeyi 46 天前
@xyfan 舍近求远用的好,感觉一开始流程设计就有问题,既然是自己生产的,直接时间戳加一个批次号不就好了。怎么会想着还用摄像头采集再去重
|
17
lodinglog 46 天前
Redis 可行。题外话.生成算法能保证不重复,但是没人敢打包票印刷厂那边的喷码/打印机那边打印不重。该有的重复验证还是需要有。
|
![]() |
18
iosyyy 46 天前
千万级别才多大 redis 完全够用
|
19
stinkytofu 46 天前
@xyfan #13 你没仔细审题, 码包是客户给的, 客户那边的生成唯一性没办法保证, 而且应该也出现过重复的, 不然老板不会提这样的要求!
|
20
2020beBetter 46 天前
一物一码,好熟悉的名词。刚入行就是做一物一码相关的项目。
1.redis 完全可行。 2.放到 redis 里面做 重复现在是出现在哪里?是喷到包装盒上重复了(你们机器的问题)。客户给的码包(原始问题) |
21
2020beBetter 46 天前
1.入口 对客户发来的码包进行逐条验证,与历史数据比较。
2.出口 对包装盒喷涂完成后进行验证,这个成本较大(可以考虑进行部分验证) |
![]() |
22
tool2d 46 天前
"2. 有一个码管理系统,条码都会导入系统,然后通过系统生成 txt 文件 下发给喷码机。"
既然能拿到原始数据,何必用摄像头识别二维码。txt 就直接过滤了。 |
![]() |
23
lenmore 46 天前
没必要 redis 。几千万数据,建好索引,MySQL 没有任何问题。
|
24
yshtcn 46 天前
码包是客户给的没关系,你在喷码之前就查重就可以了。虽然帖子比较乱,不知道是历史查重还是同一包查重。但是只要你把码给解析成数据,那就是个查重算法解决的问题。
|
25
yshtcn 46 天前
可以说不需要任何的数据库或者高并发,实习生/GPT 都会写
|
26
yshtcn 46 天前
昂,其实楼主已经做了,是我没认真看。其实问题已经转化为一批/一个新的数据如何在每批几十万,累计千万的数据库中查重的问题了。一批的话,我觉得速度不是问题。但是单个再校验就要求速度了。
我认为 GPT 提出的结合哈希表(散列表)或者布隆过滤器、数据库索引优化应该就可以了。最多会出现假阳性的检测结果。 |
![]() |
27
unco020511 46 天前
@stinkytofu 拿到码包第一时间就可以去重啊,为啥还要到最后的流程去重
|
28
dode 46 天前
历史条码严格递增,不允许变小
|
29
dode 46 天前
按二维码的前缀或后缀分库分表,压缩包复制 N 份,各自解压按分表规则导入查重
|
30
tek 46 天前
md5 + hash
|
31
lmshl 46 天前
如果不能改变上游的话,最简单的方法就是搞一个 bloom filter index ,postgresql 原生支持这种 index 。
如果只能用 mysql 的话,也可以在 mysql 里自己维护实现 bloom filter ,不是很难。 然后做分级索引,合并成一个大的 bloom 。 虽然会有 false positive ,只要控制在 1%以内,你就可以以极高的效率查出哪个码从来没出现过。仅在命中 bloom 的时候去做二次校检。 |
![]() |
32
rekulas 46 天前
这个直接分表不是很简单么,mysql 一表一亿基本几毫秒就返回了
其实更好的方式是找个 kv 库, 不需要 redis 直接本地磁盘就行了, 1 年亿级数据太小了压根不用担心效率,一天 1 亿的数据库对 kv 来说也没啥影响 提供个参考, 之前 rocketdb, 40 亿数据情况下普通 ssh 硬盘读取查询 5-10 万并发,平均时间几毫秒 |