2013-11-25 6 views
11

मैं हाइव में दो बड़े तालिकाओं में शामिल होने हूँ के शामिल होने के इतने की तरह (एक 1 अरब से अधिक पंक्तियाँ, एक के बारे में 100 मिलियन पंक्तियों है):हाइव - कुशल दो तालिकाओं

create table joinedTable as select t1.id, ... from t1 join t2 ON (t1.id = t2.id); 

मैं में दो तालिकाओं bucketed है वैसे ही, प्रत्येक के लिए 100 बाल्टी में आईडी द्वारा क्लस्टरिंग, लेकिन क्वेरी अभी भी एक लंबा समय ले रही है।

इसे कैसे गति दें इस पर कोई सुझाव?

उत्तर

13

जैसे ही आप जॉइन कुंजी द्वारा डेटा बाल्टी करते हैं, आप बाल्टी मानचित्र में शामिल हो सकते हैं। इसके लिए एक टेबल में बाल्टी की मात्रा अन्य तालिका में बाल्टी की मात्रा का एक बहु होना चाहिए। इसे क्वेरी से पहले set hive.optimize.bucketmapjoin=true; निष्पादित करके सक्रिय किया जा सकता है। यदि टेबल परिस्थितियों को पूरा नहीं करते हैं, तो हाइव सामान्य आंतरिक शामिल होंगी।

यदि दोनों तालिकाओं में बाल्टी की समान मात्रा होती है और डेटा बाल्टी कुंजी द्वारा क्रमबद्ध किया जाता है, तो हाइव तेजी से सॉर्ट-मर्ज में शामिल हो सकता है। इसे सक्रिय करने के लिए, आप निम्नलिखित आदेश पर अमल करने के लिए है:

set hive.input.format=org.apache.hadoop.hive.ql.io.BucketizedHiveInputFormat; 
set hive.optimize.bucketmapjoin=true; 
set hive.optimize.bucketmapjoin.sortedmerge=true; 

आप अलग अलग से कुछ दृश्यावलोकन पा सकते हैं https://cwiki.apache.org/confluence/download/attachments/27362054/Hive+Summit+2011-join.pdf तहत तकनीक में शामिल हो।

+0

मैं इसे एक शॉट दूंगा। इंडेक्स हाइव में बिल्कुल मदद करते हैं? अर्थात। अगर मैंने आईडी द्वारा टी 1 और टी 2 दोनों को अनुक्रमित किया है? – maia

+0

और मैं अनुमान लगा सकता हूं कि कितने बाल्टी उपयोग करना है? – maia

+0

इंडेक्स में शामिल होने में प्रदर्शन में सुधार नहीं होगा। उनका उपयोग एकल पंक्तियों को पुनर्प्राप्त करने के लिए किया जाता है, उदाहरण के लिए 'WHERE id = 123' में। बाल्टी यहां सबसे अच्छी पसंद हैं। –

11

जैसा कि मैंने देखा है कि उत्तर @ एड्रियन लैंग की पेशकश की तुलना में थोड़ा अधिक जटिल है।

सबसे पहले आप BucketJoin और क्रमबद्ध-मर्ज बाल्टी में शामिल हों (SMBJ) के बीच एक बहुत ही महत्वपूर्ण अंतर को समझना चाहिए:

एक bucketjoin करने के लिए "एक तालिका में बाल्टी की राशि की राशि का गुणांक होना चाहिए अन्य तालिका में बाल्टी "जैसा कि पहले बताया गया है और इसके अलावा hive.optimize.bucketmapjoin को सत्य पर सेट किया जाना चाहिए।
एक जॉइन जारी करने के बाद, हाइव इसे bucketjoin में परिवर्तित कर देगा यदि उपरोक्त स्थिति पर रखती है लेकिन ध्यान दें कि हाइव बाल्टी को लागू नहीं करेगा! इसका मतलब यह है कि तालिका को बाल्टी बनाने के लिए तालिका के लिए पर्याप्त मात्रा में बाल्टी में बाल्टी लगाने के लिए पर्याप्त नहीं है क्योंकि हाइव इसे लागू नहीं करता है जब तक कि hive.enforce.bucketing सत्य पर सेट न हो (जिसका अर्थ है कि बाल्टी की मात्रा वास्तव में निर्धारित होती है तालिका में डेटा डालने वाली क्वेरी के अंतिम चरण में reducers की मात्रा)।
प्रदर्शन की ओर से के रूप में, कृपया ध्यान दें कि जब का उपयोग कर एक bucketjoin एक से पहले मानचित्रकारों इसे उपयोग और कर एकल कार्य वितरित कैश में "छोटे" तालिका पढ़ता में शामिल होने के - इस चरण में शायद बहुत बहुत लंबा हो जाएगा और अप्रभावी जब आपकी मेज ~ 100 मीटर पंक्तियां है!
वार्ड के बाद शामिल होने के लिए रेड्यूसर में नियमित रूप से शामिल होने के समान ही किया जाएगा।

