Giunsa pagdugang ang katulin sa pagbasa gikan sa HBase hangtod sa 3 ka beses ug gikan sa HDFS hangtod sa 5 ka beses

Ang taas nga pasundayag usa sa hinungdanon nga mga kinahanglanon kung nagtrabaho uban ang dagkong datos. Sa departamento sa pagkarga sa datos sa Sberbank, gibomba namo ang halos tanang transaksyon ngadto sa among Data Cloud nga nakabase sa Hadoop ug busa nag-atubang sa dagkong mga agos sa impormasyon. Siyempre, kanunay kaming nangitag mga paagi aron mapauswag ang pasundayag, ug karon gusto namong isulti kanimo kung giunsa namo pagdumala ang pag-patch sa RegionServer HBase ug ang kliyente sa HDFS, salamat nga nahimo namon nga madugangan ang katulin sa mga operasyon sa pagbasa.
Giunsa pagdugang ang katulin sa pagbasa gikan sa HBase hangtod sa 3 ka beses ug gikan sa HDFS hangtod sa 5 ka beses

Bisan pa, sa wala pa magpadayon sa esensya sa mga pag-uswag, angay nga hisgutan ang mga pagdili nga, sa prinsipyo, dili malikayan kung naglingkod ka sa usa ka HDD.

Ngano nga ang HDD ug paspas nga Random Access nga pagbasa dili magkatugma
Sama sa imong nahibal-an, ang HBase, ug daghang uban pang mga database, nagtipig sa datos sa mga bloke nga pila ka napulo ka kilobytes ang gidak-on. Sa kasagaran kini mga 64 KB. Karon atong hunahunaon nga kita kinahanglan nga makakuha lamang sa 100 ka bytes ug kita mohangyo sa HBase sa paghatag kanato niini nga data gamit ang usa ka piho nga yawe. Tungod kay ang block nga gidak-on sa HFiles kay 64 KB, ang hangyo mahimong 640 ka pilo nga mas dako (usa lang ka minuto!) kay sa gikinahanglan.

Sunod, tungod kay ang hangyo moagi sa HDFS ug ang metadata caching nga mekanismo niini ShortCircuitCache (nga nagtugot sa direkta nga pag-access sa mga file), kini nagdala sa pagbasa nga 1 MB gikan sa disk. Bisan pa, kini mahimong ipasibo sa parameter dfs.client.read.shortcircuit.buffer.size ug sa daghang mga kaso makatarunganon nga pakunhuran kini nga kantidad, pananglitan sa 126 KB.

Ingnon ta nga buhaton nato kini, apan dugang pa, sa dihang magsugod kita sa pagbasa sa datos pinaagi sa java api, sama sa mga gimbuhaton sama sa FileChannel.basaha ug hangyoa ang operating system nga basahon ang gipiho nga gidaghanon sa datos, kini mabasa nga "basta" 2 ka beses pa. , i.e. 256 KB sa among kaso. Kini tungod kay ang java walay sayon ​​nga paagi sa pagbutang sa FADV_RANDOM nga bandera aron mapugngan kini nga kinaiya.

Ingon usa ka sangputanan, aron makuha ang among 100 bytes, 2600 ka beses nga labi pa ang gibasa sa ilawom sa hood. Morag klaro ang solusyon, atong pakunhuran ang gidak-on sa block ngadto sa usa ka kilobyte, ibutang ang gihisgutan nga bandila ug makaangkon og dako nga pagpadali sa paglamdag. Apan ang problema mao nga pinaagi sa pagkunhod sa gidak-on sa block sa 2 ka beses, gipakunhuran usab namon ang gidaghanon sa mga byte nga gibasa matag yunit sa oras sa 2 ka beses.

Ang uban nga ganansya gikan sa pagbutang sa FADV_RANDOM nga bandila mahimong makuha, apan sa taas nga multi-threading ug adunay block nga gidak-on nga 128 KB, apan kini usa ka maximum nga duha ka napulo ka porsyento:

Giunsa pagdugang ang katulin sa pagbasa gikan sa HBase hangtod sa 3 ka beses ug gikan sa HDFS hangtod sa 5 ka beses

Ang mga pagsulay gihimo sa 100 ka mga file, ang matag 1 GB ang gidak-on ug nahimutang sa 10 ka HDD.

Atong kuwentahon kon unsa ang atong mahimo, sa prinsipyo, sa pagsalig niini nga katulin:
Ingnon ta nga nagbasa kita gikan sa 10 ka mga disk sa gikusgon nga 280 MB/sec, i.e. 3 ka milyon nga 100 ka byte. Apan sa atong nahinumduman, ang datos nga atong gikinahanglan 2600 ka pilo nga mas ubos kay sa gibasa. Busa, atong bahinon ang 3 milyon sa 2600 ug makuha 1100 nga mga rekord matag segundo.

Depressing, dili ba? Kana ang kinaiyahan Random nga Pag-access access sa data sa HDD - sa walay pagtagad sa block gidak-on. Kini ang pisikal nga limitasyon sa random nga pag-access ug wala’y database nga makapugong sa labi pa sa ilawom sa ingon nga mga kondisyon.

Sa unsang paagi nga ang mga database makab-ot ang labi ka taas nga tulin? Aron matubag kini nga pangutana, atong tan-awon kung unsa ang nahitabo sa mosunod nga litrato:

Giunsa pagdugang ang katulin sa pagbasa gikan sa HBase hangtod sa 3 ka beses ug gikan sa HDFS hangtod sa 5 ka beses

