2012-12-05 27 views
41

जहां तक ​​मैं समझता हूं;बनाम ऑर्डर द्वारा बनाम ऑर्डर बनाम क्रमबद्ध करें

  • तरह केवल द्वारा विश्व स्तर पर आदेश चीजों से कम करने में

  • आदेश के साथ सॉर्ट करता है लेकिन एक reducers

    में सब कुछ shoves
  • क्लस्टर समझदारी से कुंजी हैश द्वारा reducers में सामान वितरित करता है और एक बनाने के द्वारा

तो मेरा प्रश्न वैश्विक आदेश की गारंटी के द्वारा क्लस्टर करता है? एक ही कुंजी को उसी reducers में डालकर वितरित करें, लेकिन आसन्न कुंजी के बारे में क्या?

इस पर एकमात्र दस्तावेज़ मुझे मिल सकता है here है और उदाहरण से ऐसा लगता है कि यह उन्हें वैश्विक स्तर पर आदेश देता है। लेकिन परिभाषा से मुझे लगता है कि यह हमेशा ऐसा नहीं करता है।

उत्तर

110

एक छोटा सा जवाब: हाँ, CLUSTER BY वैश्विक आदेश की गारंटी देता है, बशर्ते आप कई आउटपुट फाइलों में शामिल होने के इच्छुक हों।

अब संस्करण:

  • ORDER BY x: वैश्विक आदेश की गारंटी देता है, लेकिन सिर्फ एक कम करने के माध्यम से सभी डेटा भेजे करके करता है। यह बड़े डेटासेट के लिए मूल रूप से अस्वीकार्य है। आप एक सॉर्टेड फ़ाइल को आउटपुट के रूप में समाप्त करते हैं।
  • SORT BY x: प्रत्येक एन reducers में डेटा आदेश, लेकिन प्रत्येक reducer डेटा की ओवरलैपिंग श्रेणियां प्राप्त कर सकते हैं। आप ओवरलैपिंग श्रेणियों के साथ एन या अधिक सॉर्ट की गई फ़ाइलों के साथ समाप्त होते हैं।
  • DISTRIBUTE BY x: सुनिश्चित करता है कि प्रत्येक एन रेड्यूसर को x की गैर-ओवरलैपिंग श्रेणियां मिलती हैं, लेकिन प्रत्येक रेड्यूसर के आउटपुट को सॉर्ट नहीं करती है। आप गैर-ओवरलैपिंग श्रेणियों वाले एन या अनसुलझा फ़ाइलों के साथ समाप्त होते हैं।
  • CLUSTER BY x: सुनिश्चित करता है कि प्रत्येक एन रेड्यूसर को गैर-ओवरलैपिंग श्रेणियां मिलती हैं, फिर उन श्रेणियों द्वारा रेड्यूसर पर सेट किया जाता है। यह आपको वैश्विक क्रम देता है, और ऐसा करने जैसा ही है (DISTRIBUTE BY x और SORT BY x)। आप गैर-ओवरलैपिंग श्रेणियों वाले एन या अधिक सॉर्ट की गई फ़ाइलों के साथ समाप्त होते हैं।

समझ में आओ? तो CLUSTER BY मूल रूप से ORDER BY का अधिक स्केलेबल संस्करण है।

+0

अच्छा स्पष्टीकरण .. – minhas23

+7

जैसा कि अन्य उत्तरों द्वारा उल्लिखित है, https://cwiki.apache.org/confluence/display/Hive/LanguageManual+SortBy, 'CLUSTER BY' और 'DISTRIBUTE BY' के अनुसार आपको गैर- ओवरलैपिंग रेंज। 'क्लस्टर बाय' वैश्विक क्रम की गारंटी नहीं दे सकता है। – yhuai

+0

मैं सोच रहा हूं ... क्या "बड़े डेटासेट" माना जाता है? क्या आप इसे माप सकते हैं? – idoda

10

मुझे पहले स्पष्टीकरण दें: clustered by केवल अपनी बाल्टी को अलग-अलग बाल्टी में वितरित करता है, clustered by ... sorted by बाल्टी सॉर्ट किया जाता है।

