Kif iżżid il-veloċità tal-qari minn HBase sa 3 darbiet u minn HDFS sa 5 darbiet

Prestazzjoni għolja hija waħda mir-rekwiżiti ewlenin meta taħdem ma 'big data. Aħna, fil-ġestjoni tat-tagħbija tad-dejta fi Sberbank, qed nippumpjaw kważi t-tranżazzjonijiet kollha fil-Cloud tad-Data tagħna bbażat fuq Hadoop u għalhekk qed nittrattaw flussi ta 'informazzjoni verament kbar. Naturalment, aħna dejjem qed infittxu modi biex intejbu l-prestazzjoni, u issa rridu ngħidulek kif irnexxielna nirranġaw il-klijent RegionServer HBase u HDFS, li għamilha possibbli li tiżdied b'mod sinifikanti l-veloċità tal-operazzjoni tal-qari.
Kif iżżid il-veloċità tal-qari minn HBase sa 3 darbiet u minn HDFS sa 5 darbiet

Madankollu, qabel ma ngħaddi għall-essenza tat-titjib, ta 'min jitkellem dwar il-limitazzjonijiet li, fil-prinċipju, ma jistgħux jiġu evitati jekk inti toqgħod fuq l-HDD.

Għaliex l-HDD u l-Qari Fast Random Access Huma Inkompatibbli
Kif tafu, HBase, u ħafna databases oħra, jaħżnu d-dejta fi blokki ta 'diversi għexieren ta' kilobytes fid-daqs. B'mod awtomatiku, dan huwa madwar 64 KB. Issa immaġina li għandna bżonn niksbu biss 100 bytes u nitolbu lil HBase biex tagħtina din id-dejta billi tuża ċerta ċavetta. Peress li d-daqs tal-blokk f'HFiles huwa 64 KB, it-talba se tkun 640 darba akbar (għal minuta!) milli meħtieġ.

Barra minn hekk, peress li t-talba se tgħaddi mill-HDFS u l-mekkaniżmu tal-caching tal-metadejta tagħha ShortCircuitCache (li jippermetti aċċess dirett għall-fajls), allura dan jirriżulta fil-qari diġà 1 MB mid-diska. Madankollu, dan jista 'jiġi aġġustat bil-parametru dfs.client.read.shortcircuit.buffer.size u f'ħafna każijiet jagħmel sens li jitnaqqas dan il-valur, pereżempju għal 126 KB.

Ejja ngħidu li nagħmlu dan, iżda barra minn hekk, meta nibdew naqraw id-dejta permezz tal-java api, b'funzjonijiet bħal FileChannel.read u titlob lis-sistema operattiva biex taqra l-ammont speċifikat ta 'dejta, inaqqas "fil-każ" 2 darbiet aktar , i.e. 256 KB fil-każ tagħna. Dan għaliex m'hemm l-ebda mod faċli f'java biex tissettja l-bandiera FADV_RANDOM biex tevita din l-imġieba.

Bħala riżultat, biex tikseb il-100 bytes tagħna, jinqraw 2600 darba aktar taħt il-barnuża. Jidher li s-soluzzjoni hija ovvja, ejja nnaqqsu d-daqs tal-blokk għal kilobyte, issettja l-bandiera msemmija u niksbu aċċelerazzjoni kbira tal-illuminazzjoni. Iżda l-inkwiet huwa li billi nnaqqsu d-daqs tal-blokk b'2 darbiet, innaqqsu wkoll in-numru ta 'bytes mnaqqsa għal kull unità ta' ħin b'2 darbiet.

Jista' jinkiseb xi gwadann mill-issettjar tal-bandiera FADV_RANDOM, iżda biss b'multithreading għoli u b'daqs tal-blokk ta' 128 KB, iżda dan huwa massimu ta' ftit għexieren ta' fil-mija:

Kif iżżid il-veloċità tal-qari minn HBase sa 3 darbiet u minn HDFS sa 5 darbiet

It-testijiet saru fuq 100 fajl, kull 1 GB fid-daqs u li jinsabu fuq 10 HDDs.

Ejja nikkalkulaw fuq xiex nistgħu noqogħdu bażikament b'tali veloċità:
Ejja ngħidu li naqraw minn 10 diski b'veloċità ta '280 MB / s, i.e. 3 miljun darba 100 bytes. Imma kif niftakru, għandna bżonn dejta li hija 2600 darba inqas minn dak li jinqara. Għalhekk, naqsmu 3 miljun b'2600 u nġibu 1100 rekord kull sekonda.

Diżappuntanti, hux? Din hija n-natura Aċċess Każwali aċċess għad-data fuq l-HDD - irrispettivament mid-daqs tal-blokk. Dan huwa l-limitu fiżiku ta 'aċċess każwali u l-ebda database ma tista' tagħfas aktar taħt kundizzjonijiet bħal dawn.

Kif allura jistgħu l-bażijiet jiksbu veloċitajiet ferm ogħla? Biex twieġeb din il-mistoqsija, ejja naraw x'jiġri fl-istampa li ġejja:

Kif iżżid il-veloċità tal-qari minn HBase sa 3 darbiet u minn HDFS sa 5 darbiet

Hawnhekk naraw li l-ewwel ftit minuti l-veloċità hija verament madwar elf rekord kull sekonda. Madankollu, barra minn hekk, minħabba l-fatt li jitnaqqas ħafna aktar milli kien mitlub, id-dejta tiġi depożitata fil-buff / cache tas-sistema operattiva (linux) u l-veloċità tikber għal aktar deċenti 60 elf kull sekonda