Dinhi atong makita nga sa unang pipila ka minuto ang katulin kay halos usa ka libo ka rekord matag segundo. Bisan pa, dugang pa, tungod sa kamatuoran nga labi pa ang gibasa kaysa gihangyo, ang datos natapos sa buff / cache sa operating system (linux) ug ang tulin nga pagtaas sa labi ka disente nga 60 ka libo matag segundo.

Busa, dugang pa nga atong atubangon ang pagpadali sa pag-access lamang sa mga datos nga anaa sa OS cache o nahimutang sa SSD/NVMe storage devices nga susama sa katulin sa pag-access.

Sa among kaso, magpahigayon kami mga pagsulay sa usa ka bangko sa 4 nga mga server, nga ang matag usa gisingil sama sa mosunod:

CPU: Xeon E5-2680 v4 @ 2.40GHz 64 nga mga hilo.
Memorya: 730 GB.
java nga bersyon: 1.8.0_111

Ug dinhi ang yawe nga punto mao ang kantidad sa datos sa mga lamesa nga kinahanglan basahon. Ang tinuod mao nga kung magbasa ka sa datos gikan sa usa ka lamesa nga hingpit nga gibutang sa cache sa HBase, nan dili kini moabut sa pagbasa gikan sa buff/cache sa operating system. Tungod kay ang HBase sa default naggahin sa 40% sa memorya sa usa ka istruktura nga gitawag BlockCache. Sa tinuud kini usa ka ConcurrentHashMap, diin ang yawe mao ang ngalan sa file + offset sa block, ug ang kantidad mao ang aktwal nga datos sa kini nga offset.

Busa, kung magbasa lamang gikan niini nga istruktura, kita nakita namon ang maayo kaayo nga tulin, sama sa usa ka milyon nga hangyo matag segundo. Apan hunahunaon nato nga dili kita makagahin og gatusan ka gigabytes nga memorya alang lamang sa mga panginahanglan sa database, tungod kay adunay daghang uban pang mapuslanon nga mga butang nga nagdagan niini nga mga server.

Pananglitan, sa among kaso, ang gidaghanon sa BlockCache sa usa ka RS mga 12 GB. Kami mitugpa sa duha ka RS sa usa ka node, i.e. Ang 96 GB gigahin alang sa BlockCache sa tanan nga mga node. Ug adunay daghang mga higayon nga dugang nga datos, pananglitan, himoa nga kini 4 nga mga lamesa, 130 nga mga rehiyon matag usa, diin ang mga file 800 MB ang gidak-on, gi-compress sa FAST_DIFF, i.e. usa ka kinatibuk-an nga 410 GB (kini usa ka putli nga datos, i.e. nga wala gikonsiderar ang hinungdan sa pagkopya).

Busa, ang BlockCache maoy mga 23% lamang sa kinatibuk-ang gidaghanon sa datos ug mas duol kini sa tinuod nga kondisyon sa gitawag ug BigData. Ug dinhi nagsugod ang kalingawan - tungod kay klaro, ang gamay nga cache hits, mas grabe ang pasundayag. Human sa tanan, kung mingawon ka, kinahanglan nimo nga buhaton ang daghang trabaho - i.e. adto sa pagtawag sa mga function sa sistema. Bisan pa, dili kini malikayan, busa tan-awon naton ang usa ka hingpit nga lahi nga aspeto - unsa ang mahitabo sa datos sa sulod sa cache?

Atong pasimplehon ang sitwasyon ug isipon nga kita adunay usa ka cache nga mohaum lamang sa 1 ka butang. Ania ang usa ka pananglitan kung unsa ang mahitabo kung kita mosulay sa pagtrabaho sa usa ka gidaghanon sa datos nga 3 ka beses nga mas dako kaysa sa cache, kinahanglan naton:

1. Ibutang ang block 1 sa cache
2. Kuhaa ang block 1 gikan sa cache
3. Ibutang ang block 2 sa cache
4. Kuhaa ang block 2 gikan sa cache
5. Ibutang ang block 3 sa cache

5 nga mga aksyon nahuman! Bisan pa, kini nga kahimtang dili matawag nga normal; sa tinuud, gipugos namon ang HBase nga buhaton ang usa ka hugpong nga wala’y pulos nga trabaho. Kanunay kini nga nagbasa sa datos gikan sa OS cache, gibutang kini sa BlockCache, aron lang ilabay kini hapit dayon tungod kay usa ka bag-ong bahin sa datos ang miabot. Ang animation sa sinugdanan sa post nagpakita sa esensya sa problema - Ang Garbage Collector nagkalayo, ang atmospera nag-init, ang gamay nga Greta sa layo ug init nga Sweden nasuko. Ug kami nga mga tawo sa IT dili gyud ganahan kung ang mga bata maguol, mao nga nagsugod kami sa paghunahuna kung unsa ang among mahimo bahin niini.

Unsa kaha kung dili nimo ibutang ang tanan nga mga bloke sa cache, apan usa lamang ka porsyento niini, aron ang cache dili moawas? Magsugod kita pinaagi sa pagdugang lang sa pipila ka linya sa code sa pagsugod sa function alang sa pagbutang sa datos sa BlockCache:

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

Ang punto dinhi mao ang mosunod: ang offset mao ang posisyon sa block sa file ug ang katapusan nga mga digit niini random ug parehas nga giapod-apod gikan sa 00 ngadto sa 99. Busa, atong laktawan ang mga nahulog sa range nga atong gikinahanglan.

Pananglitan, ibutang ang cacheDataBlockPercent = 20 ug tan-awa kung unsa ang mahitabo:

Giunsa pagdugang ang katulin sa pagbasa gikan sa HBase hangtod sa 3 ka beses ug gikan sa HDFS hangtod sa 5 ka beses

Ang resulta klaro. Sa mga graph sa ubos, kini nahimong tin-aw ngano nga ang maong usa ka pagpatulin nahitabo - kita sa pagluwas sa usa ka daghan sa GC mga kapanguhaan nga walay pagbuhat sa Sisyphean buhat sa pagbutang sa data sa cache lamang sa diha-diha dayon ilabay kini sa drain sa Martian iro:

Giunsa pagdugang ang katulin sa pagbasa gikan sa HBase hangtod sa 3 ka beses ug gikan sa HDFS hangtod sa 5 ka beses

Sa parehas nga oras, ang paggamit sa CPU nagdugang, apan labi ka gamay sa pagka-produktibo:

Giunsa pagdugang ang katulin sa pagbasa gikan sa HBase hangtod sa 3 ka beses ug gikan sa HDFS hangtod sa 5 ka beses

Angay usab nga matikdan nga ang mga bloke nga gitipigan sa BlockCache lahi. Kadaghanan, mga 95%, mao ang datos mismo. Ug ang uban mao ang metadata, sama sa Bloom filter o LEAF_INDEX ug ug uban pa.. Kini nga datos dili igo, apan kini mapuslanon kaayo, tungod kay sa wala pa direkta nga pag-access sa datos, ang HBase milingi sa meta aron masabtan kung gikinahanglan ba nga pangitaon pa dinhi ug, kung mao, kung asa gayud nahimutang ang block sa interes.

Busa, sa code atong makita ang usa ka check nga kahimtang buf.getBlockType().isData() ug salamat sa kini nga meta, ibilin namon kini sa cache sa bisan unsang kaso.

Karon atong dugangan ang load ug gamay nga higpitan ang feature sa usa ka lakaw. Sa una nga pagsulay gihimo namon ang porsyento nga cutoff = 20 ug ang BlockCache gamay nga wala magamit. Karon ibutang nato kini sa 23% ug idugang ang 100 ka mga hilo matag 5 ka minuto aron makita kung unsang punto ang saturation mahitabo:

Giunsa pagdugang ang katulin sa pagbasa gikan sa HBase hangtod sa 3 ka beses ug gikan sa HDFS hangtod sa 5 ka beses

Dinhi atong makita nga ang orihinal nga bersyon hapit diha-diha dayon naigo sa kisame sa mga 100 ka libo nga mga hangyo matag segundo. Samtang ang patch naghatag usa ka pagpatulin hangtod sa 300 ka libo. Sa parehas nga oras, klaro nga ang dugang nga pagpatulin dili na "libre"; Ang paggamit sa CPU nagkadaghan usab.

Bisan pa, kini dili kaayo elegante nga solusyon, tungod kay wala kita mahibal-an daan kung unsa nga porsyento sa mga bloke ang kinahanglan nga i-cache, kini nagdepende sa load profile. Busa, usa ka mekanismo ang gipatuman aron awtomatikong i-adjust kini nga parameter depende sa kalihokan sa mga operasyon sa pagbasa.

Tulo ka mga kapilian ang gidugang aron makontrol kini:

hbase.lru.cache.heavy.eviction.count.limit — nagtakda kung pila ka beses ang proseso sa pagpalayas sa datos gikan sa cache kinahanglan nga modagan sa dili pa kita magsugod sa paggamit sa pag-optimize (sama sa paglaktaw sa mga bloke). Pinaagi sa default kini katumbas sa MAX_INT = 2147483647 ug sa tinuud nagpasabut nga ang bahin dili magsugod sa pagtrabaho sa kini nga kantidad. Tungod kay ang proseso sa pagpalayas magsugod matag 5 - 10 segundos (depende kini sa karga) ug 2147483647 * 10 / 60 / 60 / 24 / 365 = 680 ka tuig. Bisan pa, mahimo namon nga itakda kini nga parameter sa 0 ug himuon nga molihok dayon ang bahin pagkahuman sa paglansad.

Bisan pa, adunay usa usab ka payload sa kini nga parameter. Kung ang among load ingon nga ang mga mubo nga termino nga pagbasa (ingon sa panahon sa adlaw) ug dugay nga mga pagbasa (sa gabii) kanunay nga gisal-ot, nan makasiguro kami nga ang bahin gi-on lamang kung ang mga operasyon sa taas nga pagbasa nagpadayon.

Pananglitan, nahibal-an namon nga ang mga mubo nga pagbasa kasagaran molungtad mga 1 minuto. Dili kinahanglan nga magsugod sa paglabay sa mga bloke, ang cache wala'y panahon nga mahimong karaan ug unya mahimo natong ibutang kini nga parameter nga katumbas sa, pananglitan, 10. Kini mosangpot sa kamatuoran nga ang pag-optimize magsugod lamang sa pagtrabaho kung dugay- Ang termino nga aktibo nga pagbasa nagsugod na, i.e. sa 100 segundos. Busa, kung kita adunay usa ka mubo nga termino nga pagbasa, nan ang tanan nga mga bloke moadto sa cache ug magamit (gawas sa mga papahawaon sa standard algorithm). Ug kung maghimo kami mga dugay nga pagbasa, ang bahin gi-on ug kami adunay labi ka taas nga pasundayag.