एक साधारण प्रयोग के साथ (नीचे देखें) आप देख सकते हैं कि आपको डिफ़ॉल्ट रूप से वैश्विक आदेश नहीं मिलेगा। इसका कारण यह है कि डिफ़ॉल्ट विभाजनकर्ता वास्तविक कुंजी ऑर्डरिंग के बावजूद हैश कोड का उपयोग करके कुंजी को विभाजित करता है।

हालांकि आप अपना डेटा पूरी तरह से ऑर्डर कर सकते हैं।

प्रेरणा टॉम व्हाइट (तीसरा संस्करण, अध्याय 8, पृष्ठ 274, कुल क्रमबद्ध) द्वारा "हैडोप: द डेफिनिटिव गाइड" है, जहां उन्होंने कुल ऑर्डर पार्टिशनर पर चर्चा की।

मैं पहले आपके कुल ऑर्डरिंग प्रश्न का उत्तर दूंगा, और फिर मैंने कई प्रकार से संबंधित हाइव प्रयोगों का वर्णन किया जो मैंने किया था।

ध्यान रखें: मैं जो वर्णन कर रहा हूं वह 'अवधारणा का प्रमाण' है, मैं क्लाउडेरा के सीडीएच 3 वितरण का उपयोग करके एक उदाहरण को संभालने में सक्षम था।

मूल रूप से मुझे उम्मीद थी कि org.apache.hadoop.mapred.lib TotalOrderPartitioner चाल करेगा। दुर्भाग्य से ऐसा इसलिए नहीं हुआ क्योंकि यह मूल्य से हाइव विभाजन की तरह दिखता है, कुंजी नहीं। इसलिए मैं यह पैच (उपवर्ग होना चाहिए, लेकिन मुझे लगता है कि के लिए समय नहीं है):

अपने हाइव के रूप में

public int getPartition(K key, V value, int numPartitions) { 
    return partitions.findPartition(key); 
} 

बदलें

public int getPartition(K key, V value, int numPartitions) { 
    return partitions.findPartition(value); 
} 

अब आप (समझौता) सेट कर सकते हैं साथ TotalOrderPartitioner विभाजक:

hive> set hive.mapred.partitioner=org.apache.hadoop.mapred.lib.TotalOrderPartitioner; 

hive> set total.order.partitioner.natural.order=false 

hive> set total.order.partitioner.path=/user/yevgen/out_data2 

मैं भी

इस्तेमाल किया 0
hive> set hive.enforce.bucketing = true; 

hive> set mapred.reduce.tasks=4; 

मेरे परीक्षणों में।

फ़ाइल out_data2 कुलऑर्डरपार्टिशनर को मूल्यों को बाल्टी करने के लिए कहता है। आप अपने डेटा का नमूनाकरण करके out_data2 उत्पन्न करते हैं। मेरे परीक्षणों में मैंने 4 बाल्टी और चाबियाँ 0 से 10 तक उपयोग कीं।

import org.apache.hadoop.util.ToolRunner; 
import org.apache.hadoop.util.Tool; 
import org.apache.hadoop.conf.Configured; 
import org.apache.hadoop.fs.Path; 
import org.apache.hadoop.io.NullWritable; 
import org.apache.hadoop.io.SequenceFile; 
import org.apache.hadoop.hive.ql.io.HiveKey; 
import org.apache.hadoop.fs.FileSystem; 


public class TotalPartitioner extends Configured implements Tool{ 
    public static void main(String[] args) throws Exception{ 
      ToolRunner.run(new TotalPartitioner(), args); 
    } 

    @Override 
    public int run(String[] args) throws Exception { 
     Path partFile = new Path("/home/yevgen/out_data2"); 
     FileSystem fs = FileSystem.getLocal(getConf()); 

     HiveKey key = new HiveKey(); 
     NullWritable value = NullWritable.get(); 

     SequenceFile.Writer writer = SequenceFile.createWriter(fs, getConf(), partFile, HiveKey.class, NullWritable.class); 
     key.set(new byte[]{1,3}, 0, 2);//partition at 3; 1 came from Hive -- do not know why 
     writer.append(key, value); 
     key.set(new byte[]{1, 6}, 0, 2);//partition at 6 
     writer.append(key, value); 
     key.set(new byte[]{1, 9}, 0, 2);//partition at 9 
     writer.append(key, value); 
     writer.close(); 
     return 0; 
    } 

} 

तब मैं HDFS को out_data2 जिसके परिणामस्वरूप की नकल की