Għalhekk, aktar se nittrattaw l-aċċess aċċellerat biss għad-dejta li tinsab fil-cache tal-OS jew li tinsab f'apparat ta 'ħażna SSD/NVMe ta' veloċità ta 'aċċess komparabbli.

Fil-każ tagħna, aħna se nwettqu testijiet fuq stand ta '4 servers, li kull wieħed minnhom huwa ċċarġjat kif ġej:

CPU: Xeon E5-2680 v4 @ 2.40GHz 64 ħajt.
Memorja: 730 GB.
verżjoni java: 1.8.0_111

U hawn il-punt ewlieni huwa l-ammont ta 'dejta fit-tabelli li jeħtieġ li jinqara. Il-fatt hu li jekk taqra data minn tabella li tidħol għal kollox fil-cache HBase, allura lanqas biss tasal għall-qari minn buff / cache tas-sistema operattiva. Minħabba li HBase awtomatikament jalloka 40% tal-memorja għal struttura msejħa BlockCache. Fil-fatt, dan huwa ConcurrentHashMap, fejn iċ-ċavetta hija l-isem tal-fajl + offset tal-blokk, u l-valur huwa d-dejta attwali f'dan l-offset.

Għalhekk, meta naqraw biss minn din l-istruttura, aħna ara veloċità kbira, bħal miljun talba kull sekonda. Imma ejja nimmaġinaw li ma nistgħux nagħtu mijiet ta 'gigabytes ta' memorja biss għall-bżonnijiet tad-database, minħabba li ħafna affarijiet utli oħra qed iduru fuq dawn is-servers.

Pereżempju, fil-każ tagħna, il-volum ta 'BlockCache fuq RS wieħed huwa ta' madwar 12 GB. Inżulna żewġ RS fuq nodu wieħed, i.e. 96 GB allokati għal BlockCache fuq in-nodi kollha. U fl-istess ħin, hemm ħafna aktar dejta, pereżempju, ħalliha tkun 4 tabelli, 130 reġjun kull wieħed, li fihom fajls ta 'daqs ta' 800 MB, ikkompressati minn FAST_DIFF, i.e. total ta '410 GB (din hija dejta pura, jiġifieri mingħajr ma jitqies il-fattur ta' replikazzjoni).

Għalhekk, BlockCache huwa biss madwar 23% tad-dejta totali u dan huwa ħafna eqreb tal-kundizzjonijiet reali ta 'dak li jissejjaħ BigData. U hawn jibda l-aktar interessanti - wara kollox, huwa ovvju li inqas ma jkun hemm hits tal-cache, iktar tkun agħar il-prestazzjoni. Wara kollox, f'każ ta' miss, ikollok tagħmel ħafna xogħol - i.e. jinżel qabel issejjaħ il-funzjonijiet tas-sistema. Madankollu, dan ma jistax jiġi evitat, u għalhekk ejja nikkunsidraw aspett kompletament differenti - x'jiġri mid-data ġewwa l-cache?

Ejja nissimplifikaw is-sitwazzjoni u nassumu li għandna cache li fiha jitqiegħed oġġett 1 biss. Hawn eżempju ta’ x’jiġri meta nippruvaw naħdmu b’volum ta’ dejta 3 darbiet akbar mill-cache, ikollna:

1. Poġġi blokk 1 fil-cache
2. Neħħi blokk 1 mill-cache
3. Poġġi blokk 2 fil-cache
4. Neħħi blokk 2 mill-cache
5. Poġġi blokk 3 fil-cache

5 azzjonijiet mitmuma! Madankollu, din is-sitwazzjoni ma tistax tissejjaħ normali; fil-fatt, qed inġegħlu lil HBase tagħmel mazz ta 'xogħol kompletament inutli. Huwa kontinwament jaqra dejta mill-cache tal-OS, ipoġġiha f'BlockCache, biss biex tarmiha kważi immedjatament minħabba li tkun waslet porzjon ġdid ta 'dejta. L-animazzjoni fil-bidu tal-post turi l-essenza tal-problema - Garbage Collector qed imur barra mill-iskala, l-atmosfera qed tissaħħan, iċ-ċkejkna Greta fl-Isvezja mbiegħda u sħuna qed titħawwad. U aħna n-nies tal-IT verament ma nħobbux meta t-tfal ikunu mdejqin, għalhekk nibdew naħsbu dwar x’nistgħu nagħmlu dwaru.

Imma x'jiġri jekk mhux il-blokki kollha jitqiegħdu fil-cache, iżda ċertu persentaġġ minnhom biss, sabiex il-cache ma tfur? Ejja nibdew billi nżidu biss ftit linji ta' kodiċi fil-quċċata tal-funzjoni push BlockCache:

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

It-tifsira hawnhekk hija din li ġejja, offset hija l-pożizzjoni tal-blokka fil-fajl u l-aħħar ċifri tagħha huma mqassma b'mod każwali u indaqs minn 00 sa 99. Għalhekk, aħna se naqbżu biss dawk li jaqgħu fil-medda li għandna bżonn.

Pereżempju, issettja cacheDataBlockPercent = 20 u ara x'jiġri:

Kif iżżid il-veloċità tal-qari minn HBase sa 3 darbiet u minn HDFS sa 5 darbiet

Ir-riżultat qiegħed hemm. Fil-grafiċi hawn taħt, jidher ċar għaliex seħħet din l-aċċelerazzjoni - aħna niffrankaw mazz ta 'riżorsi GC mingħajr ma nagħmlu x-xogħol ta' Sisyphean li npoġġu d-dejta fil-cache biss biex immedjatament titfagħha fil-fossa fuq il-klieb Martian:

Kif iżżid il-veloċità tal-qari minn HBase sa 3 darbiet u minn HDFS sa 5 darbiet

Fl-istess ħin, l-użu tas-CPU jikber, iżda ħafna inqas mill-prestazzjoni:

Kif iżżid il-veloċità tal-qari minn HBase sa 3 darbiet u minn HDFS sa 5 darbiet

Ta 'min jinnota wkoll li l-blokki maħżuna fi BlockCache huma differenti. Il-biċċa l-kbira, madwar 95%, hija data nfisha. U l-bqija hija metadata, bħal filtri Bloom jew LEAF_INDEX u т.д.. Din id-dejta mhix biżżejjed, iżda hija utli ħafna, għaliex qabel ma taċċessa d-dejta direttament, HBase idur għall-meta biex tifhem jekk huwiex meħtieġ li tfittex hawn aktar u, jekk iva, fejn jinsab eżattament il-blokk ta 'interess.

Għalhekk, fil-kodiċi naraw kundizzjoni ta 'kontroll buf.getBlockType().isData() u grazzi għal din il-meta se nżommu fil-cache xorta waħda.

Issa ejja nżidu t-tagħbija u fl-istess ħin tixgħel ftit il-karatteristika. Fl-ewwel test, għamilna l-perċentwal tal-qtugħ = 20 u BlockCache kien daqsxejn mgħobbi biżżejjed. Issa ejja nissettjawha għal 23% u żid 100 ħajt kull 5 minuti biex naraw meta sseħħ is-saturazzjoni:

Kif iżżid il-veloċità tal-qari minn HBase sa 3 darbiet u minn HDFS sa 5 darbiet

Hawnhekk naraw li l-verżjoni oriġinali kważi immedjatament tolqot il-limitu ta 'madwar 100 elf talba kull sekonda. Billi l-garża tagħti aċċelerazzjoni sa 300 elf. Fl-istess ħin, huwa ċar li aktar aċċelerazzjoni m'għadhiex daqshekk "ħielsa", filwaqt li l-utilizzazzjoni tas-CPU qed tikber ukoll.

Madankollu, din mhix soluzzjoni eleganti ħafna, peress li ma nafux minn qabel liema perċentwal ta 'blokki għall-cache, jiddependi fuq il-profil tat-tagħbija. Għalhekk, ġie implimentat mekkaniżmu biex jaġġusta awtomatikament dan il-parametru skont l-attività tal-operazzjonijiet tal-qari.

Tliet għażliet ġew miżjuda biex jikkontrollaw dan:

hbase.lru.cache.heavy.eviction.count.limit - tistabbilixxi kemm-il darba l-proċess ta 'tkeċċija tad-dejta mill-cache għandu jibda qabel ma nibdew nużaw l-ottimizzazzjoni (jiġifieri skip blocks). B'mod awtomatiku, huwa ugwali għal MAX_INT = 2147483647 u fil-fatt ifisser li l-karatteristika qatt mhi se tibda taħdem b'dan il-valur. Minħabba li l-proċess ta 'żgumbrament jibda kull 5 - 10 sekondi (jiddependi fuq it-tagħbija) u 2147483647 * 10 / 60 / 60 / 24 / 365 = 680 sena. Madankollu, nistgħu nissettjaw dan il-parametru għal 0 u nagħmlu l-karatteristika taħdem immedjatament wara l-bidu.

Madankollu, hemm ukoll tagħbija f'dan il-parametru. Jekk ikollna n-natura tat-tagħbija b'tali mod li qari għal żmien qasir (ejja ngħidu matul il-jum) u qari fit-tul (bil-lejl) huma kontinwament imxerrda, allura nistgħu nagħmlu l-karatteristika tinxtegħel biss meta operazzjonijiet ta 'qari fit-tul huma fil-progress.

Pereżempju, nafu li l-qari għal żmien qasir normalment idum madwar minuta. M'hemmx bżonn li tibda tarmi l-blokki, il-cache mhux se jkollu ħin biex isir skadut u allura nistgħu nissettjaw dan il-parametru ugwali għal, pereżempju, 1. Dan iwassal għall-fatt li l-ottimizzazzjoni tibda taħdem biss meta twil- il-qari attiv tat-terminu beda, i.e. wara 10 sekonda. Għalhekk, jekk ikollna qari għal żmien qasir, allura l-blokki kollha jidħlu fil-cache u jkunu disponibbli (ħlief għal dawk li se jiġu żgumbrati mill-algoritmu standard). U meta nagħmlu qari fit-tul, il-karatteristika tinxtegħel u jkollna prestazzjoni ferm ogħla.

hbase.lru.cache.heavy.eviction.mb.size.limit - tissettja kemm nixtiequ npoġġu megabytes fil-cache (u naturalment tkeċċi) f'10 sekondi. Il-karatteristika se tipprova tilħaq dan il-valur u żżommu. Il-punt huwa dan: jekk nidħlu gigabytes fil-cache, allura jkollna nkeċċu gigabytes, u dan, kif rajna hawn fuq, jiswa ħafna flus. Madankollu, m'għandekx tipprova tissettjaha żgħira wisq, peress li dan iwassal għal ħruġ prematur mill-mod ta 'jaqbeż il-blokk. Għal servers b'saħħithom (madwar 20-40 qlub fiżiċi), huwa ottimali li jiġu stabbiliti madwar 300-400 MB. Għall-klassi tan-nofs (~ 10 cores) 200-300 MB. Għal sistemi dgħajfa (2-5 qlub) 50-100 MB jistgħu jkunu normali (mhux ittestjati fuq dawn).