hbase.lru.cache.heavy.eviction.mb.size.limit — nagtakda kung pila ka megabytes ang gusto namon ibutang sa cache (ug, siyempre, papahawaon) sa 10 segundos. Ang bahin mosulay sa pagkab-ot niini nga bili ug magpadayon niini. Ang punto mao kini: kung atong itulod ang mga gigabytes ngadto sa cache, nan kinahanglan natong papahawaon ang mga gigabytes, ug kini, ingon sa atong nakita sa ibabaw, mahal kaayo. Bisan pa, dili nimo kinahanglan nga sulayan nga itakda kini nga gamay ra, tungod kay kini ang hinungdan nga ang block skip mode mogawas nga wala sa panahon. Alang sa kusgan nga mga server (mga 20-40 nga pisikal nga mga cores), labing maayo nga itakda ang mga 300-400 MB. Alang sa tungatunga nga klase (~ 10 cores) 200-300 MB. Alang sa huyang nga mga sistema (2-5 cores) 50-100 MB mahimong normal (wala gisulayan niini).

Atong tan-awon kung giunsa kini paglihok: ingnon ta nga atong gibutang ang hbase.lru.cache.heavy.eviction.mb.size.limit = 500, adunay usa ka matang sa load (pagbasa) ug unya matag ~ 10 segundos atong kuwentahon kung pila ang mga byte. gipalayas gamit ang pormula:

Overhead = Libre nga Bytes Sum (MB) * 100 / Limitasyon (MB) - 100;

Kung sa tinuud 2000 MB ang gipalayas, nan ang Overhead katumbas sa:

2000 * 100 / 500 - 100 = 300%

Ang mga algorithm misulay sa pagpadayon sa dili molapas sa pipila ka napulo ka porsyento, mao nga ang bahin makunhuran ang porsyento sa mga naka-cache nga mga bloke, sa ingon nagpatuman sa usa ka mekanismo sa auto-tuning.

Apan, kung moubos ang load, ingnon ta nga 200 MB ra ang gipalayas ug ang Overhead mahimong negatibo (ang gitawag nga overshooting):

200 * 100 / 500 - 100 = -60%

Sa kasukwahi, ang bahin mopataas sa porsyento sa mga naka-cache nga mga bloke hangtud nga ang Overhead mahimong positibo.

Sa ubos usa ka pananglitan kung giunsa kini pagtan-aw sa tinuud nga datos. Dili kinahanglan nga sulayan nga maabot ang 0%, imposible. Maayo kaayo kung kini mga 30 - 100%, makatabang kini nga malikayan ang wala pa sa panahon nga paggawas gikan sa mode sa pag-optimize sa panahon sa mga mubu nga pagdagsang.

hbase.lru.cache.heavy.eviction.overhead.coefficient — nagtakda kung unsa kadali ang gusto namon makuha ang resulta. Kung nahibal-an namon nga sigurado nga ang among mga pagbasa kasagaran taas ug dili gusto nga maghulat, mahimo namon nga madugangan kini nga ratio ug makakuha og taas nga pasundayag nga mas paspas.

Pananglitan, atong gibutang kini nga coefficient = 0.01. Kini nagpasabot nga ang Overhead (tan-awa sa ibabaw) padaghanon niini nga numero pinaagi sa resulta nga resulta ug ang porsyento sa mga cached block makunhuran. Ibutang nato nga ang Overhead = 300% ug coefficient = 0.01, unya ang porsyento sa mga cached block makunhuran sa 3%.

Ang susama nga "Backpressure" nga lohika gipatuman usab alang sa negatibo nga Overhead (overshooting) nga mga kantidad. Tungod kay ang mga mubu nga panahon nga pag-usab-usab sa gidaghanon sa mga pagbasa ug pagpalayas kanunay nga posible, kini nga mekanismo nagtugot kanimo sa paglikay sa ahat nga paggawas gikan sa optimization mode. Ang backpressure adunay balit-ad nga lohika: kung mas kusog ang pag-overshoot, mas daghang mga bloke ang na-cache.

Giunsa pagdugang ang katulin sa pagbasa gikan sa HBase hangtod sa 3 ka beses ug gikan sa HDFS hangtod sa 5 ka beses

Code sa pagpatuman

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

Atong tan-awon ang tanan niini gamit ang tinuod nga pananglitan. Kami adunay mosunod nga script sa pagsulay:

  1. Magsugod ta sa pag-scan (25 ka thread, batch = 100)
  2. Human sa 5 minutos, idugang ang multi-gets (25 threads, batch = 100)
  3. Human sa 5 minutos, i-off ang multi-gets (ang pag-scan ra ang nahabilin pag-usab)

Naghimo kami og duha ka dagan, una hbase.lru.cache.heavy.eviction.count.limit = 10000 (nga sa pagkatinuod nagpugong sa feature), ug dayon nagtakda og limit = 0 (makapahimo niini).

Sa mga log sa ubos atong makita kung giunsa ang pag-on sa feature ug gi-reset ang Overshooting ngadto sa 14-71%. Matag karon ug unya ang load mokunhod, nga mopaandar sa Backpressure ug ang HBase mag-cache pag-usab sa daghang mga bloke.