इन सेटिंग्स मैं अपने डेटा bucketed/हल कर दिया गया साथ

(/ उपयोगकर्ता/येवगेन/out_data2 में) (पिछले आइटम देखें: मैं तदर्थ दृष्टिकोण का उपयोग कर out_data2 उत्पन्न मेरी प्रयोग सूची में)।

यहां मेरे प्रयोग हैं।

  • बनाएं नमूना डेटा

    बैश> गूंज -e "1 \ n3 \ n2 \ n4 \ n5 \ n7 \ n6 \ एन 8 \ n9 \ N0"> data.txt

  • बनाएं मूल परीक्षण तालिका:

    हाइव> तालिका परीक्षण (x int) बनाएं; हाइव> तालिका परीक्षण में डेटा डेटा स्थानीय inpath 'data.txt' लोड करें;

मूल रूप से इस तालिका में क्रमशः 0 से 9 के मान होते हैं।

  • का प्रदर्शन कैसे तालिका नकल काम करता है>

    छत्ता (वास्तव में पैरामीटर जो कम कर कार्यों का उपयोग करने की अधिकतम संख्या सेट mapred.reduce.tasks) तालिका test2 बनाने (एक्स int);

    हाइव> mapred.reduce.tasks = 4 सेट करें;

    छत्ता> डालने अधिलेखित तालिका test2 परीक्षण से चयन a.x एक a.x = b.x पर परीक्षण ख में शामिल होने के; - stupied गैर तुच्छ के लिए मजबूर करने में शामिल होने के नक्शे-को कम

    बैश> Hadoop FS -बिल्ली/उपयोगकर्ता/छत्ता/गोदाम/test2/000001_0

  • बाल्टी लगाने का प्रदर्शन करें। आप देख सकते हैं कि कुंजियां किसी भी प्रकार के क्रम के बिना यादृच्छिक रूप से assinged हैं:

    हाइव> तालिका test3 (x int) (x) द्वारा 4 बाल्टी में क्लस्टर किया गया;

    हाइव> hive.enforce.bucketing = true सेट करें;

    हाइव> सम्मिलित करें तालिका टेस्ट 3 परीक्षण से * चुनें;

    बैश> Hadoop FS -बिल्ली/उपयोगकर्ता/छत्ता/गोदाम/test3/000000_0

  • छँटाई के साथ बकेटिंग।परिणाम आंशिक रूप से तालिका test4 (एक्स int) 4 बाल्टी में से (एक्स) (एक्स desc) के अनुसार क्रमबद्ध क्लस्टर बनाने हल कर रहे हैं, नहीं पूरी तरह से हल कर

    छत्ता>;

    हाइव> तालिका टेस्ट 4 ओवरराइट करें परीक्षण से * चयन करें;

    बैश> Hadoop FS -बिल्ली/उपयोगकर्ता/छत्ता/गोदाम/test4/000001_0

आप देख सकते हैं कि मूल्यों में हल कर रहे हैं आरोही क्रम। ऐसा लगता है कि सीडीएच 3 में हाइव बग? के रूप में मेज test5 बनाने का चयन एक्स परीक्षण से एक्स तरह एक्स desc द्वारा द्वारा वितरित>

छत्ता;:

  • आंशिक रूप से बयान से क्लस्टर के बिना हल कर हो रही है

    बैश> Hadoop FS -बिल्ली/उपयोगकर्ता/छत्ता/गोदाम/test5/000001_0

  • मेरी समझौता TotalOrderParitioner का उपयोग करें:

    छत्ता > hive.mapred.partitioner = org.apache.hadoop.mapred.lib setOrderPartitioner सेट करें;

    छत्ता> = झूठी

    छत्ता> सेट total.order.partitioner total.order.partitioner.natural.order निर्धारित किया है।पथ =/उपयोगकर्ता/प्रशिक्षण/out_data2

    हाइव> तालिका test6 (x int) (x) द्वारा क्रमबद्ध (x) 4 बाल्टी में क्रमबद्ध करें;

    हाइव> तालिका टेस्ट 6 ओवरराइट करें परीक्षण से * चयन करें;

    बैश> Hadoop FS -बिल्ली/उपयोगकर्ता/छत्ता/गोदाम/test6/000000_0

    बैश> Hadoop FS -बिल्ली/उपयोगकर्ता/छत्ता/गोदाम/test6/000001_0

    बैश> Hadoop FS -बिल्ली/उपयोगकर्ता/छत्ता/गोदाम/test6/000002_0

    बैश> Hadoop FS -बिल्ली/उपयोगकर्ता/हाइव/गोदाम/test6/000003_0

