HIVE/PIG JOIN 基于 SUBSTRING 匹配

HIVE/PIG JOIN Based on SUBSTRING match

我有一个要求,我需要加入带有人名的推文 table,例如过滤包含任何人名的推文。我有以下数据:

推文 Table:(7000 万条记录存储为 HIVE Table)

id tweet
1 Cristiano Ronaldo greatest of all time
2 Brad Pitt movies
3 Random tweet without any person name

人名:(160 万个名字作为 .tsv 文件存储在 HDFS 上)

id person_name
1 Cristiano Ronaldo
2 Brad Pitt
3 Angelina Jolie

预期结果:

id tweet person_name
1 Cristiano Ronaldo greatest of all time Cristiano Ronaldo
2 Brad Pitt movies Brad Pitt

到目前为止我尝试过的:

我也将人名 .tsv 文件转换为 HIVE table,然后尝试使用以下 HIVE 查询加入 2 tables:

SELECT * FROM tweets t INNER JOIN people p WHERE instr(t.tweet, p.person_name) > 0;

尝试了一些示例数据,效果很好。但是当我尝试 运行 整个数据时(7000 万条推文加入 160 万个人姓名),它需要很长时间。确实看起来效率不高。

我也想尝试使用 PIG 进行 JOIN(因为它被认为比 HIVE JOIN 效率更高),我可以在其中直接 JOIN person names .tsv file tweets HIVE Table,但不确定如何JOIN 基于 PIG 中的子字符串。

有人可以分享一下 PIG JOIN 语法来解决这个问题吗?如果你有任何想法?另外,请给我一些我可以使用的替代方案的建议吗?

Map-Join值得一试。 Person table 很小,如果适合内存,可以将其连接转换为 Map-Join 运算符。 Table 将加载到每个映射器内存中。

检查 EXPLAIN 输出。如果它说 Common Join operator 在 Reducer 顶点上,那么尝试增加 mapper 容器内存并调整 map-join 设置以转换为 Map Join。

负责 Map Join 的设置(假设 People table <2.5Gb) 尝试将 mapjoin table 大小增加到 2.5Gb(检查实际大小)并 运行 再次解释。

 set hive.auto.convert.join=true; --this enables map-join
 set hive.auto.convert.join.noconditionaltask = true;
 set hive.mapjoin.smalltable.filesize=2500000000; --size of table to fit in memory
 set hive.auto.convert.join.noconditionaltask.size=2500000000;

还应增加容器大小以避免 OOM(如果您使用的是 Tez):

set hive.tez.container.size=8192;  --container size in megabytes
set hive.tez.java.opts=-Xmx6144m;  --set this 80% of hive.tez.container.size

数字只是一个例子。尝试再次调整并检查 EXPLAIN,如果它显示 Map-Join 运算符,然后再次检查执行,它应该 运行 快得多。

我们的想法是创建存储桶,这样我们就不必比较大量记录。我们将增加记录/连接的数量以使用多个节点而不是大型交叉连接来完成工作。--> WHERE instr(t.tweet, p.person_name) > 0;

  1. 我建议将推文拆分成单独的词。是的,将您的记录数乘以。
  2. 过滤掉 'stopwords' 或适合记忆的一些其他单词列表。
  3. 将姓名拆分为(名字)和“姓氏”
  4. 在“lastname”和 instr(t.tweet, p.person_name) 上加入推文和姓名,这应该会显着减少您通过函数比较的数据大小。它会 运行 更快。

如果您要定期这样做,请考虑使用 sort/bucket 真正让事情变得热闹起来。 (使其更快,因为它有望为 Sort Merge Join 做好准备。)