Ejja nħarsu lejn kif jaħdem dan: ejja ngħidu li nissettjaw hbase.lru.cache.heavy.eviction.mb.size.limit = 500, hemm xi tip ta' tagħbija (qari) u mbagħad kull ~10 sekondi nikkalkulaw kemm kien hemm bytes żgumbrat bl-użu tal-formula:

Overhead = Somm ta' Bytes Meħlusa (MB) * 100 / Limitu (MB) - 100;

Jekk fil-fatt 2000 MB ġew żgumbrati, allura Overhead hija ugwali għal:

2000 * 100 / 500 - 100 = 300%

L-algoritmi jippruvaw jappoġġjaw mhux aktar minn ftit għexieren ta 'mija, għalhekk il-karatteristika tnaqqas il-perċentwal ta' blokki fil-cache, u b'hekk timplimenta l-mekkaniżmu ta 'rfinar awtomatiku.

Madankollu, jekk it-tagħbija tinżel, ejja ngħidu li 200 MB biss jiġu żgumbrati u Overhead isir negattiv (l-hekk imsejjaħ overshooting):

200 * 100 / 500 - 100 = -60%

Għall-kuntrarju, il-karatteristika se żżid il-persentaġġ ta 'blokki fil-cache sakemm Overhead isir pożittiv.

Hawn taħt hemm eżempju ta 'kif dan jidher fuq data reali. M'hemmx bżonn li tipprova tilħaq 0%, huwa impossibbli. Huwa tajjeb ħafna meta jkun ta 'madwar 30 - 100%, dan jgħin biex jiġi evitat ħruġ prematur mill-mod ta' ottimizzazzjoni waqt żidiet f'terminu qasir.

hbase.lru.cache.heavy.eviction.overhead.coefficient - tistabbilixxi kemm nixtiequ nġibu r-riżultat malajr. Jekk nafu żgur li l-qari tagħna huma l-aktar twal u ma rridux nistennew, nistgħu nżidu dan il-proporzjon u niksbu prestazzjoni għolja aktar malajr.

Pereżempju, aħna nissettjaw dan il-koeffiċjent = 0.01. Dan ifisser li Overhead (ara hawn fuq) se jiġi mmultiplikat b'dan in-numru bir-riżultat u l-perċentwal ta 'blokki cache se jitnaqqas. Ejja ngħidu li Overhead = 300%, u l-koeffiċjent = 0.01, allura l-persentaġġ ta 'blokki cache se jitnaqqas bi 3%.

Loġika simili ta '"Kontropressjoni" hija implimentata wkoll għal valuri negattivi ta' Overhead (overshooting). Peress li l-varjazzjonijiet għal żmien qasir fil-volum ta 'qari u żgumbramenti huma dejjem possibbli, dan il-mekkaniżmu jippermettilek tevita ħruġ prematur mill-mod ta' ottimizzazzjoni. Il-kontropressjoni għandha loġika maqluba: iktar ma tkun b'saħħitha l-overshooting, aktar blokki jiġu miżmumin fil-cache.

Kif iżżid il-veloċità tal-qari minn HBase sa 3 darbiet u minn HDFS sa 5 darbiet

Kodiċi ta' implimentazzjoni

        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;
       }

Ikkunsidra issa dan kollu fuq eżempju reali. Għandna x-xenarju tat-test li ġej:

  1. Ibda tagħmel Scan (25 ħajta, lott = 100)
  2. Wara 5 minuti, żid multi-gets (25 ħajta, lott = 100)
  3. Wara 5 minuti, itfi l-multi-gets (reġa' jibqa' biss scan)

Nagħmlu żewġ ġirjiet, l-ewwel hbase.lru.cache.heavy.eviction.count.limit = 10000 (li fil-fatt tiddiżattiva l-karatteristika), u mbagħad issettja limitu = 0 (jippermetti).

Fir-zkuk hawn taħt naraw kif il-karatteristika tinxtegħel u tirreset Overshooting għal 14-71%. Minn żmien għal żmien it-tagħbija tinżel, li tixgħel il-Backpressure u l-HBase jaqbad aktar blokki mill-ġdid.