4

जैसा कि मैं समझता हूं, संक्षिप्त उत्तर संख्या आपको ओवरलैपिंग श्रेणियां मिलेंगी।

SortBy documentation से: "क्लस्टर बाय द्वारा वितरित और क्रमबद्ध दोनों के लिए एक छोटा सा कट है।" "कॉलम द्वारा एक ही वितरण के साथ सभी पंक्तियां एक ही reducer पर जायेंगे।" लेकिन ऐसी कोई जानकारी नहीं है जो गैर-ओवरलैपिंग श्रेणियों की गारंटी द्वारा वितरित करें।

इसके अलावा, DDL BucketedTables documentation से: "कैसे हाइव बाल्टी भर पंक्तियों को वितरित करता है सामान्य में, बाल्टी संख्या अभिव्यक्ति hash_function (bucketing_column) आधुनिक num_buckets से निर्धारित होता है।" मुझे लगता है कि चयन कथन में क्लस्टर रेड्यूसर के बीच पंक्तियों को वितरित करने के लिए समान सिद्धांत का उपयोग करता है क्योंकि इसका मुख्य उपयोग डेटा के साथ बाल्टी वाली टेबल को पॉप्युलेट करने के लिए होता है।

मैंने तालिका बुद्धि 1 int कॉलम "ए" बनाया, और 0 से 9 तक संख्याएं डालीं।

फिर मैंने reducers की संख्या 2 set mapred.reduce.tasks = 2; पर सेट की।

और खंड select * from my_tab cluster by a;

के हिसाब से समूह के साथ इस तालिका से डेटा से चयन करें और नतीजा यह है कि मैं उम्मीद प्राप्त किया:

0 2 4 6 8 1 3 5 7 9

तो सबसे पहले कम करने (संख्या 0) भी संख्या हो गया (क्योंकि उनके के मोड 2 देता है 0)

और दूसरा reducer (संख्या 1) विषम संख्या मिली (क्योंकि उनके मोड 2 देता है 1)

तो इस प्रकार "द्वारा वितरित" काम करता है।

और फिर "सॉर्ट करें" प्रत्येक रेड्यूसर के अंदर परिणामों को टाइप करता है।

1

CLUSTER BY वैश्विक ऑर्डरिंग नहीं करता है।

स्वीकार्य उत्तर (लार्स येनकेन द्वारा) यह बताकर गुमराह करता है कि reducers गैर-ओवरलैपिंग श्रेणियां प्राप्त करेंगे। चूंकि एंटोन ज़विरिखिन सही ढंग से बकेटेडटेबल्स दस्तावेज को इंगित करते हैं, क्लस्टर बीई मूल रूप से प्रत्येक बाल्टी/रेड्यूसर के भीतर (बाल्टी के समान) के साथ वितरित होता है। और बाल्टी में बस हैश और मोड द्वारा वितरित करें और हैशिंग फ़ंक्शन may ऑर्डर को सुरक्षित रखें (i> j> i> j का हैश हैश) हैश मान का मोड नहीं है।

यहाँ एक बेहतर अतिव्यापी पर्वतमाला

http://myitlearnings.com/bucketing-in-hive/

0

से कम करने प्रति है वैश्विक नहीं छँटाई क्लस्टर दिखा उदाहरण है। कई पुस्तकों में भी गलत तरीके से या भ्रमित का उल्लेख किया गया है। इसका विशेष उपयोग होता है जहां कहा जाता है कि आप प्रत्येक विभाग को विशिष्ट रेड्यूसर में वितरित करते हैं और उसके बाद प्रत्येक विभाग में कर्मचारी नाम से सॉर्ट करते हैं और क्लस्टर को इस्तेमाल करने के लिए किसी भी प्रकार की अनुमति नहीं देते हैं और यह अधिक प्रदर्शन-चींटी है क्योंकि वर्कलोड को reducers के बीच वितरित किया जाता है ।

+0

यदि आप वितरित करने के बाद collect_set या collect_list का उपयोग करते हैं, तो क्या यह ऑर्डर सुरक्षित रखेगा? – vkaul11