Log RehiyonServer
gipalayas (MB): 0, ratio 0.0, overhead (%): -100, bug-at nga eviction counter: 0, kasamtangan nga caching DataBlock (%): 100
gipalayas (MB): 0, ratio 0.0, overhead (%): -100, bug-at nga eviction counter: 0, kasamtangan nga caching DataBlock (%): 100
gipalayas (MB): 2170, ratio 1.09, overhead (%): 985, bug-at nga eviction counter: 1, kasamtangan nga caching DataBlock (%): 91 <pagsugod
gipalayas (MB): 3763, ratio 1.08, overhead (%): 1781, bug-at nga eviction counter: 2, kasamtangan nga caching DataBlock (%): 76
gipalayas (MB): 3306, ratio 1.07, overhead (%): 1553, bug-at nga eviction counter: 3, kasamtangan nga caching DataBlock (%): 61
gipalayas (MB): 2508, ratio 1.06, overhead (%): 1154, bug-at nga eviction counter: 4, kasamtangan nga caching DataBlock (%): 50
gipalayas (MB): 1824, ratio 1.04, overhead (%): 812, bug-at nga eviction counter: 5, kasamtangan nga caching DataBlock (%): 42
gipalayas (MB): 1482, ratio 1.03, overhead (%): 641, bug-at nga eviction counter: 6, kasamtangan nga caching DataBlock (%): 36
gipalayas (MB): 1140, ratio 1.01, overhead (%): 470, bug-at nga eviction counter: 7, kasamtangan nga caching DataBlock (%): 32
gipalayas (MB): 913, ratio 1.0, overhead (%): 356, bug-at nga eviction counter: 8, kasamtangan nga caching DataBlock (%): 29
gipalayas (MB): 912, ratio 0.89, overhead (%): 356, bug-at nga eviction counter: 9, kasamtangan nga caching DataBlock (%): 26
gipalayas (MB): 684, ratio 0.76, overhead (%): 242, bug-at nga eviction counter: 10, kasamtangan nga caching DataBlock (%): 24
gipalayas (MB): 684, ratio 0.61, overhead (%): 242, bug-at nga eviction counter: 11, kasamtangan nga caching DataBlock (%): 22
gipalayas (MB): 456, ratio 0.51, overhead (%): 128, bug-at nga eviction counter: 12, kasamtangan nga caching DataBlock (%): 21
gipalayas (MB): 456, ratio 0.42, overhead (%): 128, bug-at nga eviction counter: 13, kasamtangan nga caching DataBlock (%): 20
gipalayas (MB): 456, ratio 0.33, overhead (%): 128, bug-at nga eviction counter: 14, kasamtangan nga caching DataBlock (%): 19
gipalayas (MB): 342, ratio 0.33, overhead (%): 71, bug-at nga eviction counter: 15, kasamtangan nga caching DataBlock (%): 19
gipalayas (MB): 342, ratio 0.32, overhead (%): 71, bug-at nga eviction counter: 16, kasamtangan nga caching DataBlock (%): 19
gipalayas (MB): 342, ratio 0.31, overhead (%): 71, bug-at nga eviction counter: 17, kasamtangan nga caching DataBlock (%): 19
gipalayas (MB): 228, ratio 0.3, overhead (%): 14, bug-at nga eviction counter: 18, kasamtangan nga caching DataBlock (%): 19
gipalayas (MB): 228, ratio 0.29, overhead (%): 14, bug-at nga eviction counter: 19, kasamtangan nga caching DataBlock (%): 19
gipalayas (MB): 228, ratio 0.27, overhead (%): 14, bug-at nga eviction counter: 20, kasamtangan nga caching DataBlock (%): 19
gipalayas (MB): 228, ratio 0.25, overhead (%): 14, bug-at nga eviction counter: 21, kasamtangan nga caching DataBlock (%): 19
gipalayas (MB): 228, ratio 0.24, overhead (%): 14, bug-at nga eviction counter: 22, kasamtangan nga caching DataBlock (%): 19
gipalayas (MB): 228, ratio 0.22, overhead (%): 14, bug-at nga eviction counter: 23, kasamtangan nga caching DataBlock (%): 19
gipalayas (MB): 228, ratio 0.21, overhead (%): 14, bug-at nga eviction counter: 24, kasamtangan nga caching DataBlock (%): 19
gipalayas (MB): 228, ratio 0.2, overhead (%): 14, bug-at nga eviction counter: 25, kasamtangan nga caching DataBlock (%): 19
gipalayas (MB): 228, ratio 0.17, overhead (%): 14, bug-at nga eviction counter: 26, kasamtangan nga caching DataBlock (%): 19
gipalayas (MB): 456, ratio 0.17, overhead (%): 128, bug-at nga eviction counter: 27, kasamtangan nga pag-cache sa DataBlock (%): 18 < gidugang nga nakuha (apan parehas ang lamesa)
gipalayas (MB): 456, ratio 0.15, overhead (%): 128, bug-at nga eviction counter: 28, kasamtangan nga caching DataBlock (%): 17
gipalayas (MB): 342, ratio 0.13, overhead (%): 71, bug-at nga eviction counter: 29, kasamtangan nga caching DataBlock (%): 17
gipalayas (MB): 342, ratio 0.11, overhead (%): 71, bug-at nga eviction counter: 30, kasamtangan nga caching DataBlock (%): 17
gipalayas (MB): 342, ratio 0.09, overhead (%): 71, bug-at nga eviction counter: 31, kasamtangan nga caching DataBlock (%): 17
gipalayas (MB): 228, ratio 0.08, overhead (%): 14, bug-at nga eviction counter: 32, kasamtangan nga caching DataBlock (%): 17
gipalayas (MB): 228, ratio 0.07, overhead (%): 14, bug-at nga eviction counter: 33, kasamtangan nga caching DataBlock (%): 17
gipalayas (MB): 228, ratio 0.06, overhead (%): 14, bug-at nga eviction counter: 34, kasamtangan nga caching DataBlock (%): 17
gipalayas (MB): 228, ratio 0.05, overhead (%): 14, bug-at nga eviction counter: 35, kasamtangan nga caching DataBlock (%): 17
gipalayas (MB): 228, ratio 0.05, overhead (%): 14, bug-at nga eviction counter: 36, kasamtangan nga caching DataBlock (%): 17
gipalayas (MB): 228, ratio 0.04, overhead (%): 14, bug-at nga eviction counter: 37, kasamtangan nga caching DataBlock (%): 17
gipalayas (MB): 109, ratio 0.04, overhead (%): -46, bug-at nga eviction counter: 37, kasamtangan nga caching DataBlock (%): 22 < back pressure
gipalayas (MB): 798, ratio 0.24, overhead (%): 299, bug-at nga eviction counter: 38, kasamtangan nga caching DataBlock (%): 20
gipalayas (MB): 798, ratio 0.29, overhead (%): 299, bug-at nga eviction counter: 39, kasamtangan nga caching DataBlock (%): 18
gipalayas (MB): 570, ratio 0.27, overhead (%): 185, bug-at nga eviction counter: 40, kasamtangan nga caching DataBlock (%): 17
gipalayas (MB): 456, ratio 0.22, overhead (%): 128, bug-at nga eviction counter: 41, kasamtangan nga caching DataBlock (%): 16
gipalayas (MB): 342, ratio 0.16, overhead (%): 71, bug-at nga eviction counter: 42, kasamtangan nga caching DataBlock (%): 16
gipalayas (MB): 342, ratio 0.11, overhead (%): 71, bug-at nga eviction counter: 43, kasamtangan nga caching DataBlock (%): 16
gipalayas (MB): 228, ratio 0.09, overhead (%): 14, bug-at nga eviction counter: 44, kasamtangan nga caching DataBlock (%): 16
gipalayas (MB): 228, ratio 0.07, overhead (%): 14, bug-at nga eviction counter: 45, kasamtangan nga caching DataBlock (%): 16
gipalayas (MB): 228, ratio 0.05, overhead (%): 14, bug-at nga eviction counter: 46, kasamtangan nga caching DataBlock (%): 16
gipalayas (MB): 222, ratio 0.04, overhead (%): 11, bug-at nga eviction counter: 47, kasamtangan nga caching DataBlock (%): 16
gipalayas (MB): 104, ratio 0.03, overhead (%): -48, bug-at nga eviction counter: 47, kasamtangan nga caching DataBlock (%): 21 < interrupt gets
gipalayas (MB): 684, ratio 0.2, overhead (%): 242, bug-at nga eviction counter: 48, kasamtangan nga caching DataBlock (%): 19
gipalayas (MB): 570, ratio 0.23, overhead (%): 185, bug-at nga eviction counter: 49, kasamtangan nga caching DataBlock (%): 18
gipalayas (MB): 342, ratio 0.22, overhead (%): 71, bug-at nga eviction counter: 50, kasamtangan nga caching DataBlock (%): 18
gipalayas (MB): 228, ratio 0.21, overhead (%): 14, bug-at nga eviction counter: 51, kasamtangan nga caching DataBlock (%): 18
gipalayas (MB): 228, ratio 0.2, overhead (%): 14, bug-at nga eviction counter: 52, kasamtangan nga caching DataBlock (%): 18
gipalayas (MB): 228, ratio 0.18, overhead (%): 14, bug-at nga eviction counter: 53, kasamtangan nga caching DataBlock (%): 18
gipalayas (MB): 228, ratio 0.16, overhead (%): 14, bug-at nga eviction counter: 54, kasamtangan nga caching DataBlock (%): 18
gipalayas (MB): 228, ratio 0.14, overhead (%): 14, bug-at nga eviction counter: 55, kasamtangan nga caching DataBlock (%): 18
gipalayas (MB): 112, ratio 0.14, overhead (%): -44, bug-at nga eviction counter: 55, kasamtangan nga caching DataBlock (%): 23 < back pressure
gipalayas (MB): 456, ratio 0.26, overhead (%): 128, bug-at nga eviction counter: 56, kasamtangan nga caching DataBlock (%): 22
gipalayas (MB): 342, ratio 0.31, overhead (%): 71, bug-at nga eviction counter: 57, kasamtangan nga caching DataBlock (%): 22
gipalayas (MB): 342, ratio 0.33, overhead (%): 71, bug-at nga eviction counter: 58, kasamtangan nga caching DataBlock (%): 22
gipalayas (MB): 342, ratio 0.33, overhead (%): 71, bug-at nga eviction counter: 59, kasamtangan nga caching DataBlock (%): 22
gipalayas (MB): 342, ratio 0.33, overhead (%): 71, bug-at nga eviction counter: 60, kasamtangan nga caching DataBlock (%): 22
gipalayas (MB): 342, ratio 0.33, overhead (%): 71, bug-at nga eviction counter: 61, kasamtangan nga caching DataBlock (%): 22
gipalayas (MB): 342, ratio 0.33, overhead (%): 71, bug-at nga eviction counter: 62, kasamtangan nga caching DataBlock (%): 22
gipalayas (MB): 342, ratio 0.33, overhead (%): 71, bug-at nga eviction counter: 63, kasamtangan nga caching DataBlock (%): 22
gipalayas (MB): 342, ratio 0.32, overhead (%): 71, bug-at nga eviction counter: 64, kasamtangan nga caching DataBlock (%): 22
gipalayas (MB): 342, ratio 0.33, overhead (%): 71, bug-at nga eviction counter: 65, kasamtangan nga caching DataBlock (%): 22
gipalayas (MB): 342, ratio 0.33, overhead (%): 71, bug-at nga eviction counter: 66, kasamtangan nga caching DataBlock (%): 22
gipalayas (MB): 342, ratio 0.32, overhead (%): 71, bug-at nga eviction counter: 67, kasamtangan nga caching DataBlock (%): 22
gipalayas (MB): 342, ratio 0.33, overhead (%): 71, bug-at nga eviction counter: 68, kasamtangan nga caching DataBlock (%): 22
gipalayas (MB): 342, ratio 0.32, overhead (%): 71, bug-at nga eviction counter: 69, kasamtangan nga caching DataBlock (%): 22
gipalayas (MB): 342, ratio 0.32, overhead (%): 71, bug-at nga eviction counter: 70, kasamtangan nga caching DataBlock (%): 22
gipalayas (MB): 342, ratio 0.33, overhead (%): 71, bug-at nga eviction counter: 71, kasamtangan nga caching DataBlock (%): 22
gipalayas (MB): 342, ratio 0.33, overhead (%): 71, bug-at nga eviction counter: 72, kasamtangan nga caching DataBlock (%): 22
gipalayas (MB): 342, ratio 0.33, overhead (%): 71, bug-at nga eviction counter: 73, kasamtangan nga caching DataBlock (%): 22
gipalayas (MB): 342, ratio 0.33, overhead (%): 71, bug-at nga eviction counter: 74, kasamtangan nga caching DataBlock (%): 22
gipalayas (MB): 342, ratio 0.33, overhead (%): 71, bug-at nga eviction counter: 75, kasamtangan nga caching DataBlock (%): 22
gipalayas (MB): 342, ratio 0.33, overhead (%): 71, bug-at nga eviction counter: 76, kasamtangan nga caching DataBlock (%): 22
gipalayas (MB): 21, ratio 0.33, overhead (%): -90, bug-at nga eviction counter: 76, kasamtangan nga caching DataBlock (%): 32
gipalayas (MB): 0, ratio 0.0, overhead (%): -100, bug-at nga eviction counter: 0, kasamtangan nga caching DataBlock (%): 100
gipalayas (MB): 0, ratio 0.0, overhead (%): -100, bug-at nga eviction counter: 0, kasamtangan nga caching DataBlock (%): 100