Log tar-Reġjun Server
żgumbrat (MB): 0, proporzjon 0.0, overhead (%): -100, counter ta 'żgumbrament tqil: 0, caching kurrenti DataBlock (%): 100
żgumbrat (MB): 0, proporzjon 0.0, overhead (%): -100, counter ta 'żgumbrament tqil: 0, caching kurrenti DataBlock (%): 100
żgumbrat (MB): 2170, proporzjon 1.09, overhead (%): 985, counter ta 'żgumbrament tqil: 1, caching kurrenti DataBlock (%): 91 < bidu
żgumbrat (MB): 3763, proporzjon 1.08, overhead (%): 1781, counter ta 'żgumbrament tqil: 2, caching kurrenti DataBlock (%): 76
żgumbrat (MB): 3306, proporzjon 1.07, overhead (%): 1553, counter ta 'żgumbrament tqil: 3, caching kurrenti DataBlock (%): 61
żgumbrat (MB): 2508, proporzjon 1.06, overhead (%): 1154, counter ta 'żgumbrament tqil: 4, caching kurrenti DataBlock (%): 50
żgumbrat (MB): 1824, proporzjon 1.04, overhead (%): 812, counter ta 'żgumbrament tqil: 5, caching kurrenti DataBlock (%): 42
żgumbrat (MB): 1482, proporzjon 1.03, overhead (%): 641, counter ta 'żgumbrament tqil: 6, caching kurrenti DataBlock (%): 36
żgumbrat (MB): 1140, proporzjon 1.01, overhead (%): 470, counter ta 'żgumbrament tqil: 7, caching kurrenti DataBlock (%): 32
żgumbrat (MB): 913, proporzjon 1.0, overhead (%): 356, counter ta 'żgumbrament tqil: 8, caching kurrenti DataBlock (%): 29
żgumbrat (MB): 912, proporzjon 0.89, overhead (%): 356, counter ta 'żgumbrament tqil: 9, caching kurrenti DataBlock (%): 26
żgumbrat (MB): 684, proporzjon 0.76, overhead (%): 242, counter ta 'żgumbrament tqil: 10, caching kurrenti DataBlock (%): 24
żgumbrat (MB): 684, proporzjon 0.61, overhead (%): 242, counter ta 'żgumbrament tqil: 11, caching kurrenti DataBlock (%): 22
żgumbrat (MB): 456, proporzjon 0.51, overhead (%): 128, counter ta 'żgumbrament tqil: 12, caching kurrenti DataBlock (%): 21
żgumbrat (MB): 456, proporzjon 0.42, overhead (%): 128, counter ta 'żgumbrament tqil: 13, caching kurrenti DataBlock (%): 20
żgumbrat (MB): 456, proporzjon 0.33, overhead (%): 128, counter ta 'żgumbrament tqil: 14, caching kurrenti DataBlock (%): 19
żgumbrat (MB): 342, proporzjon 0.33, overhead (%): 71, counter ta 'żgumbrament tqil: 15, caching kurrenti DataBlock (%): 19
żgumbrat (MB): 342, proporzjon 0.32, overhead (%): 71, counter ta 'żgumbrament tqil: 16, caching kurrenti DataBlock (%): 19
żgumbrat (MB): 342, proporzjon 0.31, overhead (%): 71, counter ta 'żgumbrament tqil: 17, caching kurrenti DataBlock (%): 19
żgumbrat (MB): 228, proporzjon 0.3, overhead (%): 14, counter ta 'żgumbrament tqil: 18, caching kurrenti DataBlock (%): 19
żgumbrat (MB): 228, proporzjon 0.29, overhead (%): 14, counter ta 'żgumbrament tqil: 19, caching kurrenti DataBlock (%): 19
żgumbrat (MB): 228, proporzjon 0.27, overhead (%): 14, counter ta 'żgumbrament tqil: 20, caching kurrenti DataBlock (%): 19
żgumbrat (MB): 228, proporzjon 0.25, overhead (%): 14, counter ta 'żgumbrament tqil: 21, caching kurrenti DataBlock (%): 19
żgumbrat (MB): 228, proporzjon 0.24, overhead (%): 14, counter ta 'żgumbrament tqil: 22, caching kurrenti DataBlock (%): 19
żgumbrat (MB): 228, proporzjon 0.22, overhead (%): 14, counter ta 'żgumbrament tqil: 23, caching kurrenti DataBlock (%): 19
żgumbrat (MB): 228, proporzjon 0.21, overhead (%): 14, counter ta 'żgumbrament tqil: 24, caching kurrenti DataBlock (%): 19
żgumbrat (MB): 228, proporzjon 0.2, overhead (%): 14, counter ta 'żgumbrament tqil: 25, caching kurrenti DataBlock (%): 19
żgumbrat (MB): 228, proporzjon 0.17, overhead (%): 14, counter ta 'żgumbrament tqil: 26, caching kurrenti DataBlock (%): 19
żgumbrat (MB): 456, proporzjon 0.17, overhead (%): 128, counter ta 'żgumbrament tqil: 27, caching kurrenti DataBlock (%): 18 < miżjud gets (iżda tabella l-istess)
żgumbrat (MB): 456, proporzjon 0.15, overhead (%): 128, counter ta 'żgumbrament tqil: 28, caching kurrenti DataBlock (%): 17
żgumbrat (MB): 342, proporzjon 0.13, overhead (%): 71, counter ta 'żgumbrament tqil: 29, caching kurrenti DataBlock (%): 17
żgumbrat (MB): 342, proporzjon 0.11, overhead (%): 71, counter ta 'żgumbrament tqil: 30, caching kurrenti DataBlock (%): 17
żgumbrat (MB): 342, proporzjon 0.09, overhead (%): 71, counter ta 'żgumbrament tqil: 31, caching kurrenti DataBlock (%): 17
żgumbrat (MB): 228, proporzjon 0.08, overhead (%): 14, counter ta 'żgumbrament tqil: 32, caching kurrenti DataBlock (%): 17
żgumbrat (MB): 228, proporzjon 0.07, overhead (%): 14, counter ta 'żgumbrament tqil: 33, caching kurrenti DataBlock (%): 17
żgumbrat (MB): 228, proporzjon 0.06, overhead (%): 14, counter ta 'żgumbrament tqil: 34, caching kurrenti DataBlock (%): 17
żgumbrat (MB): 228, proporzjon 0.05, overhead (%): 14, counter ta 'żgumbrament tqil: 35, caching kurrenti DataBlock (%): 17
żgumbrat (MB): 228, proporzjon 0.05, overhead (%): 14, counter ta 'żgumbrament tqil: 36, caching kurrenti DataBlock (%): 17
żgumbrat (MB): 228, proporzjon 0.04, overhead (%): 14, counter ta 'żgumbrament tqil: 37, caching kurrenti DataBlock (%): 17
żgumbrat (MB): 109, proporzjon 0.04, overhead (%): -46, counter ta 'żgumbrament tqil: 37, caching kurrenti DataBlock (%): 22 < pressjoni lura
żgumbrat (MB): 798, proporzjon 0.24, overhead (%): 299, counter ta 'żgumbrament tqil: 38, caching kurrenti DataBlock (%): 20
żgumbrat (MB): 798, proporzjon 0.29, overhead (%): 299, counter ta 'żgumbrament tqil: 39, caching kurrenti DataBlock (%): 18
żgumbrat (MB): 570, proporzjon 0.27, overhead (%): 185, counter ta 'żgumbrament tqil: 40, caching kurrenti DataBlock (%): 17
żgumbrat (MB): 456, proporzjon 0.22, overhead (%): 128, counter ta 'żgumbrament tqil: 41, caching kurrenti DataBlock (%): 16
żgumbrat (MB): 342, proporzjon 0.16, overhead (%): 71, counter ta 'żgumbrament tqil: 42, caching kurrenti DataBlock (%): 16
żgumbrat (MB): 342, proporzjon 0.11, overhead (%): 71, counter ta 'żgumbrament tqil: 43, caching kurrenti DataBlock (%): 16
żgumbrat (MB): 228, proporzjon 0.09, overhead (%): 14, counter ta 'żgumbrament tqil: 44, caching kurrenti DataBlock (%): 16
żgumbrat (MB): 228, proporzjon 0.07, overhead (%): 14, counter ta 'żgumbrament tqil: 45, caching kurrenti DataBlock (%): 16
żgumbrat (MB): 228, proporzjon 0.05, overhead (%): 14, counter ta 'żgumbrament tqil: 46, caching kurrenti DataBlock (%): 16
żgumbrat (MB): 222, proporzjon 0.04, overhead (%): 11, counter ta 'żgumbrament tqil: 47, caching kurrenti DataBlock (%): 16
żgumbrat (MB): 104, proporzjon 0.03, overhead (%): -48, counter ta 'żgumbrament tqil: 47, caching kurrenti DataBlock (%): 21 < interrupt gets
żgumbrat (MB): 684, proporzjon 0.2, overhead (%): 242, counter ta 'żgumbrament tqil: 48, caching kurrenti DataBlock (%): 19
żgumbrat (MB): 570, proporzjon 0.23, overhead (%): 185, counter ta 'żgumbrament tqil: 49, caching kurrenti DataBlock (%): 18
żgumbrat (MB): 342, proporzjon 0.22, overhead (%): 71, counter ta 'żgumbrament tqil: 50, caching kurrenti DataBlock (%): 18
żgumbrat (MB): 228, proporzjon 0.21, overhead (%): 14, counter ta 'żgumbrament tqil: 51, caching kurrenti DataBlock (%): 18
żgumbrat (MB): 228, proporzjon 0.2, overhead (%): 14, counter ta 'żgumbrament tqil: 52, caching kurrenti DataBlock (%): 18
żgumbrat (MB): 228, proporzjon 0.18, overhead (%): 14, counter ta 'żgumbrament tqil: 53, caching kurrenti DataBlock (%): 18
żgumbrat (MB): 228, proporzjon 0.16, overhead (%): 14, counter ta 'żgumbrament tqil: 54, caching kurrenti DataBlock (%): 18
żgumbrat (MB): 228, proporzjon 0.14, overhead (%): 14, counter ta 'żgumbrament tqil: 55, caching kurrenti DataBlock (%): 18
żgumbrat (MB): 112, proporzjon 0.14, overhead (%): -44, counter ta 'żgumbrament tqil: 55, caching kurrenti DataBlock (%): 23 < pressjoni lura
żgumbrat (MB): 456, proporzjon 0.26, overhead (%): 128, counter ta 'żgumbrament tqil: 56, caching kurrenti DataBlock (%): 22
żgumbrat (MB): 342, proporzjon 0.31, overhead (%): 71, counter ta 'żgumbrament tqil: 57, caching kurrenti DataBlock (%): 22
żgumbrat (MB): 342, proporzjon 0.33, overhead (%): 71, counter ta 'żgumbrament tqil: 58, caching kurrenti DataBlock (%): 22
żgumbrat (MB): 342, proporzjon 0.33, overhead (%): 71, counter ta 'żgumbrament tqil: 59, caching kurrenti DataBlock (%): 22
żgumbrat (MB): 342, proporzjon 0.33, overhead (%): 71, counter ta 'żgumbrament tqil: 60, caching kurrenti DataBlock (%): 22
żgumbrat (MB): 342, proporzjon 0.33, overhead (%): 71, counter ta 'żgumbrament tqil: 61, caching kurrenti DataBlock (%): 22
żgumbrat (MB): 342, proporzjon 0.33, overhead (%): 71, counter ta 'żgumbrament tqil: 62, caching kurrenti DataBlock (%): 22
żgumbrat (MB): 342, proporzjon 0.33, overhead (%): 71, counter ta 'żgumbrament tqil: 63, caching kurrenti DataBlock (%): 22
żgumbrat (MB): 342, proporzjon 0.32, overhead (%): 71, counter ta 'żgumbrament tqil: 64, caching kurrenti DataBlock (%): 22
żgumbrat (MB): 342, proporzjon 0.33, overhead (%): 71, counter ta 'żgumbrament tqil: 65, caching kurrenti DataBlock (%): 22
żgumbrat (MB): 342, proporzjon 0.33, overhead (%): 71, counter ta 'żgumbrament tqil: 66, caching kurrenti DataBlock (%): 22
żgumbrat (MB): 342, proporzjon 0.32, overhead (%): 71, counter ta 'żgumbrament tqil: 67, caching kurrenti DataBlock (%): 22
żgumbrat (MB): 342, proporzjon 0.33, overhead (%): 71, counter ta 'żgumbrament tqil: 68, caching kurrenti DataBlock (%): 22
żgumbrat (MB): 342, proporzjon 0.32, overhead (%): 71, counter ta 'żgumbrament tqil: 69, caching kurrenti DataBlock (%): 22
żgumbrat (MB): 342, proporzjon 0.32, overhead (%): 71, counter ta 'żgumbrament tqil: 70, caching kurrenti DataBlock (%): 22
żgumbrat (MB): 342, proporzjon 0.33, overhead (%): 71, counter ta 'żgumbrament tqil: 71, caching kurrenti DataBlock (%): 22
żgumbrat (MB): 342, proporzjon 0.33, overhead (%): 71, counter ta 'żgumbrament tqil: 72, caching kurrenti DataBlock (%): 22
żgumbrat (MB): 342, proporzjon 0.33, overhead (%): 71, counter ta 'żgumbrament tqil: 73, caching kurrenti DataBlock (%): 22
żgumbrat (MB): 342, proporzjon 0.33, overhead (%): 71, counter ta 'żgumbrament tqil: 74, caching kurrenti DataBlock (%): 22
żgumbrat (MB): 342, proporzjon 0.33, overhead (%): 71, counter ta 'żgumbrament tqil: 75, caching kurrenti DataBlock (%): 22
żgumbrat (MB): 342, proporzjon 0.33, overhead (%): 71, counter ta 'żgumbrament tqil: 76, caching kurrenti DataBlock (%): 22
żgumbrat (MB): 21, proporzjon 0.33, overhead (%): -90, counter ta 'żgumbrament tqil: 76, caching kurrenti DataBlock (%): 32
żgumbrat (MB): 0, proporzjon 0.0, overhead (%): -100, counter ta 'żgumbrament tqil: 0, caching kurrenti DataBlock (%): 100
żgumbrat (MB): 0, proporzjon 0.0, overhead (%): -100, counter ta 'żgumbrament tqil: 0, caching kurrenti DataBlock (%): 100

