当前业务场景是这样:已有一组 hash 值,大概 5 亿条,我希望找到一种存储结构或者工具能够实现,再来一组 hash 值的时候,能够快速的过滤掉已经存在的数据,因为所有新增的 hash 值我都要用程序处理一遍。每次新增一组大概 1 亿级别左右。程序处理完后,再导入到设计好的结构中。硬件标准为; cpu 6700k ,硬盘 STAT3 接口固态存储,内存 16g 。如果对内存要求较高,还可以再加 16g 。
目前我处理的方式是这样的,按照 hash 值首字母分 26 个文件,当前已有 10 亿条数据,每个文件大概 1g 左右,在去重时,先对新增的数据分文件,然后再分别读取对应两个文件数据,用的是 java Set 去重后保存。不过我发现当旧数据文件达到 3g 以上时,大概 1.2 亿条,这种方式就相当慢,时间并不是随着文件大小线性增加,好像有个阈值,超过了就非常慢。暂时这个值是多少没去测试。
1
liprais 2016-09-02 18:50:28 +08:00
'这种方式就相当慢,时间并不是随着文件大小线性增加,好像有个阈值,超过了就非常慢。暂时这个值是多少没去测试。'
这个阈值就是你的内存大小..... |
3
CosimoZi 2016-09-02 18:55:22 +08:00
布隆过滤器
|
4
RangerWolf 2016-09-02 18:57:10 +08:00
如果是只能单机解决, 建议采用分而治之的方法~
思想其实就是一些分布式 NoSQL 的一些思想。 比如将 Hash 的头 2 个字母或者 3 个字母做分表。 每次只解决一个分表之中的内容~ 我们的业务跟你有完全一样的需求,我们是分布式数据库 Cassandra , hash 做主键,每次只需要到 DB 之中查询一下就好了~ 异步查询,通过并发来加快速度,最终性能也满足我们的需求, 并且持续运行稳定~ |
5
htfy96 2016-09-02 19:00:59 +08:00 via Android
hash 值范围是多少?如果就 32 位的话加条内存全放内存里就行啊…
|
6
cheitu OP @htfy96 是 32 以内,当前我就是全放内存,不知道是文件读取效率低还是 java set 去重效率低, 1g 左右, 5 分钟内解决,超过了 3g ,时间就变得很长。这个时间我还没测试出来。目前最有耐心的一次等待是 40 分钟都没解决。
|
8
cheitu OP @RangerWolf 谢了。我研究下。
|
9
SoloCompany 2016-09-02 19:51:09 +08:00 via iPhone
上 profiler 啊,明显是内存不足导致,你把 1g 的时候运行的内 lheap 的峰值看一下,然后乘以 4 来初始化 heap
|
10
cheitu OP @SoloCompany 好。我后面再进行测试下
|