HBase
 sql >> डेटाबेस >  >> NoSQL >> HBase

कैसे करें:MapReduce में क्षेत्र-विशिष्ट कुंजी श्रेणियों के साथ नमकीन अपाचे HBase तालिकाओं को स्कैन करें

इस पोस्ट को फिर से प्रकाशित करने की अनुमति के लिए FINRA के सॉफ्टवेयर डेवलपर पेंग्यु वांग को धन्यवाद।

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

सॉल्टिंग रो कीज़

उदाहरण के लिए, दैनिक आधार पर डेटा लोड स्वीकार करने वाली तालिका दिनांक से शुरू होने वाली तार्किक पंक्ति कुंजियों का उपयोग कर सकती है, और हम इस तालिका को 1,000 क्षेत्रों में पूर्व-विभाजित करना चाहते हैं। इस मामले में, हम 1,000 विभिन्न लवण उत्पन्न करने की उम्मीद करते हैं। नमक उत्पन्न किया जा सकता है, उदाहरण के लिए:

StringUtils.leftPad(Integer.toString(Math.abs(keyCore.hashCode()% 1000)), 3, "0") + "|" + लॉजिकलकी लॉजिकलकी =2015-04-26|abcrowKey =893|2015-04-26|abc

hashCode() . से आउटपुट मोडुलो के साथ नमक मूल्य के लिए "000" से "999" तक यादृच्छिकता प्रदान करता है। इस महत्वपूर्ण परिवर्तन के साथ, टेबल को नमक सीमाओं पर पूर्व-विभाजित किया जाता है क्योंकि यह बनाया गया है। MapReduce बल्कलोड के साथ HFiles को लोड करते समय यह पंक्ति मात्रा को समान रूप से वितरित करेगा। यह गारंटी देता है कि समान नमक वाली पंक्ति कुंजियाँ एक ही क्षेत्र में आती हैं।

कई उपयोग के मामलों में, जैसे डेटा संग्रह करना, आपको MapReduce जॉब का उपयोग करके किसी विशेष तार्किक कुंजी श्रेणी (दिनांक सीमा) पर डेटा को स्कैन या कॉपी करने की आवश्यकता होती है। मानक तालिका MapReduce नौकरियां Scan . प्रदान करके सेटअप की जाती हैं प्रमुख श्रेणी विशेषताओं के साथ उदाहरण।

 स्कैन स्कैन =नया स्कैन (); स्कैन.सेट कैशिंग (1000); स्कैन। 04-26"));scan.setStopRow(Bytes.toBytes("2015-04-27"));/* टेबल मैपर जॉब सेटअप करें */TableMapReduceUtil.initTableMapperJob(tablename,scan,DataScanMapper.class,ImmutableBytesWritable.class, KeyValue.class,job, true, TableInputFormat.class);…

हालांकि, नमकीन पूर्व-विभाजित तालिकाओं के लिए ऐसी नौकरी की स्थापना चुनौतीपूर्ण हो जाती है। प्रत्येक क्षेत्र के लिए प्रारंभ और बंद पंक्ति कुंजियाँ भिन्न होंगी क्योंकि प्रत्येक में एक अद्वितीय नमक होता है। और हम एक Scan . के लिए कई रेंज निर्दिष्ट नहीं कर सकते हैं उदाहरण।

इस समस्या को हल करने के लिए, हमें यह देखना होगा कि MapReduce तालिका कैसे काम करती है। आम तौर पर, MapReduce ढांचा प्रत्येक इनपुट विभाजन को पढ़ने और संसाधित करने के लिए एक मानचित्र कार्य बनाता है। प्रत्येक विभाजन InputFormat . में उत्पन्न होता है वर्ग आधार, विधि द्वारा getSplits()

HBase तालिका MapReduce नौकरी में, TableInputFormat InputFormat . के रूप में प्रयोग किया जाता है . कार्यान्वयन के अंदर, getSplits() Scan . से प्रारंभ और रोक पंक्ति कुंजियों को पुनः प्राप्त करने के लिए विधि को ओवरराइड किया गया है उदाहरण। चूंकि स्टार्ट और स्टॉप पंक्ति कुंजियाँ कई क्षेत्रों में फैली हुई हैं, इसलिए सीमा क्षेत्र की सीमाओं से विभाजित होती है और TableSplit की सूची लौटाती है ऑब्जेक्ट जो स्कैन कुंजी श्रेणी को कवर करता है। HDFS ब्लॉक पर आधारित होने के बजाय, TableSplit क्षेत्र पर आधारित हैं। getSplits() . को ओवरराइट करके विधि, हम TableSplit . को नियंत्रित करने में सक्षम हैं ।