L-iskans kienu meħtieġa sabiex juru l-istess proċess fil-forma ta 'graff tar-relazzjoni bejn żewġ sezzjonijiet tal-cache - single (fejn blokki li ħadd qatt ma talab s'issa) u multi (id-data "rikjesta" mill-inqas darba huma maħżuna hawn):

Kif iżżid il-veloċità tal-qari minn HBase sa 3 darbiet u minn HDFS sa 5 darbiet

U fl-aħħarnett, kif tidher l-operazzjoni tal-parametri fil-forma ta 'graff. Għal tqabbil, il-cache kienet mitfija kompletament fil-bidu, imbagħad HBase tnediet b'caching u ttardja l-bidu tax-xogħol ta 'ottimizzazzjoni b'5 minuti (30 ċiklu ta' żgumbrament).

Il-kodiċi sħiħ jista' jinstab f'Pull Request HBASE-23887 fuq github.

Madankollu, 300 elf qari kull sekonda mhuwiex dak kollu li jista 'jingħafas fuq dan il-hardware taħt dawn il-kundizzjonijiet. Il-fatt hu li meta jkollok bżonn taċċessa d-dejta permezz tal-HDFS, jintuża l-mekkaniżmu ShortCircuitCache (minn hawn 'il quddiem SSC), li jippermettilek taċċessa d-dejta direttament, u tevita l-interazzjonijiet tan-netwerk.