Ang mga pag-scan gikinahanglan aron ipakita ang parehas nga proseso sa porma sa usa ka graph sa relasyon tali sa duha ka mga seksyon sa cache - usa (diin ang mga bloke nga wala pa gihangyo kaniadto) ug daghang (data nga "gihangyo" labing menos kausa gitipigan dinhi):

Giunsa pagdugang ang katulin sa pagbasa gikan sa HBase hangtod sa 3 ka beses ug gikan sa HDFS hangtod sa 5 ka beses

Ug sa katapusan, unsa ang hitsura sa operasyon sa mga parameter sa porma sa usa ka graph. Alang sa pagtandi, ang cache hingpit nga gipalong sa sinugdanan, dayon ang HBase gilunsad uban ang pag-cache ug paglangan sa pagsugod sa trabaho sa pag-optimize sa 5 minuto (30 nga mga siklo sa pagpalayas).

Ang bug-os nga code makita sa Pull Request HBASE 23887 sa github.

Bisan pa, ang 300 ka libo nga pagbasa matag segundo dili ang tanan nga mahimo sa kini nga hardware sa ilawom sa kini nga mga kondisyon. Ang tinuod mao nga kung kinahanglan nimo nga ma-access ang data pinaagi sa HDFS, gigamit ang ShortCircuitCache (gitawag nga SSC) nga mekanismo, nga nagtugot kanimo nga ma-access ang data direkta, paglikay sa mga interaksyon sa network.

