HBase बाट 3 पटकसम्म र HDFS बाट 5 पटकसम्म पढ्ने गति कसरी बढाउने

ठूलो डेटा संग काम गर्दा उच्च प्रदर्शन प्रमुख आवश्यकताहरु मध्ये एक हो। हामी, Sberbank मा डाटा लोडिङ व्यवस्थापनमा, हाम्रो Hadoop-आधारित डाटा क्लाउडमा लगभग सबै लेनदेनहरू पम्प गर्दैछौं र त्यसैले हामी साँच्चै ठूलो सूचना प्रवाहको साथ काम गरिरहेका छौं। स्वाभाविक रूपमा, हामी सधैं प्रदर्शन सुधार गर्ने तरिकाहरू खोजिरहेका छौं, र अब हामी तपाईंलाई कसरी RegionServer HBase र HDFS क्लाइन्ट प्याच गर्न व्यवस्थित गर्यौं भनेर बताउन चाहन्छौं, जसले पढ्ने सञ्चालनको गतिलाई उल्लेखनीय रूपमा बढाउन सम्भव बनायो।
HBase बाट 3 पटकसम्म र HDFS बाट 5 पटकसम्म पढ्ने गति कसरी बढाउने

जे होस्, सुधारहरूको सारमा जानु अघि, यो सीमितताहरूको बारेमा कुरा गर्न लायक छ जुन, सिद्धान्तमा, यदि तपाइँ HDD मा बस्नु भयो भने बाइपास गर्न सकिँदैन।

किन HDD र छिटो Random Access रिडहरू असंगत छन्
तपाईलाई थाहा छ, HBase, र धेरै अन्य डाटाबेसहरू, आकारमा धेरै दसौं किलोबाइटको ब्लकहरूमा डाटा भण्डारण गर्दछ। पूर्वनिर्धारित रूपमा, यो लगभग 64 KB हो। अब कल्पना गर्नुहोस् कि हामीले केवल 100 बाइटहरू प्राप्त गर्न आवश्यक छ र हामी HBase लाई निश्चित कुञ्जी प्रयोग गरेर हामीलाई यो डाटा दिनको लागि सोध्छौं। HFiles मा ब्लक साइज 64 KB भएकोले, अनुरोध आवश्यक भन्दा 640 गुणा ठूलो (केवल एक मिनेट!) हुनेछ।

यसबाहेक, अनुरोध HDFS र यसको मेटाडेटा क्यासिङ मेकानिजम मार्फत जानेछ ShortCircuitCache (जसले फाइलहरूमा प्रत्यक्ष पहुँच अनुमति दिन्छ), त्यसपछि यसले डिस्कबाट पहिले नै १ MB पढ्ने परिणाम दिन्छ। यद्यपि, यो प्यारामिटरको साथ समायोजन गर्न सकिन्छ dfs.client.read.shortcircuit.buffer.size र धेरै अवस्थामा यो मान घटाउनको लागि अर्थ हुन्छ, उदाहरणका लागि १२६ KB मा।

हामी यो गर्छौं भनौं, तर यसको अतिरिक्त, जब हामी FileChannel.read जस्ता कार्यहरू सहित java api मार्फत डेटा पढ्न थाल्छौं र अपरेटिङ सिस्टमलाई निर्दिष्ट मात्रामा डेटा पढ्न सोध्छौं, यसले "केसमा मात्र" २ गुणा बढी घटाउँछ। , अर्थात् हाम्रो मामला मा 2 KB मा। यो किनभने यो व्यवहार रोक्नको लागि FADV_RANDOM झण्डा सेट गर्न जाभामा कुनै सजिलो तरिका छैन।

नतिजाको रूपमा, हाम्रो 100 बाइटहरू प्राप्त गर्न, हुड अन्तर्गत 2600 गुणा बढी पढिन्छ। यस्तो देखिन्छ कि समाधान स्पष्ट छ, ब्लक साइजलाई किलोबाइटमा घटाउनुहोस्, उल्लेखित झण्डा सेट गर्नुहोस् र ठूलो प्रबुद्धता त्वरण प्राप्त गर्नुहोस्। तर समस्या यो छ कि ब्लक साइज २ पटक घटाएर, हामीले समयको प्रति एकाइ घटाउने बाइटको संख्या पनि २ पटक घटाउँछौं।

FADV_RANDOM झण्डा सेट गरेर केही लाभहरू प्राप्त गर्न सकिन्छ, तर केवल उच्च मल्टिथ्रेडिङ र 128 KB को ब्लक साइजको साथ, तर यो अधिकतम दश प्रतिशतको एक जोडी हो:

HBase बाट 3 पटकसम्म र HDFS बाट 5 पटकसम्म पढ्ने गति कसरी बढाउने

परीक्षणहरू 100 फाइलहरूमा गरिएको थियो, प्रत्येक 1 GB आकारमा र 10 HDD मा अवस्थित।

हामी आधारभूत रूपमा यस्तो गतिमा के गणना गर्न सक्छौं गणना गरौं:
मानौं हामी 10 MB / s को गतिमा 280 डिस्कबाट पढ्छौं, अर्थात्। 3 मिलियन पटक 100 बाइट। तर हामी सम्झन्छौं, हामीलाई पढेको भन्दा 2600 गुणा कम डेटा चाहिन्छ। यसरी, हामी 3 मिलियनलाई 2600 ले भाग गर्छौं र पाउँछौं 1100 रेकर्ड प्रति सेकेन्ड।

निराशाजनक, हैन? यस्तो प्रकृति हो अनियमित पहुँच HDD मा डाटा पहुँच - ब्लक आकार को परवाह बिना। यो अनियमित पहुँचको भौतिक सीमा हो, र कुनै पनि डाटाबेसले त्यस्ता अवस्थाहरूमा थप निचोड गर्न सक्दैन।

त्यसोभए आधारहरूले कसरी धेरै उच्च गति हासिल गर्न सक्छन्? यस प्रश्नको जवाफको लागि, निम्न चित्रमा के हुन्छ हेरौं:

HBase बाट 3 पटकसम्म र HDFS बाट 5 पटकसम्म पढ्ने गति कसरी बढाउने

यहाँ हामी देख्छौं कि पहिलो केहि मिनेट गति वास्तवमा प्रति सेकेन्ड एक हजार रेकर्ड छ। जे होस्, थप, अनुरोध गरिएको भन्दा धेरै घटाइएको तथ्यको कारणले गर्दा, डाटा अपरेटिङ सिस्टम (लिनक्स) को बफ / क्यासमा जम्मा गरिन्छ र गति प्रति सेकेन्ड अधिक सभ्य 60 हजारमा बढ्छ।

यसरी, हामी OS क्यासमा रहेको वा तुलनात्मक पहुँच गतिको SSD/NVMe भण्डारण यन्त्रहरूमा अवस्थित डाटामा मात्र पहुँच बढाउनेसँग सम्झौता गर्नेछौं।

हाम्रो अवस्थामा, हामी 4 सर्भरहरूको स्ट्यान्डमा परीक्षणहरू सञ्चालन गर्नेछौं, जसमध्ये प्रत्येकलाई निम्न रूपमा चार्ज गरिन्छ:

CPU: Xeon E5-2680 v4 @ 2.40GHz 64 थ्रेडहरू।
मेमोरी: 730 GB।
java संस्करण: 1.8.0_111

र यहाँ मुख्य बिन्दु भनेको तालिकाहरूमा डेटाको मात्रा हो जुन पढ्न आवश्यक छ। तथ्य यो हो कि यदि तपाइँ HBase क्यासमा पूर्ण रूपमा फिट हुने तालिकाबाट डाटा पढ्नुहुन्छ भने, यो अपरेटिङ सिस्टमको बफ / क्यासबाट पढ्न पनि आउँदैन। किनभने HBase पूर्वनिर्धारित रूपमा BlockCache भनिने संरचनामा मेमोरीको 40% आवंटित गर्दछ। वास्तवमा, यो एक ConcurrentHashMap हो, जहाँ कुञ्जी फाइल नाम + ब्लकको अफसेट हो, र यो अफसेटमा मान वास्तविक डेटा हो।

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

उदाहरण को लागी, हाम्रो मामला मा, एक RS मा BlockCache को भोल्युम लगभग 12 GB छ। हामीले एउटा नोडमा दुई RS ल्यायौं, अर्थात्। सबै नोडहरूमा BlockCache को लागि 96 GB छुट्याइएको छ। र एकै समयमा, त्यहाँ धेरै डेटा छ, उदाहरणका लागि, यसलाई 4 तालिकाहरू, प्रत्येक 130 क्षेत्रहरू, जसमा 800 एमबी आकारका फाइलहरू, FAST_DIFF द्वारा संकुचित, अर्थात्। कुल 410 GB (यो शुद्ध डाटा हो, अर्थात् प्रतिकृति कारकलाई ध्यान नदिई)।

यसरी, BlockCache कुल डाटाको लगभग 23% मात्र हो र यो BigData भनिने वास्तविक अवस्थाको धेरै नजिक छ। र यहाँ सबैभन्दा रोचक सुरु हुन्छ - सबै पछि, यो स्पष्ट छ कि कम क्यास हिट, खराब प्रदर्शन। आखिर, मिसको अवस्थामा, तपाईंले धेरै काम गर्नुपर्नेछ - अर्थात्। प्रणाली प्रकार्यहरू कल गर्नु अघि descend। जे होस्, यो बेवास्ता गर्न सकिँदैन, र त्यसैले हामी एक पूर्ण फरक पक्ष विचार गरौं - क्यास भित्र डाटा के हुन्छ?

परिस्थितिलाई सरल बनाउनुहोस् र हामीसँग एउटा क्यास छ जसमा केवल १ वस्तु राखिएको छ भनी मानौं। हामीले क्यास भन्दा ३ गुणा ठूलो डेटा भोल्युमसँग काम गर्ने प्रयास गर्दा के हुन्छ भन्ने उदाहरण यहाँ छ, हामीले गर्नुपर्नेछ:

१. क्यासमा ब्लक १ राख्नुहोस्
२. क्यासबाट ब्लक १ हटाउनुहोस्
१. क्यासमा ब्लक १ राख्नुहोस्
२. क्यासबाट ब्लक १ हटाउनुहोस्
१. क्यासमा ब्लक १ राख्नुहोस्

5 कार्यहरू गरियो! यद्यपि, यो अवस्थालाई सामान्य भन्न सकिँदैन, वास्तवमा, हामीले HBase लाई पूर्ण रूपमा बेकारको काम गर्न बाध्य पारिरहेका छौं। उसले लगातार OS क्यासबाट डाटा पढ्छ, यसलाई आफ्नो BlockCache मा राख्छ, यसलाई लगभग तुरुन्तै बाहिर फाल्नको लागि, किनभने डाटाको नयाँ भाग आएको छ। पोष्टको सुरुमा एनिमेसनले समस्याको सार देखाउँदछ - गार्बेज कलेक्टर चार्टबाट बाहिर छ, वातावरण न्यानो हुँदैछ, सानो ग्रेटा टाढा र तातो स्वीडेनमा विचलित हुँदैछ। र हामी IT मानिसहरूलाई बच्चाहरू दुखी हुँदा यो मनपर्दैन, त्यसैले हामी यसको बारेमा के गर्न सकिन्छ भनेर सोच्न थाल्छौं।