कस्टम TableInputFormat का निर्माण

getSplits() . के व्यवहार को बदलने के लिए विधि, एक कस्टम वर्ग जो TableInputFormat का विस्तार कर रहा है आवश्यक है। getSplits() . का उद्देश्य यहाँ प्रत्येक क्षेत्र में तार्किक कुंजी श्रेणी को कवर करना है, उनके अद्वितीय नमक के साथ उनकी पंक्ति कुंजी श्रेणी का निर्माण करना है। HTable वर्ग विधि प्रदान करता है getStartEndKeys() जो प्रत्येक क्षेत्र के लिए प्रारंभ और समाप्ति पंक्ति कुंजियाँ देता है। प्रत्येक प्रारंभ कुंजी से, क्षेत्र के लिए संबंधित नमक को पार्स करें।

जोड़ी कुंजी =table.getStartEndKeys();के लिए (int i =0; i  

जॉब कॉन्फ़िगरेशन लॉजिकल की रेंज पास करता है

TableInputFormat Scan . से स्टार्ट और स्टॉप की को पुनः प्राप्त करता है उदाहरण। चूंकि हम Scan . का उपयोग नहीं कर सकते हैं हमारे MapReduce कार्य में, हम Configuration . का उपयोग कर सकते हैं इसके बजाय इन दो चरों को पारित करने के लिए और केवल तार्किक प्रारंभ और स्टॉप कुंजी पर्याप्त है (एक चर एक तिथि या अन्य व्यावसायिक जानकारी हो सकती है)। getSplits() विधि में JobContext है तर्क, कॉन्फ़िगरेशन इंस्टेंस को context.getConfiguration() . के रूप में पढ़ा जा सकता है ।

MapReduce ड्राइवर में:

कॉन्फ़िगरेशन कॉन्फ़ =getConf();conf =HBaseConfiguration.addHbaseResources(conf);conf.set("logical.scan.start", "2015-04-26");conf.set("logical.scan.stop ", "2015-04-27");

Custom TableInputFormat . में :

@Override सार्वजनिक सूची getSplits(JobContext प्रसंग) IOException फेंकता है {conf =context.getConfiguration();String scanStart =conf.get("logical.scan.start");String scanStop =conf.get("logical.scan .stop");…}

क्षेत्र के अनुसार नमकीन कुंजी श्रेणी का पुनर्निर्माण करें

अब जबकि हमारे पास प्रत्येक क्षेत्र के लिए नमक और तार्किक स्टार्ट/स्टॉप कुंजी है, हम वास्तविक पंक्ति कुंजी श्रेणी का पुनर्निर्माण कर सकते हैं।

byte[] startRowKey =Bytes.toBytes(regionSalt + "|" + scanStart);byte[] endRowKey =Bytes.toBytes(regionSalt + "|" + scanStop);

हर क्षेत्र के लिए टेबलस्प्लिट बनाना

पंक्ति कुंजी श्रेणी के साथ, अब हम TableSplit . को इनिशियलाइज़ कर सकते हैं क्षेत्र के लिए उदाहरण।

सूची विभाजन =नया ArrayList(keys.getFirst().length); for (int i =0; i  

देखने के लिए एक और चीज डेटा इलाके है। फ़्रेमवर्क अपने स्थानीय होस्ट में मैप टास्क असाइन करने के लिए प्रत्येक इनपुट स्प्लिट में स्थान की जानकारी का उपयोग करता है। हमारे TableInputFormat . के लिए , हम विधि का उपयोग करते हैं getTableRegionLocation() पंक्ति कुंजी परोसने वाले क्षेत्र के स्थान को पुनः प्राप्त करने के लिए।

इसके बाद यह स्थान TableSplit . को भेज दिया जाता है निर्माता। यह आश्वस्त करेगा कि तालिका विभाजन को संसाधित करने वाला मैपर उसी क्षेत्र सर्वर पर है। एक विधि, जिसे DNS.reverseDns() . कहा जाता है , HBase नाम सर्वर के लिए पते की आवश्यकता है। यह विशेषता कॉन्फ़िगरेशन में संग्रहीत है "hbase.nameserver.address ".

this.nameServer =Reference.getConfiguration().get("hbase.nameserver.address", null);…public String getTableRegionLocation(HTable table, byte[] rowKey) IOException को फेंकता है {HServerAddress RegionServerAddress =table.getRegionLocation(rowKey) ).getServerAddress();InetAddress RegionAddress =RegionServerAddress.getInetSocketAddress().getAddress();स्ट्रिंग क्षेत्रस्थान;कोशिश {regionLocation =reverseDNS(regionAddress);} पकड़ें (नामकरण अपवाद ई) {regionLocation =RegionServerAddress.getHostname();}रिटर्न रीजनलोकेशन; }संरक्षित स्ट्रिंग रिवर्स डीएनएस (InetAddress ipAddress) नेमिंग एक्सेप्शन फेंकता है {स्ट्रिंग होस्टनाम =this.reverseDNSCacheMap.get (ipAddress); यदि (होस्टनाम ==शून्य) {होस्टनाम =स्ट्रिंग्स. .reverseDNSCacheMap.put(ipAddress, hostName);}होस्टनाम लौटाएं;}

getSplits . का पूरा कोड इस तरह दिखेगा:

@Override सार्वजनिक सूची getSplits(JobContext प्रसंग) IOException फेंकता है {conf =context.getConfiguration();table =getHTable(conf);if (तालिका ==शून्य) {नया IOException फेंकें ("कोई तालिका प्रदान नहीं की गई थी।");}// नाम सर्वर पता प्राप्त करें और डिफ़ॉल्ट मान शून्य है।;स्ट्रिंग स्कैनस्टॉप =conf.get("region.scan.stop");जोड़ी कुंजी =table.getStartEndKeys();if (keys ==null || keys.getFirst() ==null || keys.getFirst()। लम्बाई ==0) {फेंक नया रनटाइम अपवाद ("कम से कम एक क्षेत्र अपेक्षित है");} सूची विभाजन =नया ऐरेलिस्ट (कुंजी। getFirst ()। लंबाई); के लिए (int i =0; i  

MapReduce ड्राइवर में कस्टम TableInoutFormat का उपयोग करें

अब हमें TableInputFormat को बदलने की जरूरत है कस्टम बिल्ड के साथ क्लास जिसका उपयोग हमने टेबल MapReduce जॉब सेटअप के लिए किया था।

कॉन्फ़िगरेशन कॉन्फ़ =getConf (); कॉन्फ़ =HBaseConfiguration.addHbaseResources(conf);HTableInterface status_table =new HTable(conf, status_tablename);conf.set("logical.scan.start", "2015-04-26");conf.set("logic.scan.stop", "2015-04-27"); स्कैन स्कैन =नया स्कैन (); स्कैन.सेट कैशिंग (1000); स्कैन.सेट कैशब्लॉक्स (झूठा); स्कैन.सेटबैच (1000);scan.setMaxVersions(1);/* टेबल मैपर जॉब सेटअप करें 

कस्टम का दृष्टिकोण TableInputFormat HBase तालिकाओं के लिए एक कुशल और स्केलेबल स्कैन क्षमता प्रदान करता है जिसे संतुलित डेटा लोड के लिए नमक का उपयोग करने के लिए डिज़ाइन किया गया है। चूंकि स्कैन किसी भी असंबंधित पंक्ति कुंजियों को बायपास कर सकता है, भले ही तालिका कितनी भी बड़ी क्यों न हो, स्कैन की जटिलता केवल लक्ष्य डेटा के आकार तक ही सीमित है। अधिकांश उपयोग के मामलों में, यह तालिका के बढ़ने पर अपेक्षाकृत सुसंगत प्रसंस्करण समय की गारंटी दे सकता है।


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. स्पार्क शेल के साथ HBase पर स्पार्क

  2. Apache HBase में वास्तव में स्केलिंग कैसे काम करती है

  3. सीडीपी परिचालन डेटाबेस के लिए उच्च उपलब्धता (मल्टी-एजेड)

  4. कैसे करें:Apache HBase REST इंटरफ़ेस का उपयोग करें, भाग 3

  5. Hadoop पारिस्थितिकी तंत्र - Hadoop घटकों का परिचय