Gipakita sa profile nga bisan kung kini nga mekanismo naghatag usa ka dako nga ganansya, kini usab sa usa ka punto mahimo nga usa ka bottleneck, tungod kay hapit tanan nga bug-at nga mga operasyon mahitabo sa sulod sa usa ka kandado, nga nagdala sa pag-block sa kadaghanan sa oras.

Giunsa pagdugang ang katulin sa pagbasa gikan sa HBase hangtod sa 3 ka beses ug gikan sa HDFS hangtod sa 5 ka beses

Sa pagkaamgo niini, among naamgohan nga ang problema mahimong malikayan pinaagi sa paghimo og usa ka han-ay sa mga independenteng SSC:

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

Ug unya pagtrabaho uban kanila, dili apil ang mga interseksyon usab sa katapusan nga offset digit:

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

Karon mahimo ka magsugod sa pagsulay. Aron mahimo kini, magbasa kami og mga file gikan sa HDFS nga adunay usa ka yano nga multi-threaded nga aplikasyon. Ibutang ang mga parameter:

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

Ug basaha lang ang mga file:

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

Kini nga code gipatuman sa lain nga mga hilo ug atong dugangan ang gidaghanon sa dungan nga pagbasa sa mga file (gikan sa 10 ngadto sa 200 - horizontal axis) ug ang gidaghanon sa mga cache (gikan sa 1 ngadto sa 10 - mga graphic). Ang bertikal nga axis nagpakita sa pagpatulin nga resulta sa pagtaas sa SSC kalabot sa kaso kung adunay usa lamang ka cache.

Giunsa pagdugang ang katulin sa pagbasa gikan sa HBase hangtod sa 3 ka beses ug gikan sa HDFS hangtod sa 5 ka beses