Il-profiling wera li għalkemm dan il-mekkaniżmu jagħti gwadann kbir, isir ukoll ostaklu f'xi punt, minħabba li kważi l-operazzjonijiet tqal kollha jseħħu ġewwa l-lock, li jwassal għal serraturi ħafna mill-ħin.

Kif iżżid il-veloċità tal-qari minn HBase sa 3 darbiet u minn HDFS sa 5 darbiet

Meta rrealizzajna dan, indunajna li l-problema tista 'tiġi evitata billi noħolqu firxa ta' SSCs indipendenti:

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

U mbagħad aħdem magħhom, esklużi l-intersezzjonijiet ukoll bl-aħħar ċifra tal-offset:

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

Issa tista 'tibda tittestja. Biex tagħmel dan, aħna se naqraw fajls minn HDFS b'applikazzjoni sempliċi b'ħafna kamini. Issettja l-parametri:

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

U aqra biss il-fajls:

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);
}

Dan il-kodiċi jiġi esegwit f'ħjut separati u se nżidu n-numru ta 'fajls li jinqraw simultanjament (minn 10 għal 200 - l-assi orizzontali) u n-numru ta' caches (minn 1 sa 10 - grafika). L-assi vertikali juri l-aċċelerazzjoni li ż-żieda fl-SSC tagħti relattiva għall-każ meta jkun hemm cache waħda biss.

Kif iżżid il-veloċità tal-qari minn HBase sa 3 darbiet u minn HDFS sa 5 darbiet