एक SMBJ करने के लिए दोनों तालिकाओं, बाल्टी की सटीक एक ही राशि है करने के लिए है एक ही स्तंभों पर और सही करने के लिए hive.optimize.bucketmapjoin.sortedmerge सेटिंग के अलावा इन स्तंभों के अनुसार क्रमबद्ध।
पिछले ऑप्टिमाइज़ेशन के रूप में, हाइव बाल्टीटिंग और सॉर्टिंग को लागू नहीं करता है बल्कि यह मानता है कि टेबल वास्तव में बाल्टी और सॉर्ट किए गए हैं (न केवल परिभाषा के अनुसार बल्कि hive.enforce.sorting सेट करके या मैन्युअल रूप से डेटा डालने के दौरान सॉर्ट करना) - यह बहुत महत्वपूर्ण है क्योंकि दोनों मामलों में में गलत परिणाम हो सकता है।
performace की ओर से के रूप में, इस अनुकूलन निम्नलिखित कारणों के लिए जिस तरह से और अधिक कुशल है:

  1. प्रत्येक नक्शाकार दोनों बाल्टी पढ़ता है और वितरित कैश लोड करने के लिए कोई भी कार्य विवाद
  2. किया जा रहा शामिल होने के वहाँ एक है मर्ज-सॉर्ट जुड़ें क्योंकि डेटा पहले ही सॉर्ट किया गया है जो अत्यधिक कुशल है।

कृपया ध्यान दें निम्नलिखित बातों:

    दोनों ही मामलों में
  • set hive.input.format=org.apache.hadoop.hive.ql.io.BucketizedHiveInputFormat;
    निष्पादित किया जाना चाहिए
  • दोनों ही मामलों में एक /*+ MAPJOIN(b) */ में (दाएं select के बाद क्वेरी में लागू किया जाना चाहिए और जहां b है छोटी तालिका)
  • कितने बाल्टी?
    इसे इस कोण से देखा जाना चाहिए: विचार को बड़ी तालिका में कड़ाई से लागू किया जाना चाहिए क्योंकि इसका इस दिशा से अधिक प्रभाव पड़ता है और बाद में कॉन्फ़िगरेशन को छोटी तालिका में जरूरी रूप में लागू किया जाएगा। मुझे लगता है कि अंगूठे के नियम के रूप में प्रत्येक बाल्टी में 1 और 3 ब्लॉक के बीच होना चाहिए, शायद कहीं 2 ब्लॉक के पास। इसलिए यदि आपका ब्लॉक आकार 256 एमबी है तो यह बड़ी तालिका में प्रत्येक बाल्टी में ~ 512 एमबी डेटा रखने के लिए उचित है, इसलिए यह एक साधारण विभाजन मुद्दा बन जाता है।

इसके अलावा, यह न भूलें कि अकेले ये अनुकूलन हमेशा तेज क्वेरी समय की गारंटी नहीं देंगे।
आइए कहें कि आप एक एसएमबीजे करना चुनते हैं, इससे जुड़ने से पहले 2 टेबल को सॉर्ट करने की लागत बढ़ जाती है - इसलिए जितनी बार आप अपनी क्वेरी को कम करेंगे, उतनी ही कम आप इस सॉर्टिंग चरण के लिए "भुगतान" कर रहे हैं।

कभी-कभी, एक साधारण जुड़ाव सर्वश्रेष्ठ प्रदर्शन का कारण बनता है और उपरोक्त ऑप्टिमाइज़ेशन में से कोई भी मदद नहीं करेगा और आपको एप्लिकेशन/लॉजिकल लेवल में नियमित रूप से शामिल प्रक्रिया को अनुकूलित करना होगा या मेमोरीडस/हाइव सेटिंग्स को स्मृति उपयोग जैसे ट्यून करना होगा/समांतरता आदि

0

मुझे नहीं लगता कि यह एक जरूरी मानदंड है कि "एक तालिका में बाल्टी की मात्रा अन्य तालिका में बाल्टी की मात्रा का एक बहु होना चाहिए" नक्शा बाल्टी में शामिल होने के लिए, हमारे पास भी बाल्टी की संख्या हो सकती है ।