Giunsa pagbasa ang graph: Ang oras sa pagpatuman sa 100 ka libo nga pagbasa sa 64 KB nga mga bloke nga adunay usa ka cache nanginahanglan 78 segundos. Samtang sa 5 caches kini nagkinahanglan og 16 segundos. Mga. adunay pagpatulin nga ~5 ka beses. Sama sa makita gikan sa graph, ang epekto dili kaayo mamatikdan sa gamay nga gidaghanon sa parallel reads, kini nagsugod sa pagdula sa usa ka mamatikdan nga papel kung adunay labaw pa sa 50 nga thread reads. Mamatikdan usab nga ang pagdugang sa gidaghanon sa mga SSC gikan sa 6 ug sa ibabaw naghatag usa ka labi ka gamay nga pagtaas sa pasundayag.

Mubo nga sulat 1: tungod kay ang mga resulta sa pagsulay medyo dali nga mabag-o (tan-awa sa ubos), 3 nga pagdagan ang gihimo ug ang mga sangputanan nga mga kantidad gi-average.

Mubo nga sulat 2: Ang nakuha sa pasundayag gikan sa pag-configure sa random nga pag-access parehas, bisan kung ang pag-access mismo mas hinay.

Bisan pa, kinahanglan nga ipatin-aw nga, dili sama sa kaso sa HBase, kini nga pagpadali dili kanunay libre. Dinhi among "giablihan" ang katakus sa CPU sa pagbuhat sa labi pa, imbis nga magbitay sa mga kandado.

Giunsa pagdugang ang katulin sa pagbasa gikan sa HBase hangtod sa 3 ka beses ug gikan sa HDFS hangtod sa 5 ka beses

Dinhi imong maobserbahan nga, sa kinatibuk-an, ang pagtaas sa gidaghanon sa mga cache naghatag sa gibana-bana nga proporsyonal nga pagtaas sa paggamit sa CPU. Bisan pa, adunay gamay nga dugang nga mga kombinasyon sa kadaugan.

Pananglitan, atong tan-awon pag-ayo ang setting nga SSC = 3. Ang pagtaas sa performance sa range maoy mga 3.3 ka beses. Sa ubos mao ang mga resulta gikan sa tanang tulo ka managlahing dagan.

Giunsa pagdugang ang katulin sa pagbasa gikan sa HBase hangtod sa 3 ka beses ug gikan sa HDFS hangtod sa 5 ka beses

Samtang ang pagkonsumo sa CPU nagdugang mga 2.8 ka beses. Ang kalainan dili kaayo dako, apan ang gamay nga Greta malipayon na ug tingali adunay panahon sa pag-eskwela ug pagkuha sa mga leksyon.

Sa ingon, kini adunay positibo nga epekto sa bisan unsang himan nga naggamit sa daghang pag-access sa HDFS (pananglitan Spark, ug uban pa), basta ang code sa aplikasyon gaan ang timbang (ie ang plug naa sa bahin sa kliyente sa HDFS) ug adunay libre nga gahum sa CPU. . Aron masusi, atong sulayan kung unsa ang epekto sa hiniusa nga paggamit sa BlockCache optimization ug SSC tuning alang sa pagbasa gikan sa HBase.

Giunsa pagdugang ang katulin sa pagbasa gikan sa HBase hangtod sa 3 ka beses ug gikan sa HDFS hangtod sa 5 ka beses

Makita nga ubos sa ingon nga mga kondisyon ang epekto dili sama ka dako sa mga refined nga mga pagsulay (pagbasa nga walay bisan unsa nga pagproseso), apan posible nga mopilit sa dugang nga 80K dinhi. Mag-uban, ang duha nga pag-optimize naghatag hangtod sa 4x nga pagpadali.

Ang usa ka PR gihimo usab alang niini nga pag-optimize [HDFS-15202], nga gihiusa ug kini nga gamit mahimong magamit sa umaabot nga mga pagpagawas.

Ug sa katapusan, makapainteres nga itandi ang performance sa pagbasa sa parehas nga database sa lapad nga kolum, Cassandra ug HBase.

Aron mahimo kini, naglunsad kami og mga higayon sa standard YCSB load testing utility gikan sa duha ka host (800 ka thread sa kinatibuk-an). Sa kilid sa server - 4 nga mga higayon sa RegionServer ug Cassandra sa 4 nga mga host (dili ang kung diin ang mga kliyente nagdagan, aron malikayan ang ilang impluwensya). Ang mga pagbasa naggikan sa mga lamesa sa gidak-on:

HBase - 300 GB sa HDFS (100 GB puro nga datos)

Cassandra - 250 GB (replication factor = 3)

Mga. ang volume halos pareho ra (sa HBase gamay pa).

Mga parameter sa HBase:

dfs.client.short.circuit.num = 5 (Pag-optimize sa kliyente sa HDFS)

hbase.lru.cache.heavy.eviction.count.limit = 30 - kini nagpasabut nga ang patch magsugod sa pagtrabaho pagkahuman sa 30 nga pagpalayas (~5 minuto)

hbase.lru.cache.heavy.eviction.mb.size.limit = 300 - target nga gidaghanon sa caching ug pagpalayas

Ang mga log sa YCSB gi-parse ug gi-compile sa mga Excel graph:

Giunsa pagdugang ang katulin sa pagbasa gikan sa HBase hangtod sa 3 ka beses ug gikan sa HDFS hangtod sa 5 ka beses

Sama sa imong nakita, kini nga mga pag-optimize nagpaposible sa pagtandi sa pasundayag sa kini nga mga database sa ilawom sa kini nga mga kondisyon ug pagkab-ot sa 450 ka libo nga pagbasa matag segundo.

Kami nanghinaut nga kini nga impormasyon mahimong mapuslanon sa usa ka tawo sa panahon sa kulbahinam nga pakigbisog alang sa pagka-produktibo.

Source: www.habr.com

Idugang sa usa ka comment