我正在读取一个大文件(超过10亿条记录)并将其与其他三个文件连接起来,我想知道是否有任何方法可以提高该过程的效率,以避免对大表进行多次读取。小表可能无法放入内存中。
A = join smalltable1 by (f1,f2) RIGHT OUTER,massive by (f1,f2) ;
B = join smalltable2 by (f3) RIGHT OUTER, A by (f3) ;
C = join smalltable3 by (f4) ,B by (f4) ;
我正在考虑的另一种方法是编写一个udf并在一次读取中替换值,但我不确定udf是否有效,因为小文件无法放入内存。实现可以是:
A = LOAD massive
B = generate f1,udfToTranslateF1(f1),f2,udfToTranslateF2(f2),f3,udfToTranslateF3(f3)
感谢你的想法。。。
1条答案
按热度按时间x0fgdtte1#
清管器0.10引入布卢姆过滤器集成http://search-hadoop.com/c/pig:/src/org/apache/pig/builtin/bloom.java%7c%7c+%2522done+%2522exec+元组%2522
你可以在3个小文件上训练一个bloom过滤器,过滤大文件,希望它能产生一个小文件。然后执行标准联接以获得100%的精度。
更新1您实际上需要训练2个bloom过滤器,每个小表一个,因为您在不同的键上连接。
更新2注解中提到,外部连接用于扩充数据。在这种情况下,bloom过滤器可能不是最好的选择,因为您希望保留不匹配的数据,所以它们适合于过滤,并且不在外部联接中添加数据。一个更好的方法是将所有的小表分区在各自的字段(f1、f2、f3、f4)上,将每个分区存储到一个单独的文件中,该文件足够小,可以加载到内存中。而不是在f1、f2、f3、f4上按大量表分组,并在foreach中将组(f1、f2、f3、f4)和相关包传递给用java编写的自定义函数,该函数将小文件的各个分区加载到ram中并执行扩充。