我有一個要求,我需要用人名加入推文表,比如過濾包含任何人名的推文。我有以下資料:
推文表:(7000 萬條記錄存盤為 HIVE 表)
| ID | 鳴叫 |
|---|---|
| 1 | 有史以來最偉大的克里斯蒂亞諾·羅納爾多 |
| 2 | 布拉德皮特電影 |
| 3 | 沒有任何人名的隨機推文 |
人名:(160 萬名以 .tsv 檔案形式存盤在 HDFS 上)
| ID | 人名 |
|---|---|
| 1 | 克里斯蒂亞諾·羅納爾多 |
| 2 | 布拉德·皮特 |
| 3 | 安吉麗娜·朱莉 |
預期結果:
| ID | 鳴叫 | 人名 |
|---|---|---|
| 1 | 有史以來最偉大的克里斯蒂亞諾·羅納爾多 | 克里斯蒂亞諾·羅納爾多 |
| 2 | 布拉德皮特電影 | 布拉德·皮特 |
到目前為止我嘗試過的:
我也將人名 .tsv 檔案轉換為 HIVE 表,然后嘗試使用以下 HIVE 查詢連接 2 個表:
SELECT * FROM tweets t INNER JOIN people p WHERE instr(t.tweet, p.person_name) > 0;
嘗試了一些示例資料,效果很好。但是當我嘗試運行整個資料時(7000 萬條推文加入 160 萬個人名),它需要永遠。絕對看起來效率不高。
我也想嘗試 JOIN 和 PIG(因為它被認為比 HIVE JOIN 效率低一點),我可以直接 JOIN 人名 .tsv 檔案推文 HIVE 表,但不確定如何基于 PIG 中的子字串進行 JOIN。
如果您有任何想法,有人可以分享此問題的 PIG JOIN 語法嗎?另外,請給我建議我可以使用的任何替代方案?
uj5u.com熱心網友回復:
這個想法是創建存盤桶,這樣我們就不必比較很多記錄。我們將增加記錄/連接的數量以使用多個節點來完成作業而不是大型交叉連接。-->WHERE instr(t.tweet, p.person_name) > 0;
- 我建議將推文拆分為單獨的單詞。是的,將您的記錄數增加。
- 過濾掉“停用詞”或其他一些適合記憶的詞串列。
- 將姓名拆分為(名字)和“姓氏”
- 在“姓氏”上加入推文和姓名,
instr(t.tweet, p.person_name)這應該會顯著減少您通過函式進行比較的資料大小。它會跑得更快。
如果您打算定期執行此操作,請考慮使用 sort/bucket 創建表以真正使事情變得嘶嘶聲。(讓它更快,因為它有望為 Sort Merge Join 做好準備。)
uj5u.com熱心網友回復:
值得嘗試 Map-Join。Person 表很小,如果它適合記憶體,可以將其連接轉換為 Map-Join 運算子。表將被加載到每個映射器記憶體中。
檢查 EXPLAIN 輸出。如果它說Common Join operator是在 Reducer 頂點上,那么嘗試增加映射器容器記憶體并調整映射連接設定以轉換為映射連接。
負責 Map Join 的設定(假設 People 表 <2.5Gb)嘗試將 mapjoin 表大小提高到 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 operator,然后再次檢查執行,它應該運行得更快。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/364279.html