तर के यदि सबै ब्लकहरू क्यासमा राखिएका छैनन्, तर तिनीहरूको केवल एक निश्चित प्रतिशत, ताकि क्यास ओभरफ्लो हुँदैन? BlockCache पुश प्रकार्यको शीर्षमा कोडको केही लाइनहरू थपेर सुरु गरौं:

  public void cacheBlock(BlockCacheKey cacheKey, Cacheable buf, boolean inMemory) {
    if (cacheDataBlockPercent != 100 && buf.getBlockType().isData()) {
      if (cacheKey.getOffset() % 100 >= cacheDataBlockPercent) {
        return;
      }
    }
...

यहाँको अर्थ निम्न छ, अफसेट फाइलमा ब्लकको स्थिति हो र यसको अन्तिम अंकहरू अनियमित रूपमा र समान रूपमा 00 देखि 99 सम्म वितरित हुन्छन्। त्यसैले, हामीले आवश्यक दायरामा पर्नेहरूलाई मात्र छोड्नेछौं।

उदाहरण को लागी, cacheDataBlockPercent = 20 सेट गर्नुहोस् र के हुन्छ हेर्नुहोस्:

HBase बाट 3 पटकसम्म र HDFS बाट 5 पटकसम्म पढ्ने गति कसरी बढाउने

नतिजा त्यहाँ छ। तलका ग्राफहरूमा, यो प्रवेग किन भयो भन्ने कुरा स्पष्ट हुन्छ - हामीले क्यासमा डाटा राख्ने सिसिफियन श्रम नगरीकन GC स्रोतहरूको एक गुच्छा बचत गर्छौं मात्र यसलाई तुरुन्तै मार्टियन कुकुरहरूमा नालीमा फ्याँक्नका लागि:

HBase बाट 3 पटकसम्म र HDFS बाट 5 पटकसम्म पढ्ने गति कसरी बढाउने

एकै समयमा, CPU उपयोग बढ्छ, तर प्रदर्शन भन्दा धेरै कम:

HBase बाट 3 पटकसम्म र HDFS बाट 5 पटकसम्म पढ्ने गति कसरी बढाउने

यहाँ यो पनि ध्यान दिन लायक छ कि BlockCache मा भण्डारण गरिएका ब्लकहरू फरक छन्। धेरै जसो, लगभग 95%, डाटा आफै हो। र बाँकी मेटाडेटा हो, जस्तै ब्लूम फिल्टर वा LEAF_INDEX र आदि। यो डाटा पर्याप्त छैन, तर यो धेरै उपयोगी छ, किनकि डाटामा सिधै फर्कनु अघि, HBase ले मेटालाई बुझाउँछ कि यो यहाँ थप हेर्न आवश्यक छ कि छैन र यदि हो भने, वास्तवमा यसको रुचि को ब्लक कहाँ छ।

त्यसकारण, कोडमा हामी अवस्था जाँच देख्छौं buf.getBlockType().isData() र यस मेटाको लागि धन्यवाद हामी जे भए पनि क्यासमा राख्नेछौं।

अब लोड बढाउनुहोस् र एकै समयमा सुविधालाई थोरै ट्युन गरौं। पहिलो परीक्षणमा हामीले cutoff प्रतिशत = 20 बनायौं र BlockCache थोरै कम प्रयोग गरिएको थियो। अब यसलाई 23% मा सेट गरौं र कुन बिन्दुमा संतृप्ति हुन्छ हेर्न प्रत्येक 100 मिनेटमा 5 थ्रेडहरू थपौं:

HBase बाट 3 पटकसम्म र HDFS बाट 5 पटकसम्म पढ्ने गति कसरी बढाउने

यहाँ हामी देख्छौं कि मूल संस्करण लगभग तुरुन्तै प्रति सेकेन्ड लगभग 100 हजार अनुरोधहरूमा छतमा हिट हुन्छ। जबकि प्याचले 300 हजार सम्मको गति दिन्छ। एकै समयमा, यो स्पष्ट छ कि थप प्रवेग अब "नि: शुल्क" छैन, जबकि CPU उपयोग पनि बढ्दै छ।

जे होस्, यो एक धेरै सुरुचिपूर्ण समाधान होइन, किनकी हामीलाई ब्लकको प्रतिशत क्यास गर्ने पहिले नै थाहा छैन, यो लोड प्रोफाइलमा निर्भर गर्दछ। तसर्थ, पढ्ने अपरेसनहरूको गतिविधिको आधारमा स्वचालित रूपमा यो प्यारामिटर समायोजन गर्न एक संयन्त्र लागू गरिएको थियो।

यसलाई नियन्त्रण गर्न तीन विकल्पहरू थपिएका छन्:

hbase.lru.cache.heavy.eviction.count.limit — हामीले अप्टिमाइजेसन (अर्थात् ब्लकहरू स्किपिङ) प्रयोग गर्न सुरु गर्नु अघि क्यासबाट डाटा बेदखल गर्ने प्रक्रिया कति पटक चल्नु पर्छ भनेर सेट गर्छ। पूर्वनिर्धारित रूपमा यो MAX_INT = 2147483647 बराबर हुन्छ र वास्तवमा यसको मतलब यो मानसँग सुविधाले कहिल्यै काम गर्न थाल्दैन। किनभने निष्कासन प्रक्रिया प्रत्येक 5 - 10 सेकेन्डमा सुरु हुन्छ (यो लोडमा निर्भर गर्दछ) र 2147483647 * 10 / 60 / 60 / 24 / 365 = 680 वर्ष। यद्यपि, हामी यो प्यारामिटरलाई ० मा सेट गर्न सक्छौं र लन्च पछि तुरुन्तै सुविधा काम गर्न सक्छौं।

यद्यपि, यस प्यारामिटरमा पेलोड पनि छ। यदि हामीसँग लोडको प्रकृति यस्तो छ कि छोटो-अवधि पढाइहरू (दिनमा भनौं) र लामो-अवधि पढाइहरू (रातमा) निरन्तर अन्तरसम्बन्धित हुन्छन्, तब हामी दीर्घकालीन पढ्ने अपरेशनहरू हुँदा मात्र सुविधा सक्रिय गर्न सक्छौं। प्रगति हुदैछ।

उदाहरणका लागि, हामीलाई थाहा छ कि छोटो-अवधि पढाइहरू सामान्यतया लगभग 1 मिनेटको हुन्छ। त्यहाँ ब्लकहरू फ्याँक्न सुरु गर्न आवश्यक छैन, क्यास अप्रचलित हुन समय हुनेछैन, र त्यसपछि हामी यो प्यारामिटर सेट गर्न सक्छौं, उदाहरणका लागि, 10। यसले यो तथ्यलाई नेतृत्व गर्नेछ कि अप्टिमाइजेसनले लामो समयसम्म सक्रिय पढ्दा मात्र काम गर्न थाल्छ। सुरु भएको छ, म। 100 सेकेन्ड पछि। तसर्थ, यदि हामीसँग छोटो-अवधि पढ्ने छ भने, त्यसपछि सबै ब्लकहरू क्यासमा आउनेछन् र उपलब्ध हुनेछन् (मानक एल्गोरिथ्मद्वारा निष्कासित गरिने बाहेक)। र जब हामी लामो-अवधि पढ्छौं, सुविधा सक्रिय हुन्छ र हामीसँग धेरै राम्रो प्रदर्शन हुनेछ।

hbase.lru.cache.heavy.eviction.mb.size.limit - 10 सेकेन्डमा हामी कति मेगाबाइटहरू क्यास (र स्वाभाविक रूपमा बेदखल) मा राख्न चाहन्छौं सेट गर्दछ। सुविधाले यो मानमा पुग्न र यसलाई कायम राख्न प्रयास गर्नेछ। बिन्दु यो हो, यदि हामीले क्यासमा गीगाबाइटहरू खसाल्यौं भने, गीगाबाइटहरू हटाउनु पर्छ, र यो, हामीले माथि देख्यौं, धेरै महँगो छ। यद्यपि, तपाईंले यसलाई धेरै सानो सेट गर्ने प्रयास गर्नुहुँदैन, किनकि यसले ब्लक स्किपिङ मोडबाट समयभन्दा पहिले बाहिर निस्कनेछ। शक्तिशाली सर्भरहरूका लागि (लगभग 20-40 भौतिक कोर), लगभग 300-400 MB सेट गर्न इष्टतम छ। मध्यम वर्गका लागि (~ १० कोर) २००-३०० एमबी। कमजोर प्रणालीहरूको लागि (10-200 कोर), 300-2 MB सामान्य हुन सक्छ (यस्ता प्रणालीहरूमा परीक्षण गरिएको छैन)।

यो कसरी काम गर्छ हेरौं: मानौं हामीले hbase.lru.cache.heavy.eviction.mb.size.limit = 500 सेट गर्छौं, त्यहाँ केही प्रकारको लोड (पढ्ने) छ र त्यसपछि प्रत्येक ~10 सेकेन्डमा हामीले गणना गर्छौं कि कति बाइटहरू थिए। सूत्र प्रयोग गरेर निष्कासन:

ओभरहेड = फ्री बाइट्स योग (एमबी) * 100 / सीमा (एमबी) - 100;

यदि वास्तवमा 2000 MB बेदखल गरिएको थियो, तब ओभरहेड बराबर हुन्छ:

2000 * 100 / 500 - 100 = 300%

एल्गोरिदमहरूले केही दशौं प्रतिशत भन्दा बढी समर्थन गर्ने प्रयास गर्दैन, त्यसैले सुविधाले क्यास ब्लकहरूको प्रतिशत घटाउनेछ, जसले गर्दा स्वत: ट्युनिङ मेकानिजम लागू हुन्छ।

यद्यपि, यदि लोड घटेको छ भने, मानौं कि 200 MB मात्र बेदखल गरिएको छ र ओभरहेड नकारात्मक हुन्छ (तथाकथित ओभरशुटिंग):

200 * 100 / 500 - 100 = -60%

त्यो सुविधा, यसको विपरित, ओभरहेड सकारात्मक नभएसम्म क्यास ब्लकहरूको प्रतिशत बढाउनेछ।

तल यो वास्तविक डेटामा कस्तो देखिन्छ भन्ने उदाहरण हो। ०% पुग्न प्रयास गर्न आवश्यक छैन, यो असम्भव छ। यो धेरै राम्रो छ जब यो लगभग 0 - 30% छ, यसले छोटो अवधिको फटको समयमा अनुकूलन मोडबाट समय भन्दा पहिले बाहिर निस्कनबाट बच्न मद्दत गर्दछ।

hbase.lru.cache.heavy.eviction.overhead.coefficient - हामी नतिजा कति छिटो प्राप्त गर्न चाहन्छौं सेट गर्दछ। यदि हामीलाई पक्का थाहा छ कि हाम्रा पढाइहरू प्रायः लामो हुन्छन् र पर्खन चाहँदैनन् भने, हामी यो अनुपात बढाउन सक्छौं र छिटो उच्च प्रदर्शन प्राप्त गर्न सक्छौं।

उदाहरणका लागि, हामीले यो गुणांक = ०.०१ सेट गर्छौं। यसको मतलब ओभरहेड (माथि हेर्नुहोस्) यो संख्याले परिणामद्वारा गुणन गरिनेछ र क्यास गरिएका ब्लकहरूको प्रतिशत घटाइनेछ। मानौं कि ओभरहेड = 0.01%, र गुणांक = 300, त्यसपछि क्यास ब्लकहरूको प्रतिशत 0.01% ले घटाइनेछ।

एक समान "ब्याकप्रेसर" तर्क ओभरहेड (ओभरशूटिंग) को नकारात्मक मानहरूको लागि पनि लागू गरिएको छ। पढ्ने र निष्कासनको मात्रामा छोटो-अवधिको उतार-चढाव सधैं सम्भव भएकोले, यो संयन्त्रले तपाईंलाई अप्टिमाइजेसन मोडबाट समयपूर्व निस्कनबाट बच्न अनुमति दिन्छ। ब्याकप्रेसरको उल्टो तर्क हुन्छ: ओभरसुटिंग जति बलियो हुन्छ, त्यति नै धेरै ब्लकहरू क्यास हुन्छन्।

HBase बाट 3 पटकसम्म र HDFS बाट 5 पटकसम्म पढ्ने गति कसरी बढाउने

कार्यान्वयन कोड

        LruBlockCache cache = this.cache.get();
        if (cache == null) {
          break;
        }
        freedSumMb += cache.evict()/1024/1024;
        /*
        * Sometimes we are reading more data than can fit into BlockCache
        * and it is the cause a high rate of evictions.
        * This in turn leads to heavy Garbage Collector works.
        * So a lot of blocks put into BlockCache but never read,
        * but spending a lot of CPU resources.
        * Here we will analyze how many bytes were freed and decide
        * decide whether the time has come to reduce amount of caching blocks.
        * It help avoid put too many blocks into BlockCache
        * when evict() works very active and save CPU for other jobs.
        * More delails: https://issues.apache.org/jira/browse/HBASE-23887
        */

        // First of all we have to control how much time
        // has passed since previuos evict() was launched
        // This is should be almost the same time (+/- 10s)
        // because we get comparable volumes of freed bytes each time.
        // 10s because this is default period to run evict() (see above this.wait)
        long stopTime = System.currentTimeMillis();
        if ((stopTime - startTime) > 1000 * 10 - 1) {
          // Here we have to calc what situation we have got.
          // We have the limit "hbase.lru.cache.heavy.eviction.bytes.size.limit"
          // and can calculte overhead on it.
          // We will use this information to decide,
          // how to change percent of caching blocks.
          freedDataOverheadPercent =
            (int) (freedSumMb * 100 / cache.heavyEvictionMbSizeLimit) - 100;
          if (freedSumMb > cache.heavyEvictionMbSizeLimit) {
            // Now we are in the situation when we are above the limit
            // But maybe we are going to ignore it because it will end quite soon
            heavyEvictionCount++;
            if (heavyEvictionCount > cache.heavyEvictionCountLimit) {
              // It is going for a long time and we have to reduce of caching
              // blocks now. So we calculate here how many blocks we want to skip.
              // It depends on:
             // 1. Overhead - if overhead is big we could more aggressive
              // reducing amount of caching blocks.
              // 2. How fast we want to get the result. If we know that our
              // heavy reading for a long time, we don't want to wait and can
              // increase the coefficient and get good performance quite soon.
              // But if we don't sure we can do it slowly and it could prevent
              // premature exit from this mode. So, when the coefficient is
              // higher we can get better performance when heavy reading is stable.
              // But when reading is changing we can adjust to it and set
              // the coefficient to lower value.
              int change =
                (int) (freedDataOverheadPercent * cache.heavyEvictionOverheadCoefficient);
              // But practice shows that 15% of reducing is quite enough.
              // We are not greedy (it could lead to premature exit).
              change = Math.min(15, change);
              change = Math.max(0, change); // I think it will never happen but check for sure
              // So this is the key point, here we are reducing % of caching blocks
              cache.cacheDataBlockPercent -= change;
              // If we go down too deep we have to stop here, 1% any way should be.
              cache.cacheDataBlockPercent = Math.max(1, cache.cacheDataBlockPercent);
            }
          } else {
            // Well, we have got overshooting.
            // Mayby it is just short-term fluctuation and we can stay in this mode.
            // It help avoid permature exit during short-term fluctuation.
            // If overshooting less than 90%, we will try to increase the percent of
            // caching blocks and hope it is enough.
            if (freedSumMb >= cache.heavyEvictionMbSizeLimit * 0.1) {
              // Simple logic: more overshooting - more caching blocks (backpressure)
              int change = (int) (-freedDataOverheadPercent * 0.1 + 1);
              cache.cacheDataBlockPercent += change;
              // But it can't be more then 100%, so check it.
              cache.cacheDataBlockPercent = Math.min(100, cache.cacheDataBlockPercent);
            } else {
              // Looks like heavy reading is over.
              // Just exit form this mode.
              heavyEvictionCount = 0;
              cache.cacheDataBlockPercent = 100;
            }
          }
          LOG.info("BlockCache evicted (MB): {}, overhead (%): {}, " +
            "heavy eviction counter: {}, " +
            "current caching DataBlock (%): {}",
            freedSumMb, freedDataOverheadPercent,
            heavyEvictionCount, cache.cacheDataBlockPercent);

          freedSumMb = 0;
          startTime = stopTime;
       }

अब यी सबैलाई वास्तविक उदाहरणमा विचार गर्नुहोस्। हामीसँग निम्न परीक्षण परिदृश्य छ:

  1. स्क्यान गर्न सुरु गर्नुहोस् (25 थ्रेड, ब्याच = 100)
  2. 5 मिनेट पछि, मल्टि-गेट्स थप्नुहोस् (25 थ्रेडहरू, ब्याच = 100)
  3. 5 मिनेट पछि, बहु-गेट्स बन्द गर्नुहोस् (केवल स्क्यान मात्र बाँकी छ)

हामी दुई रन गर्छौं, पहिले hbase.lru.cache.heavy.eviction.count.limit = 10000 (जसले वास्तवमा सुविधालाई असक्षम पार्छ), र त्यसपछि सीमा = 0 सेट गर्नुहोस् (सक्षम गर्दछ)।

तलका लगहरूमा, हामी देख्छौं कि कसरी सुविधा सक्रिय हुन्छ, ओभरशुटिंगलाई 14-71% मा रिसेट गर्छ। समय-समयमा लोड घट्छ, जसले ब्याकप्रेसरलाई सक्रिय गर्दछ र HBase फेरि थप ब्लकहरू क्यास गर्दछ।

लग RegionServer
बेदखल गरिएको (MB): ०, अनुपात ०.०, ओभरहेड (%): -१००, भारी निष्कासन काउन्टर: ०, हालको क्यासिङ डाटाब्लक (%): १००
बेदखल गरिएको (MB): ०, अनुपात ०.०, ओभरहेड (%): -१००, भारी निष्कासन काउन्टर: ०, हालको क्यासिङ डाटाब्लक (%): १००
बेदखल (MB): 2170, अनुपात 1.09, ओभरहेड (%): 985, भारी निष्कासन काउन्टर: 1, वर्तमान क्यासिङ डाटाब्लक (%): 91 < सुरु
निष्कासित (MB): 3763, अनुपात 1.08, ओभरहेड (%): 1781, भारी निष्कासन काउन्टर: 2, वर्तमान क्यासिङ डाटाब्लक (%): 76
निष्कासित (MB): 3306, अनुपात 1.07, ओभरहेड (%): 1553, भारी निष्कासन काउन्टर: 3, वर्तमान क्यासिङ डाटाब्लक (%): 61
निष्कासित (MB): 2508, अनुपात 1.06, ओभरहेड (%): 1154, भारी निष्कासन काउन्टर: 4, वर्तमान क्यासिङ डाटाब्लक (%): 50
निष्कासित (MB): 1824, अनुपात 1.04, ओभरहेड (%): 812, भारी निष्कासन काउन्टर: 5, वर्तमान क्यासिङ डाटाब्लक (%): 42
निष्कासित (MB): 1482, अनुपात 1.03, ओभरहेड (%): 641, भारी निष्कासन काउन्टर: 6, वर्तमान क्यासिङ डाटाब्लक (%): 36
निष्कासित (MB): 1140, अनुपात 1.01, ओभरहेड (%): 470, भारी निष्कासन काउन्टर: 7, वर्तमान क्यासिङ डाटाब्लक (%): 32
निष्कासित (MB): 913, अनुपात 1.0, ओभरहेड (%): 356, भारी निष्कासन काउन्टर: 8, वर्तमान क्यासिङ डाटाब्लक (%): 29
निष्कासित (MB): 912, अनुपात 0.89, ओभरहेड (%): 356, भारी निष्कासन काउन्टर: 9, वर्तमान क्यासिङ डाटाब्लक (%): 26
निष्कासित (MB): 684, अनुपात 0.76, ओभरहेड (%): 242, भारी निष्कासन काउन्टर: 10, वर्तमान क्यासिङ डाटाब्लक (%): 24
निष्कासित (MB): 684, अनुपात 0.61, ओभरहेड (%): 242, भारी निष्कासन काउन्टर: 11, वर्तमान क्यासिङ डाटाब्लक (%): 22
निष्कासित (MB): 456, अनुपात 0.51, ओभरहेड (%): 128, भारी निष्कासन काउन्टर: 12, वर्तमान क्यासिङ डाटाब्लक (%): 21
निष्कासित (MB): 456, अनुपात 0.42, ओभरहेड (%): 128, भारी निष्कासन काउन्टर: 13, वर्तमान क्यासिङ डाटाब्लक (%): 20
निष्कासित (MB): 456, अनुपात 0.33, ओभरहेड (%): 128, भारी निष्कासन काउन्टर: 14, वर्तमान क्यासिङ डाटाब्लक (%): 19
निष्कासित (MB): 342, अनुपात 0.33, ओभरहेड (%): 71, भारी निष्कासन काउन्टर: 15, वर्तमान क्यासिङ डाटाब्लक (%): 19
निष्कासित (MB): 342, अनुपात 0.32, ओभरहेड (%): 71, भारी निष्कासन काउन्टर: 16, वर्तमान क्यासिङ डाटाब्लक (%): 19
निष्कासित (MB): 342, अनुपात 0.31, ओभरहेड (%): 71, भारी निष्कासन काउन्टर: 17, वर्तमान क्यासिङ डाटाब्लक (%): 19
निष्कासित (MB): 228, अनुपात 0.3, ओभरहेड (%): 14, भारी निष्कासन काउन्टर: 18, वर्तमान क्यासिङ डाटाब्लक (%): 19
निष्कासित (MB): 228, अनुपात 0.29, ओभरहेड (%): 14, भारी निष्कासन काउन्टर: 19, वर्तमान क्यासिङ डाटाब्लक (%): 19
निष्कासित (MB): 228, अनुपात 0.27, ओभरहेड (%): 14, भारी निष्कासन काउन्टर: 20, वर्तमान क्यासिङ डाटाब्लक (%): 19
निष्कासित (MB): 228, अनुपात 0.25, ओभरहेड (%): 14, भारी निष्कासन काउन्टर: 21, वर्तमान क्यासिङ डाटाब्लक (%): 19
निष्कासित (MB): 228, अनुपात 0.24, ओभरहेड (%): 14, भारी निष्कासन काउन्टर: 22, वर्तमान क्यासिङ डाटाब्लक (%): 19
निष्कासित (MB): 228, अनुपात 0.22, ओभरहेड (%): 14, भारी निष्कासन काउन्टर: 23, वर्तमान क्यासिङ डाटाब्लक (%): 19
निष्कासित (MB): 228, अनुपात 0.21, ओभरहेड (%): 14, भारी निष्कासन काउन्टर: 24, वर्तमान क्यासिङ डाटाब्लक (%): 19
निष्कासित (MB): 228, अनुपात 0.2, ओभरहेड (%): 14, भारी निष्कासन काउन्टर: 25, वर्तमान क्यासिङ डाटाब्लक (%): 19
निष्कासित (MB): 228, अनुपात 0.17, ओभरहेड (%): 14, भारी निष्कासन काउन्टर: 26, वर्तमान क्यासिङ डाटाब्लक (%): 19
बेदखल (MB): 456, अनुपात 0.17, ओभरहेड (%): 128, भारी निष्कासन काउन्टर: 27, हालको क्यासिङ डाटाब्लक (%): 18 < थपिएको हुन्छ (तर तालिका उस्तै)
निष्कासित (MB): 456, अनुपात 0.15, ओभरहेड (%): 128, भारी निष्कासन काउन्टर: 28, वर्तमान क्यासिङ डाटाब्लक (%): 17
निष्कासित (MB): 342, अनुपात 0.13, ओभरहेड (%): 71, भारी निष्कासन काउन्टर: 29, वर्तमान क्यासिङ डाटाब्लक (%): 17
निष्कासित (MB): 342, अनुपात 0.11, ओभरहेड (%): 71, भारी निष्कासन काउन्टर: 30, वर्तमान क्यासिङ डाटाब्लक (%): 17
निष्कासित (MB): 342, अनुपात 0.09, ओभरहेड (%): 71, भारी निष्कासन काउन्टर: 31, वर्तमान क्यासिङ डाटाब्लक (%): 17
निष्कासित (MB): 228, अनुपात 0.08, ओभरहेड (%): 14, भारी निष्कासन काउन्टर: 32, वर्तमान क्यासिङ डाटाब्लक (%): 17
निष्कासित (MB): 228, अनुपात 0.07, ओभरहेड (%): 14, भारी निष्कासन काउन्टर: 33, वर्तमान क्यासिङ डाटाब्लक (%): 17
निष्कासित (MB): 228, अनुपात 0.06, ओभरहेड (%): 14, भारी निष्कासन काउन्टर: 34, वर्तमान क्यासिङ डाटाब्लक (%): 17
निष्कासित (MB): 228, अनुपात 0.05, ओभरहेड (%): 14, भारी निष्कासन काउन्टर: 35, वर्तमान क्यासिङ डाटाब्लक (%): 17
निष्कासित (MB): 228, अनुपात 0.05, ओभरहेड (%): 14, भारी निष्कासन काउन्टर: 36, वर्तमान क्यासिङ डाटाब्लक (%): 17
निष्कासित (MB): 228, अनुपात 0.04, ओभरहेड (%): 14, भारी निष्कासन काउन्टर: 37, वर्तमान क्यासिङ डाटाब्लक (%): 17
बेदखल (MB): 109, अनुपात 0.04, ओभरहेड (%): -46, भारी निष्कासन काउन्टर: 37, वर्तमान क्यासिङ डाटाब्लक (%): 22 < पछाडिको दबाव
निष्कासित (MB): 798, अनुपात 0.24, ओभरहेड (%): 299, भारी निष्कासन काउन्टर: 38, वर्तमान क्यासिङ डाटाब्लक (%): 20
निष्कासित (MB): 798, अनुपात 0.29, ओभरहेड (%): 299, भारी निष्कासन काउन्टर: 39, वर्तमान क्यासिङ डाटाब्लक (%): 18
निष्कासित (MB): 570, अनुपात 0.27, ओभरहेड (%): 185, भारी निष्कासन काउन्टर: 40, वर्तमान क्यासिङ डाटाब्लक (%): 17
निष्कासित (MB): 456, अनुपात 0.22, ओभरहेड (%): 128, भारी निष्कासन काउन्टर: 41, वर्तमान क्यासिङ डाटाब्लक (%): 16
निष्कासित (MB): 342, अनुपात 0.16, ओभरहेड (%): 71, भारी निष्कासन काउन्टर: 42, वर्तमान क्यासिङ डाटाब्लक (%): 16
निष्कासित (MB): 342, अनुपात 0.11, ओभरहेड (%): 71, भारी निष्कासन काउन्टर: 43, वर्तमान क्यासिङ डाटाब्लक (%): 16
निष्कासित (MB): 228, अनुपात 0.09, ओभरहेड (%): 14, भारी निष्कासन काउन्टर: 44, वर्तमान क्यासिङ डाटाब्लक (%): 16
निष्कासित (MB): 228, अनुपात 0.07, ओभरहेड (%): 14, भारी निष्कासन काउन्टर: 45, वर्तमान क्यासिङ डाटाब्लक (%): 16
निष्कासित (MB): 228, अनुपात 0.05, ओभरहेड (%): 14, भारी निष्कासन काउन्टर: 46, वर्तमान क्यासिङ डाटाब्लक (%): 16
निष्कासित (MB): 222, अनुपात 0.04, ओभरहेड (%): 11, भारी निष्कासन काउन्टर: 47, वर्तमान क्यासिङ डाटाब्लक (%): 16
बेदखल (MB): 104, अनुपात 0.03, ओभरहेड (%): -48, भारी निष्कासन काउन्टर: 47, वर्तमान क्यासिङ डाटाब्लक (%): 21 < अवरोध प्राप्त हुन्छ
निष्कासित (MB): 684, अनुपात 0.2, ओभरहेड (%): 242, भारी निष्कासन काउन्टर: 48, वर्तमान क्यासिङ डाटाब्लक (%): 19
निष्कासित (MB): 570, अनुपात 0.23, ओभरहेड (%): 185, भारी निष्कासन काउन्टर: 49, वर्तमान क्यासिङ डाटाब्लक (%): 18
निष्कासित (MB): 342, अनुपात 0.22, ओभरहेड (%): 71, भारी निष्कासन काउन्टर: 50, वर्तमान क्यासिङ डाटाब्लक (%): 18
निष्कासित (MB): 228, अनुपात 0.21, ओभरहेड (%): 14, भारी निष्कासन काउन्टर: 51, वर्तमान क्यासिङ डाटाब्लक (%): 18
निष्कासित (MB): 228, अनुपात 0.2, ओभरहेड (%): 14, भारी निष्कासन काउन्टर: 52, वर्तमान क्यासिङ डाटाब्लक (%): 18
निष्कासित (MB): 228, अनुपात 0.18, ओभरहेड (%): 14, भारी निष्कासन काउन्टर: 53, वर्तमान क्यासिङ डाटाब्लक (%): 18
निष्कासित (MB): 228, अनुपात 0.16, ओभरहेड (%): 14, भारी निष्कासन काउन्टर: 54, वर्तमान क्यासिङ डाटाब्लक (%): 18
निष्कासित (MB): 228, अनुपात 0.14, ओभरहेड (%): 14, भारी निष्कासन काउन्टर: 55, वर्तमान क्यासिङ डाटाब्लक (%): 18
बेदखल (MB): 112, अनुपात 0.14, ओभरहेड (%): -44, भारी निष्कासन काउन्टर: 55, वर्तमान क्यासिङ डाटाब्लक (%): 23 < पछाडिको दबाव
निष्कासित (MB): 456, अनुपात 0.26, ओभरहेड (%): 128, भारी निष्कासन काउन्टर: 56, वर्तमान क्यासिङ डाटाब्लक (%): 22
निष्कासित (MB): 342, अनुपात 0.31, ओभरहेड (%): 71, भारी निष्कासन काउन्टर: 57, वर्तमान क्यासिङ डाटाब्लक (%): 22
निष्कासित (MB): 342, अनुपात 0.33, ओभरहेड (%): 71, भारी निष्कासन काउन्टर: 58, वर्तमान क्यासिङ डाटाब्लक (%): 22
निष्कासित (MB): 342, अनुपात 0.33, ओभरहेड (%): 71, भारी निष्कासन काउन्टर: 59, वर्तमान क्यासिङ डाटाब्लक (%): 22
निष्कासित (MB): 342, अनुपात 0.33, ओभरहेड (%): 71, भारी निष्कासन काउन्टर: 60, वर्तमान क्यासिङ डाटाब्लक (%): 22
निष्कासित (MB): 342, अनुपात 0.33, ओभरहेड (%): 71, भारी निष्कासन काउन्टर: 61, वर्तमान क्यासिङ डाटाब्लक (%): 22
निष्कासित (MB): 342, अनुपात 0.33, ओभरहेड (%): 71, भारी निष्कासन काउन्टर: 62, वर्तमान क्यासिङ डाटाब्लक (%): 22
निष्कासित (MB): 342, अनुपात 0.33, ओभरहेड (%): 71, भारी निष्कासन काउन्टर: 63, वर्तमान क्यासिङ डाटाब्लक (%): 22
निष्कासित (MB): 342, अनुपात 0.32, ओभरहेड (%): 71, भारी निष्कासन काउन्टर: 64, वर्तमान क्यासिङ डाटाब्लक (%): 22
निष्कासित (MB): 342, अनुपात 0.33, ओभरहेड (%): 71, भारी निष्कासन काउन्टर: 65, वर्तमान क्यासिङ डाटाब्लक (%): 22
निष्कासित (MB): 342, अनुपात 0.33, ओभरहेड (%): 71, भारी निष्कासन काउन्टर: 66, वर्तमान क्यासिङ डाटाब्लक (%): 22
निष्कासित (MB): 342, अनुपात 0.32, ओभरहेड (%): 71, भारी निष्कासन काउन्टर: 67, वर्तमान क्यासिङ डाटाब्लक (%): 22
निष्कासित (MB): 342, अनुपात 0.33, ओभरहेड (%): 71, भारी निष्कासन काउन्टर: 68, वर्तमान क्यासिङ डाटाब्लक (%): 22
निष्कासित (MB): 342, अनुपात 0.32, ओभरहेड (%): 71, भारी निष्कासन काउन्टर: 69, वर्तमान क्यासिङ डाटाब्लक (%): 22
निष्कासित (MB): 342, अनुपात 0.32, ओभरहेड (%): 71, भारी निष्कासन काउन्टर: 70, वर्तमान क्यासिङ डाटाब्लक (%): 22
निष्कासित (MB): 342, अनुपात 0.33, ओभरहेड (%): 71, भारी निष्कासन काउन्टर: 71, वर्तमान क्यासिङ डाटाब्लक (%): 22
निष्कासित (MB): 342, अनुपात 0.33, ओभरहेड (%): 71, भारी निष्कासन काउन्टर: 72, वर्तमान क्यासिङ डाटाब्लक (%): 22
निष्कासित (MB): 342, अनुपात 0.33, ओभरहेड (%): 71, भारी निष्कासन काउन्टर: 73, वर्तमान क्यासिङ डाटाब्लक (%): 22
निष्कासित (MB): 342, अनुपात 0.33, ओभरहेड (%): 71, भारी निष्कासन काउन्टर: 74, वर्तमान क्यासिङ डाटाब्लक (%): 22
निष्कासित (MB): 342, अनुपात 0.33, ओभरहेड (%): 71, भारी निष्कासन काउन्टर: 75, वर्तमान क्यासिङ डाटाब्लक (%): 22
निष्कासित (MB): 342, अनुपात 0.33, ओभरहेड (%): 71, भारी निष्कासन काउन्टर: 76, वर्तमान क्यासिङ डाटाब्लक (%): 22
बेदखल गरिएको (MB): ०, अनुपात ०.०, ओभरहेड (%): -१००, भारी निष्कासन काउन्टर: ०, हालको क्यासिङ डाटाब्लक (%): १००
बेदखल गरिएको (MB): ०, अनुपात ०.०, ओभरहेड (%): -१००, भारी निष्कासन काउन्टर: ०, हालको क्यासिङ डाटाब्लक (%): १००
बेदखल गरिएको (MB): ०, अनुपात ०.०, ओभरहेड (%): -१००, भारी निष्कासन काउन्टर: ०, हालको क्यासिङ डाटाब्लक (%): १००

क्यासका दुई खण्डहरू बीचको सम्बन्धको ग्राफको रूपमा उही प्रक्रिया देखाउन स्क्यानहरू आवश्यक थियो - एकल (जहाँ ब्लकहरू जुन कसैले अहिलेसम्म अनुरोध गरेको छैन) र बहु ​​("अनुरोध गरिएको" डेटा कम्तिमा एक पटक। यहाँ भण्डारण गरिएको छ):

HBase बाट 3 पटकसम्म र HDFS बाट 5 पटकसम्म पढ्ने गति कसरी बढाउने

र अन्तमा, कसरी प्यारामिटरहरूले ग्राफको रूपमा काम गर्दछ। तुलनाको लागि, क्यास सुरुमा पूर्ण रूपमा बन्द गरिएको थियो, त्यसपछि त्यहाँ क्यासिङको साथ HBase को सुरुवात थियो र 5 मिनेट (30 बेदखल चक्र) द्वारा अप्टिमाइजेसन सुरुमा ढिलाइ भयो।

पूरा कोड पुल अनुरोधमा फेला पार्न सकिन्छ HBASE-23887 github मा।

यद्यपि, प्रति सेकेन्ड 300 हजार रिडहरू यी सर्तहरूमा यो हार्डवेयरमा निचोड गर्न सकिने सबै होइन। तथ्य यो हो कि जब तपाइँ HDFS मार्फत डेटा पहुँच गर्न आवश्यक छ, ShortCircuitCache (यसपछि SSC) संयन्त्र प्रयोग गरिन्छ, जसले तपाइँलाई नेटवर्क अन्तरक्रियाहरू बेवास्ता गर्दै, सीधा डाटा पहुँच गर्न अनुमति दिन्छ।

प्रोफाइलिङले देखाएको छ कि यद्यपि यो मेकानिज्मले ठूलो लाभ दिन्छ, यो पनि केहि बिन्दुमा एक बाधा बन्न सक्छ, किनकि लगभग सबै भारी अपरेशनहरू ताला भित्र हुन्छन्, जसले धेरैजसो समय अवरुद्ध हुन्छ।

HBase बाट 3 पटकसम्म र HDFS बाट 5 पटकसम्म पढ्ने गति कसरी बढाउने

यो महसुस गर्दै, हामीले महसुस गर्यौं कि स्वतन्त्र SSC को एर्रे सिर्जना गरेर समस्यालाई रोक्न सकिन्छ:

private final ShortCircuitCache[] shortCircuitCache;
...
shortCircuitCache = new ShortCircuitCache[this.clientShortCircuitNum];
for (int i = 0; i < this.clientShortCircuitNum; i++)
  this.shortCircuitCache[i] = new ShortCircuitCache(…);

र त्यसपछि तिनीहरूसँग काम गर्नुहोस्, अन्तिम अफसेट अंकहरूद्वारा प्रतिच्छेदहरू बाहेक:

public ShortCircuitCache getShortCircuitCache(long idx) {
    return shortCircuitCache[(int) (idx % clientShortCircuitNum)];
}

अब तपाईं परीक्षण सुरु गर्न सक्नुहुन्छ। यो गर्नको लागि, हामी साधारण बहु-थ्रेडेड अनुप्रयोगको साथ HDFS बाट फाइलहरू पढ्नेछौं। प्यारामिटरहरू सेट गर्नुहोस्:

conf.set("dfs.client.read.shortcircuit", "true");
conf.set("dfs.client.read.shortcircuit.buffer.size", "65536"); // по дефолту = 1 МБ и это сильно замедляет чтение, поэтому лучше привести в соответствие к реальным нуждам
conf.set("dfs.client.short.circuit.num", num); // от 1 до 10

र केवल फाइलहरू पढ्नुहोस्:

FSDataInputStream in = fileSystem.open(path);
for (int i = 0; i < count; i++) {
    position += 65536;
    if (position > 900000000)
        position = 0L;
    int res = in.read(position, byteBuffer, 0, 65536);
}

यो कोड अलग-अलग थ्रेडहरूमा कार्यान्वयन गरिएको छ र हामी एकैसाथ पढ्ने फाइलहरूको संख्या (१० देखि २०० - तेर्सो अक्षसम्म) र क्यासहरूको संख्या (१ देखि १० सम्म - ग्राफिक्स) वृद्धि गर्नेछौं। ठाडो अक्षले एउटा मात्र क्यास हुँदा SSC मा भएको वृद्धिले केसको सापेक्ष दिन्छ भन्ने प्रवेग देखाउँछ।

HBase बाट 3 पटकसम्म र HDFS बाट 5 पटकसम्म पढ्ने गति कसरी बढाउने

ग्राफ कसरी पढ्ने: एकल क्यासको साथ 100K ब्लकहरूमा 64k पढाइ पूरा हुन 78 सेकेन्ड लाग्छ। जबकि 5 क्यास संग यो 16 सेकेन्ड लाग्छ। ती। त्यहाँ ~ 5 पटक को एक प्रवेग छ। तपाईँले ग्राफबाट देख्न सक्नुहुन्छ, थोरै संख्यामा समानान्तर पढाइहरूमा, प्रभाव धेरै उल्लेखनीय छैन, थ्रेड रिडहरू 50 भन्दा बढी हुँदा यसले उल्लेखनीय भूमिका खेल्न थाल्छ। यो पनि उल्लेखनीय छ कि एसएससीहरूको संख्या बढ्दै गएको छ। 6 र माथिले उल्लेखनीय रूपमा कम प्रदर्शन लाभ दिन्छ।

नोट 1: परीक्षण परिणामहरू धेरै अस्थिर छन् (तल हेर्नुहोस्), 3 लन्चहरू गरियो र प्राप्त मानहरू औसत गरियो।

नोट 2: अनियमित पहुँच सेटिङबाट कार्यसम्पादन लाभ समान छ, यद्यपि पहुँच आफैंमा थोरै ढिलो छ।

यद्यपि, यो स्पष्ट हुनुपर्दछ कि, HBase को मामलाको विपरीत, यो प्रवेग सधैं निःशुल्क हुँदैन। यहाँ हामी लकहरूमा झुण्डिनुको सट्टा CPU को काम गर्ने क्षमतालाई "अनलक" गर्दैछौं।

HBase बाट 3 पटकसम्म र HDFS बाट 5 पटकसम्म पढ्ने गति कसरी बढाउने

यहाँ तपाईँले अवलोकन गर्न सक्नुहुन्छ, सामान्यतया, क्यासहरूको संख्यामा वृद्धिले CPU उपयोगमा लगभग समानुपातिक वृद्धि दिन्छ। यद्यपि, त्यहाँ धेरै विजयी संयोजनहरू छन्।

उदाहरणका लागि, SSC = 3 सेटिङमा नजिकबाट हेरौं। दायरामा प्रदर्शनमा वृद्धि लगभग 3.3 गुणा छ। तल सबै तीन अलग रन को नतिजा छन्।

HBase बाट 3 पटकसम्म र HDFS बाट 5 पटकसम्म पढ्ने गति कसरी बढाउने

जबकि CPU खपत लगभग 2.8 गुणा बढ्छ। भिन्नता धेरै ठूलो छैन, तर सानो ग्रेटा पहिले नै खुसी छ र सायद त्यहाँ स्कूल र पाठ उपस्थित हुन समय हुनेछ।

यसैले, यसले HDFS बल्क पहुँच (उदाहरणका लागि, स्पार्क, आदि) प्रयोग गर्ने कुनै पनि उपकरणमा सकारात्मक प्रभाव पार्छ, बशर्ते कि अनुप्रयोग कोड हल्का हो (अर्थात् HDFS क्लाइन्ट साइडमा प्लग गर्ने) र त्यहाँ निःशुल्क CPU पावर छ। जाँच गर्नको लागि, HBase बाट पढ्नको लागि BlockCache अप्टिमाइजेसन र ट्युनिङ SSC को संयुक्त प्रयोगले कस्तो प्रभाव पार्छ भनेर जाँच गरौं।

HBase बाट 3 पटकसम्म र HDFS बाट 5 पटकसम्म पढ्ने गति कसरी बढाउने

यो देख्न सकिन्छ कि त्यस्ता अवस्थाहरूमा प्रभाव परिष्कृत परीक्षणहरूमा जत्तिकै ठूलो हुँदैन (कुनै प्रशोधन बिना पढाइ), तर यहाँ थप 80K निचोड गर्न सम्भव छ। सँगै, दुबै अप्टिमाइजेसनले 4 पटकसम्म एक्सेलेरेशन दिन्छ।

यस अप्टिमाइजेसनको लागि PR पनि बनाइएको थियो [HDFS-15202], जुन मर्ज गरिएको छ र यो कार्यक्षमता भविष्यका रिलीजहरूमा उपलब्ध हुनेछ।

र अन्तमा, यो समान चौडा स्तम्भ डाटाबेस क्यासान्ड्रा र HBase को पढाइ प्रदर्शन तुलना गर्न रोचक थियो।

यो गर्नको लागि, मानक YCSB लोड परीक्षण उपयोगिताका उदाहरणहरू दुई होस्टहरू (कुल 800 थ्रेडहरू) बाट सुरु गरियो। सर्भर साइडमा - 4 होस्टहरूमा RegionServer र Cassandra को 4 उदाहरणहरू (जहाँ ग्राहकहरू तिनीहरूको प्रभावबाट बच्न दौडिरहेका छन्)। पढाइहरू आकारको तालिकाहरूबाट आयो:

HBase - HDFS मा 300 GB (100 GB कच्चा डाटा)

क्यासान्ड्रा - २५० जीबी (प्रतिकृति कारक = ३)

ती। भोल्युम लगभग उस्तै थियो (HBase मा अलि बढी)।

Hbase विकल्प:

dfs.client.short.circuit.num = 5 (HDFS ग्राहक अनुकूलन)

hbase.lru.cache.heavy.eviction.count.limit = ३० - यसको मतलब प्याचले 30 निष्कासन (~ 5 मिनेट) पछि काम गर्न सुरु गर्नेछ।

hbase.lru.cache.heavy.eviction.mb.size.limit = 300 - क्यासिङ र निष्कासन को लक्ष्य मात्रा

YCSB लगहरूलाई एक्सेल चार्टहरूमा पार्स र कम्पाइल गरिएको छ:

HBase बाट 3 पटकसम्म र HDFS बाट 5 पटकसम्म पढ्ने गति कसरी बढाउने

तपाईले देख्न सक्नुहुने रूपमा, अप्टिमाइजेसन डाटाले यी सर्तहरूमा यी डाटाबेसहरूको कार्यसम्पादनलाई बराबर गर्न र प्रति सेकेन्ड 450 रिडहरू प्राप्त गर्न सम्भव बनाउँदछ।

हामी आशा गर्दछौं कि यो जानकारी प्रदर्शनको लागि रोमाञ्चक संघर्षको क्रममा कसैको लागि उपयोगी हुन सक्छ।

स्रोत: www.habr.com

एक टिप्पणी थप्न