Kif taqra l-graff: 100k jaqra fi blokki 64K b'cache waħda tieħu 78 sekonda biex titlesta. Billi b'5 caches tieħu 16-il sekonda. Dawk. hemm aċċelerazzjoni ta '~5 darbiet. Kif tista 'tara mill-graff, fuq numru żgħir ta' qari paralleli, l-effett mhux notevoli ħafna, jibda jkollu rwol notevoli meta l-qari tal-ħajta huma aktar minn 50. Huwa wkoll notevoli li jiżdied in-numru ta 'SSCs minn 6 u 'l fuq jagħti gwadann ta' prestazzjoni ferm inqas.

Nota 1: peress li r-riżultati tat-test huma pjuttost volatili (ara hawn taħt), twettqu 3 tnedijiet u l-valuri miksuba ġew medjati.

Nota 2: Il-gwadann tal-prestazzjoni mill-issettjar tal-aċċess każwali huwa l-istess, għalkemm l-aċċess innifsu huwa kemmxejn aktar bil-mod.

Madankollu, għandu jiġi ċċarat li, b'differenza mill-każ b'HBase, din l-aċċelerazzjoni mhux dejjem hija ħielsa. Hawnhekk aħna aktar "nitilfu" l-abbiltà tas-CPU biex jagħmlu xogħol, minflok mdendlin fuq serraturi.

Kif iżżid il-veloċità tal-qari minn HBase sa 3 darbiet u minn HDFS sa 5 darbiet

Hawnhekk tista 'tara li b'mod ġenerali, żieda fin-numru ta' caches tagħti żieda bejn wieħed u ieħor proporzjonali fl-utilizzazzjoni tas-CPU. Madankollu, hemm kemmxejn aktar kombinazzjonijiet rebbieħa.

Pereżempju, ejja nagħtu ħarsa aktar mill-qrib lejn l-issettjar SSC = 3. Iż-żieda fil-prestazzjoni fuq il-medda hija madwar 3.3 darbiet. Hawn taħt jinsabu r-riżultati tat-tliet ġirjiet separati kollha.

Kif iżżid il-veloċità tal-qari minn HBase sa 3 darbiet u minn HDFS sa 5 darbiet

Billi l-konsum tas-CPU jikber b'madwar 2.8 darbiet. Id-differenza mhix kbira ħafna, imma ċ-ċkejkna Greta diġà hi kuntenta u forsi jkun hemm ħin biex tattendi l-iskola u l-lezzjonijiet.

Għalhekk, dan ikollu effett pożittiv fuq kwalunkwe għodda li tuża aċċess bl-ingrossa HDFS (per eżempju, Spark, eċċ.), sakemm il-kodiċi tal-applikazzjoni jkun ħafif (jiġifieri twaħħalha fuq in-naħa tal-klijent HDFS) u jkun hemm qawwa CPU b'xejn. Biex tiċċekkja, ejja nittestjaw x'effett se jagħti l-użu kkombinat tal-ottimizzazzjoni u l-irfinar ta 'SSC ta' BlockCache biex jinqara minn HBase.

Kif iżżid il-veloċità tal-qari minn HBase sa 3 darbiet u minn HDFS sa 5 darbiet

Wieħed jista 'jara li taħt kundizzjonijiet bħal dawn l-effett mhuwiex kbir daqs f'testijiet raffinati (qari mingħajr ebda ipproċessar), iżda huwa pjuttost possibbli li jingħafsu 80K addizzjonali hawn. Flimkien, iż-żewġ ottimizzazzjonijiet jipprovdu veloċità sa 4x.

Sar ukoll PR għal din l-ottimizzazzjoni [HDFS-15202], li ġiet magħquda u din il-funzjonalità se tkun disponibbli fir-rilaxxi futuri.

U fl-aħħarnett, kien interessanti li titqabbel il-prestazzjoni tal-qari ta 'database ta' kolonna wiesgħa simili, Cassandra u HBase.

Biex tagħmel dan, ġew imnedija każijiet tal-utilità standard tal-ittestjar tat-tagħbija YCSB minn żewġ hosts (800 ħajt b'kollox). Fuq in-naħa tas-server - 4 każijiet ta’ RegionServer u Cassandra fuq 4 hosts (mhux fejn il-klijenti qed jaħdmu biex jevitaw l-influwenza tagħhom). Il-qari ġie minn tabelli tad-daqs:

HBase - 300 GB fuq HDFS (100 GB dejta mhux ipproċessata)

Cassandra - 250 GB (fattur ta 'replikazzjoni = 3)

Dawk. il-volum kien bejn wieħed u ieħor l-istess (f'HBase ftit aktar).

Għażliet Hbase:

dfs.client.short.circuit.num = 5 (Ottimizzazzjoni tal-klijent HDFS)

hbase.lru.cache.heavy.eviction.count.limit = 30 - dan ifisser li l-garża se tibda taħdem wara 30 żgumbrament (~5 minuti)

hbase.lru.cache.heavy.eviction.mb.size.limit = 300 - volum mira ta' caching u żgumbrament

Iċ-zkuk tal-YCSB ġew analizzati u kkompilati fi graphs Excel:

Kif iżżid il-veloċità tal-qari minn HBase sa 3 darbiet u minn HDFS sa 5 darbiet

Kif tistgħu taraw, id-dejta tal-ottimizzazzjoni tagħmilha possibbli li tiġi ugwalizzata l-prestazzjoni ta 'dawn id-databases taħt dawn il-kundizzjonijiet u tikseb 450 qari kull sekonda.

Nittamaw li din l-informazzjoni tista 'tkun utli għal xi ħadd fil-kors ta' ġlieda eċċitanti għall-prestazzjoni.

Sors: www.habr.com

Żid kumment