#大数据 #数据去重 将数据通过一组哈希函数映射到一个超大的位数组上面,判断是用同一个哈希函数映射,如果位数组上都有值则已存在。 待补充. 优点: 速度快 优点: 处理简单,支持大数据场景 将数据hash拆分到不同的小文件中,然后再对这些小文件使用内存去重 单独把这个列出来,主要觉得跟传统的数据库还是有区别的,因为这个不需要网络IO。 本质是先排序,然后移除相邻重复行达到去重的效果。 对有限枚举的数据范围,比如int类型范围,生成一个超大的数组位。每个位表示一个值的映射。 因业务要求数据准确,以及方案更为通用,只考虑选择的sqlite和linux去重两方案测试,其中sqlite3还能衍生出两个方式。以下是测试的记录: sqlite3普通列: 表结构只有一个普通列,不设置主键唯一键,1亿个字符串,每次批量写10000,耗时115秒。 使用select distinct 去重查询总数耗时300秒 sqlite3主键列: 表结构主键列,写列为主键,1亿个字符串,每次批量写10000,耗时3151秒。 使用select distinct 去重查询总数耗时50秒 Linux命令去重: 1亿个字符串写如文件耗时15秒,使用前面的linux命令去重查询耗时55秒 性能上: Linux命令去重 > sqlite3普通列 >> sqlite3主键列 SET内存去重处理小数据量的场景中效果较好,但在处理大数据量的场景中会受到限制;Bitmap,BloomFilter和HyperLogLog去重都有其局限性;比较通用可靠的方案是Linux命令去重和SQLITE去重。非精确方案
BloomFilter
优点: 占用空间少
缺点: 判断存在时。该方案存在一定的误差。HyperLogLog
精确方案
SET内存去重
缺点: 内存有限,不适合大数据量场景数据库去重
缺点: 如果数据本身不是在数据库中,需要先写入数据库。数据量多网络IO则非常频繁HASH分治去重
优点: 能解决大数据场景
缺点: 如果没法预估数据量大小,则不好评估要拆分到多少个文件。另外处理完后需要维护这些文件的删除(是否有临时表的自动删除逻辑?待验证。)SQLITE去重
优点: 处理简单,支持大数据场景,不需要网络IO。
缺点: 依赖第三组件,一般linux都默认安装有,另外SQLITE3的写锁是库级别的,并行去做多个去重需要建单独的库,不是同一个表库中使用不同的表。Linux命令去重
sort -us --buffer-size=1G %s | wc -l
sort: 默认是按ASCII码进行排序的
选项:
-u: 去掉重复
-s: 通过禁止最后比较来实现稳定排序
--buffer-size: 设置主内存的大小缓冲区, 可不设置。
wc: 打印出文本的行,词数,和字节数
选项:
-l: 行数
优点: 性能优秀
缺点:
Bitmap
优点: 性能高
缺点: 使用范围有限,无论数据很小,空间成本都是固定大SQLITE去重和Linux命令去重性能简单测试
性能测试结论
当然测试并没有考虑到并发,机器资源利用率的指标,只能得出一个大体的结论。总结
另外:flink也支持大数据去重,依赖内置的RocksDB数据库,但因我们这边业务场景上不适合flink,就没有考虑该方案进来。
2022-12-11
Views