Kā palielināt lasÄ«Å”anas ātrumu no HBase lÄ«dz 3 reizēm un no HDFS lÄ«dz 5 reizēm

Augsta veiktspēja ir viena no galvenajām prasÄ«bām, strādājot ar lielajiem datiem. Sberbank datu ielādes nodaļā mēs pārsÅ«tām gandrÄ«z visus darÄ«jumus mÅ«su Hadoop balstÄ«tajā datu mākonÄ« un tāpēc apstrādājam patieŔām lielas informācijas plÅ«smas. Protams, mēs vienmēr meklējam veidus, kā uzlabot veiktspēju, un tagad mēs vēlamies jums pastāstÄ«t, kā mums izdevās izlabot RegionServer HBase un HDFS klientu, pateicoties kuriem mēs varējām ievērojami palielināt lasÄ«Å”anas darbÄ«bu ātrumu.
Kā palielināt lasÄ«Å”anas ātrumu no HBase lÄ«dz 3 reizēm un no HDFS lÄ«dz 5 reizēm

Tomēr, pirms pāriet pie uzlabojumu būtības, ir vērts runāt par ierobežojumiem, kurus principā nevar apiet, ja sēžat uz HDD.

Kāpēc HDD un ātra brÄ«vpiekļuves lasÄ«Å”ana nav saderÄ«gas
Kā zināms, HBase un daudzas citas datu bāzes glabā datus vairāku desmitu kilobaitu lielos blokos. Pēc noklusējuma tas ir aptuveni 64 KB. Tagad iedomāsimies, ka mums jāiegÅ«st tikai 100 baiti, un mēs lÅ«dzam HBase sniegt mums Å”os datus, izmantojot noteiktu atslēgu. Tā kā HFiles bloka lielums ir 64 KB, pieprasÄ«jums bÅ«s 640 reizes lielāks (tikai minÅ«ti!) nekā nepiecieÅ”ams.

Tālāk, jo pieprasÄ«jums tiks nosÅ«tÄ«ts caur HDFS un tā metadatu keÅ”atmiņas mehānismu ShortCircuitCache (kas nodroÅ”ina tieÅ”u piekļuvi failiem), tas noved pie jau 1 MB nolasÄ«Å”anas no diska. Tomēr to var pielāgot ar parametru dfs.client.read.shortcircuit.buffer.size un daudzos gadÄ«jumos ir jēga samazināt Å”o vērtÄ«bu, piemēram, lÄ«dz 126 KB.

Pieņemsim, ka mēs to darām, bet turklāt, kad mēs sākam lasÄ«t datus, izmantojot Java api, piemēram, funkcijas, piemēram, FileChannel.read, un lÅ«dzam operētājsistēmai nolasÄ«t norādÄ«to datu apjomu, tā nolasa ā€œkatram gadÄ«jumamā€ 2 reizes vairāk. , t.i. 256 KB mÅ«su gadÄ«jumā. Tas ir tāpēc, ka java nav vienkārÅ”s veids, kā iestatÄ«t karogu FADV_RANDOM, lai novērstu Å”o darbÄ«bu.

Rezultātā, lai iegÅ«tu mÅ«su 100 baitus, zem pārsega tiek nolasÄ«ts 2600 reižu vairāk. Å Ä·iet, ka risinājums ir acÄ«mredzams, samazināsim bloka izmēru lÄ«dz kilobaitam, uzliksim minēto karogu un gÅ«sim lielu apgaismÄ«bas paātrinājumu. Bet problēma ir tā, ka, samazinot bloka izmēru 2 reizes, mēs arÄ« 2 reizes samazinām nolasÄ«to baitu skaitu laika vienÄ«bā.

Dažus ieguvumus no karoga FADV_RANDOM iestatÄ«Å”anas var iegÅ«t, taču tikai ar augstu daudzpavedienu un bloka izmēru 128 KB, taču tas ir maksimums pāris desmitiem procentu:

Kā palielināt lasÄ«Å”anas ātrumu no HBase lÄ«dz 3 reizēm un no HDFS lÄ«dz 5 reizēm

Pārbaudes tika veiktas 100 failiem, katrs 1 GB liels un atrodas 10 HDD.

Aprēķināsim, uz ko mēs principā varam rēķināties ar Ŕādu ātrumu:
Pieņemsim, ka mēs lasām no 10 diskiem ar ātrumu 280 MB/sek, t.i. 3 miljoni reižu 100 baiti. Bet, kā mēs atceramies, mums nepiecieÅ”amie dati ir 2600 reižu mazāki nekā nolasÄ«tie dati. Tādējādi mēs sadalām 3 miljonus ar 2600 un iegÅ«stam 1100 ieraksti sekundē.

NomācoÅ”i, vai ne? Tāda ir daba NejauÅ”a piekļuve piekļuve datiem HDD ā€” neatkarÄ«gi no bloka lieluma. Å is ir fizisks brÄ«vpiekļuves ierobežojums, un neviena datubāze Ŕādos apstākļos nevar izspiest vairāk.

Kā tad datu bāzes sasniedz daudz lielāku ātrumu? Lai atbildētu uz Å”o jautājumu, apskatÄ«sim, kas notiek Å”ajā attēlā:

Kā palielināt lasÄ«Å”anas ātrumu no HBase lÄ«dz 3 reizēm un no HDFS lÄ«dz 5 reizēm

Å eit mēs redzam, ka pirmajās minÅ«tēs ātrums patieŔām ir aptuveni tÅ«kstotis rekordu sekundē. Taču tālāk, pateicoties tam, ka tiek nolasÄ«ts daudz vairāk, nekā prasÄ«ts, dati nonāk operētājsistēmas (linux) bufetā/keÅ”atmiņā un ātrums palielinās lÄ«dz pieklājÄ«gākiem 60 tÅ«kstoÅ”iem sekundē.

Tādējādi turpmāk mēs nodarbosimies ar piekļuves paātrināŔanu tikai tiem datiem, kas atrodas OS keÅ”atmiņā vai atrodas SSD/NVMe atmiņas ierÄ«cēs ar salÄ«dzināmu piekļuves ātrumu.

MÅ«su gadÄ«jumā mēs veiksim testus uz stenda, kurā ir 4 serveri, no kuriem katrs tiek iekasēts Ŕādi:

CPU: Xeon E5-2680 v4 @ 2.40 GHz 64 pavedieni.
Atmiņa: 730 GB.
java versija: 1.8.0_111

Un Å”eit galvenais ir datu apjoms tabulās, kas ir jāizlasa. Fakts ir tāds, ka, nolasot datus no tabulas, kas pilnÄ«bā ir ievietota HBase keÅ”atmiņā, tie pat netiks nolasÄ«ti no operētājsistēmas bufetes/keÅ”atmiņas. Tā kā HBase pēc noklusējuma pieŔķir 40% atmiņas struktÅ«rai, ko sauc par BlockCache. BÅ«tÄ«bā tas ir ConcurrentHashMap, kur atslēga ir faila nosaukums + bloka nobÄ«de, un vērtÄ«ba ir faktiskie dati Å”ajā nobÄ«dē.

Tādējādi, lasot tikai no Ŕīs struktÅ«ras, mēs mēs redzam lielisku ātrumu, piemēram, miljons pieprasÄ«jumu sekundē. Bet iedomāsimies, ka nevaram atvēlēt simtiem gigabaitu atmiņas tikai datu bāzes vajadzÄ«bām, jo ā€‹ā€‹Å”ajos serveros darbojas daudz citu noderÄ«gu lietu.

Piemēram, mūsu gadījumā BlockCache apjoms vienā RS ir aptuveni 12 GB. Vienā mezglā nolaidām divus RS, t.i. 96 GB ir atvēlēti BlockCache visos mezglos. Un datu ir daudzkārt vairāk, piemēram, lai tās ir 4 tabulas, katrā pa 130 reģioniem, kurās faili ir 800 MB lieli, saspiesti ar FAST_DIFF, t.i. kopā 410 GB (tie ir tīri dati, t.i., neņemot vērā replikācijas koeficientu).

Tādējādi BlockCache ir tikai aptuveni 23% no kopējā datu apjoma, un tas ir daudz tuvāk reālajiem apstākļiem, ko sauc par BigData. Un Å”eit sākas jautrÄ«ba ā€“ jo acÄ«mredzami, jo mazāk keÅ”atmiņas trāpÄ«jumu, jo sliktāka ir veiktspēja. Galu galā, ja jÅ«s nokavēsiet, jums bÅ«s daudz jāstrādā - t.i. pārejiet uz sistēmas funkciju izsaukÅ”anu. Tomēr no tā nevar izvairÄ«ties, tāpēc apskatÄ«sim pavisam citu aspektu ā€“ kas notiek ar datiem, kas atrodas keÅ”atmiņā?

VienkārÅ”osim situāciju un pieņemsim, ka mums ir keÅ”atmiņa, kas atbilst tikai 1 objektam. Å eit ir piemērs tam, kas notiks, kad mēģināsim strādāt ar datu apjomu, kas ir 3 reizes lielāks par keÅ”atmiņu, mums bÅ«s:

1. Ievietojiet 1. bloku keÅ”atmiņā
2. Noņemiet 1. bloku no keÅ”atmiņas
3. Ievietojiet 2. bloku keÅ”atmiņā
4. Noņemiet 2. bloku no keÅ”atmiņas
5. Ievietojiet 3. bloku keÅ”atmiņā

5 darbÄ«bas pabeigtas! Tomēr Å”o situāciju nevar saukt par normālu, patiesÄ«bā mēs piespiežam HBase veikt virkni pilnÄ«gi bezjēdzÄ«gu darbu. Tas pastāvÄ«gi nolasa datus no OS keÅ”atmiņas, ievieto tos BlockCache, lai gandrÄ«z nekavējoties tos izmestu, jo ir ienākusi jauna datu daļa. Animācija ieraksta sākumā parāda problēmas bÅ«tÄ«bu - Atkritumu savācējs iet nost, atmosfēra uzkarst, mazā Grēta tālajā un karstajā Zviedrijā kļūst satraukta. Un mums, IT cilvēkiem, ļoti nepatÄ«k, ja bērni ir skumji, tāpēc sākam domāt, ko darÄ«t lietas labā.

Ko darÄ«t, ja keÅ”atmiņā ievietojat nevis visus blokus, bet tikai noteiktu procentuālo daļu no tiem, lai keÅ”atmiņa nepārplÅ«st? Sāksim, vienkārÅ”i pievienojot tikai dažas koda rindiņas funkcijas sākumam datu ievietoÅ”anai BlockCache:

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

Lieta ir Ŕāda: nobÄ«de ir bloka pozÄ«cija failā, un tā pēdējie cipari ir nejauÅ”i un vienmērÄ«gi sadalÄ«ti no 00 lÄ«dz 99. Tāpēc mēs izlaidÄ«sim tikai tos, kas ietilpst mums vajadzÄ«gajā diapazonā.

Piemēram, iestatiet cacheDataBlockPercent = 20 un skatiet, kas notiek:

Kā palielināt lasÄ«Å”anas ātrumu no HBase lÄ«dz 3 reizēm un no HDFS lÄ«dz 5 reizēm

Rezultāts ir acÄ«mredzams. Zemāk redzamajos grafikos kļūst skaidrs, kāpēc notika Ŕāds paātrinājums - mēs ietaupām daudz GC resursu, neveicot sÄ«zifisko darbu, ievietojot datus keÅ”atmiņā, lai nekavējoties izmestu tos Marsa suņu kanalizācijā:

Kā palielināt lasÄ«Å”anas ātrumu no HBase lÄ«dz 3 reizēm un no HDFS lÄ«dz 5 reizēm

Tajā paŔā laikā CPU izmantoŔana palielinās, bet ir daudz mazāka par produktivitāti:

Kā palielināt lasÄ«Å”anas ātrumu no HBase lÄ«dz 3 reizēm un no HDFS lÄ«dz 5 reizēm

Ir arÄ« vērts atzÄ«mēt, ka BlockCache glabātie bloki ir atŔķirÄ«gi. Lielākā daļa, aptuveni 95%, ir paÅ”i dati. Un pārējais ir metadati, piemēram, BlÅ«ma filtri vai LEAF_INDEX un т.Š“.. Ar Å”iem datiem nepietiek, taču tie ir ļoti noderÄ«gi, jo pirms tieŔās piekļuves datiem HBase pievērÅ”as meta, lai saprastu, vai Å”eit ir jāmeklē tālāk un, ja jā, tad kur tieÅ”i atrodas interesējoÅ”ais bloks.

Tāpēc kodā mēs redzam pārbaudes nosacÄ«jumu buf.getBlockType().isData() un pateicoties Å”ai meta, mēs to jebkurā gadÄ«jumā atstāsim keÅ”atmiņā.

Tagad palielināsim slodzi un vienā piegājienā nedaudz nostiprināsim funkciju. Pirmajā testā mēs izveidojām robežvērtību = 20, un BlockCache bija nedaudz nepietiekami izmantots. Tagad iestatīsim to uz 23% un pievienosim 100 pavedienus ik pēc 5 minūtēm, lai redzētu, kurā brīdī notiek piesātinājums:

Kā palielināt lasÄ«Å”anas ātrumu no HBase lÄ«dz 3 reizēm un no HDFS lÄ«dz 5 reizēm

Å eit mēs redzam, ka sākotnējā versija gandrÄ«z uzreiz sasniedz griestus ar aptuveni 100 tÅ«kstoÅ”iem pieprasÄ«jumu sekundē. Tā kā plāksteris dod paātrinājumu lÄ«dz 300 tÅ«kst. Tajā paŔā laikā ir skaidrs, ka turpmāka paātrināŔana vairs nav tik ā€œbezmaksasā€, pieaug arÄ« CPU noslodze.

Tomēr tas nav Ä«paÅ”i elegants risinājums, jo mēs iepriekÅ” nezinām, cik procentu bloku ir nepiecieÅ”ams saglabāt keÅ”atmiņā, tas ir atkarÄ«gs no slodzes profila. Tāpēc tika ieviests mehānisms Ŕī parametra automātiskai regulÄ“Å”anai atkarÄ«bā no lasÄ«Å”anas darbÄ«bu aktivitātes.

Lai to kontrolētu, ir pievienotas trīs iespējas:

hbase.lru.cache.heavy.eviction.count.limit ā€” iestata, cik reižu vajadzētu palaist datu izņemÅ”anas procesu no keÅ”atmiņas, pirms mēs sākam izmantot optimizāciju (t.i., izlaižot blokus). Pēc noklusējuma tas ir vienāds ar MAX_INT = 2147483647 un faktiski nozÄ«mē, ka lÄ«dzeklis nekad nesāks darboties ar Å”o vērtÄ«bu. Jo izlikÅ”anas process sākas ik pēc 5 - 10 sekundēm (tas ir atkarÄ«gs no slodzes) un 2147483647 * 10 / 60 / 60 / 24 / 365 = 680 gadi. Tomēr mēs varam iestatÄ«t Å”o parametru uz 0 un likt funkcijai darboties uzreiz pēc palaiÅ”anas.

Tomēr Å”ajā parametrā ir arÄ« lietderÄ«gā slodze. Ja mÅ«su slodze ir tāda, ka Ä«stermiņa nolasÄ«jumi (teiksim dienā) un ilgstoÅ”i (naktÄ«) ir nepārtraukti mijas, tad mēs varam pārliecināties, ka funkcija tiek ieslēgta tikai tad, kad notiek ilgstoÅ”as ā€‹ā€‹ā€‹ā€‹lasÄ«Å”anas darbÄ«bas.

Piemēram, mēs zinām, ka Ä«stermiņa rādÄ«jumi parasti ilgst apmēram 1 minÅ«ti. Nav jāsāk izmest blokus, keÅ”atmiņai nebÅ«s laika novecot un tad varam iestatÄ«t Å”o parametru vienādu, piemēram, ar 10. Tas novedÄ«s pie tā, ka optimizācija sāks darboties tikai tad, kad ilgi- termina aktÄ«vā lasÄ«Å”ana ir sākusies, t.i. 100 sekundēs. Tādējādi, ja mums ir Ä«slaicÄ«ga lasÄ«Å”ana, tad visi bloki nonāks keÅ”atmiņā un bÅ«s pieejami (izņemot tos, kas tiks izlikti ar standarta algoritmu). Un, veicot ilgstoÅ”as ā€‹ā€‹ā€‹ā€‹lasÄ«Å”anas, funkcija tiek ieslēgta, un mums bÅ«tu daudz augstāka veiktspēja.

hbase.lru.cache.heavy.eviction.mb.size.limit ā€” iestata, cik megabaitu mēs vēlētos ievietot keÅ”atmiņā (un, protams, izlikt) 10 sekundēs. Funkcija mēģinās sasniegt Å”o vērtÄ«bu un to uzturēt. Lieta ir Ŕāda: ja mēs ievietosim gigabaitus keÅ”atmiņā, mums bÅ«s jāizliek gigabaiti, un tas, kā redzējām iepriekÅ”, ir ļoti dārgi. Tomēr jums nevajadzētu mēģināt iestatÄ«t to pārāk mazu, jo tas izraisÄ«s priekÅ”laicÄ«gu bloÄ·Ä“Å”anas izlaiÅ”anas režīma izieÅ”anu. JaudÄ«giem serveriem (apmēram 20-40 fiziski kodoli) ir optimāli iestatÄ«t apmēram 300-400 MB. Vidējai klasei (~10 kodoli) 200-300 MB. Vājām sistēmām (2ā€“5 kodoli) 50ā€“100 MB var bÅ«t normāli (nav pārbaudÄ«ts Å”ajās ierÄ«cēs).

ApskatÄ«sim, kā tas darbojas: pieņemsim, ka mēs iestatām hbase.lru.cache.heavy.eviction.mb.size.limit = 500, ir kaut kāda slodze (lasÄ«Å”ana) un tad ik pēc ~ 10 sekundēm mēs aprēķinām, cik baitu bija izlikts, izmantojot formulu:

Pieskaitāmās izmaksas = atbrīvoto baitu summa (MB) * 100 / ierobežojums (MB) - 100;

Ja faktiski tika izlikti 2000 MB, tad pieskaitāmās izmaksas ir vienādas ar:

2000 * 100/500 - 100 = 300%

Algoritmi cenÅ”as saglabāt ne vairāk kā dažus desmitus procentu, tāpēc funkcija samazinās keÅ”atmiņā saglabāto bloku procentuālo daudzumu, tādējādi ievieÅ”ot automātiskās regulÄ“Å”anas mehānismu.

Tomēr, ja slodze samazinās, pieņemsim, ka tiek izlikti tikai 200 MB un Overhead kļūst negatÄ«vs (tā sauktā pārsniegÅ”ana):

200*100/500-100 = -60%

Gluži pretēji, Ŕī funkcija palielinās keÅ”atmiņā saglabāto bloku procentuālo daudzumu, lÄ«dz Overhead kļūs pozitÄ«vs.

Tālāk ir sniegts piemērs tam, kā tas izskatās uz reāliem datiem. Nav jācenÅ”as sasniegt 0%, tas nav iespējams. Tas ir ļoti labi, ja tas ir aptuveni 30 - 100%, tas palÄ«dz izvairÄ«ties no priekÅ”laicÄ«gas izieÅ”anas no optimizācijas režīma Ä«slaicÄ«gu pārspriegumu laikā.

hbase.lru.cache.heavy.eviction.overhead.coefficient ā€” nosaka, cik ātri mēs vēlamies iegÅ«t rezultātu. Ja mēs droÅ”i zinām, ka mÅ«su lasÄ«jumi lielākoties ir ilgi un nevēlamies gaidÄ«t, mēs varam palielināt Å”o attiecÄ«bu un ātrāk iegÅ«t augstu veiktspēju.

Piemēram, mēs iestatām Å”o koeficientu = 0.01. Tas nozÄ«mē, ka pieskaitāmās izmaksas (skatÄ«t iepriekÅ”) tiks reizinātas ar Å”o skaitli ar iegÅ«to rezultātu, un keÅ”atmiņā saglabāto bloku procentuālais daudzums tiks samazināts. Pieņemsim, ka Overhead = 300% un koeficients = 0.01, tad keÅ”atmiņā saglabāto bloku procentuālais daudzums tiks samazināts par 3%.

LÄ«dzÄ«ga ā€œPretspiedienaā€ loÄ£ika tiek ieviesta arÄ« negatÄ«vām pieskaitāmajām (pārsnieguma) vērtÄ«bām. Tā kā vienmēr ir iespējamas Ä«slaicÄ«gas nolasÄ«Å”anas un izlikÅ”anas apjoma svārstÄ«bas, Å”is mehānisms ļauj izvairÄ«ties no priekÅ”laicÄ«gas izieÅ”anas no optimizācijas režīma. Pretspiedienam ir apgriezta loÄ£ika: jo spēcÄ«gāks ir pārsniegums, jo vairāk bloku tiek saglabāts keÅ”atmiņā.

Kā palielināt lasÄ«Å”anas ātrumu no HBase lÄ«dz 3 reizēm un no HDFS lÄ«dz 5 reizēm

ÄŖstenoÅ”anas kods

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

Tagad aplÅ«kosim to visu, izmantojot reālu piemēru. Mums ir Ŕāds testa skripts:

  1. Sāksim veikt skenÄ“Å”anu (25 pavedieni, partija = 100)
  2. Pēc 5 minÅ«tēm pievienojiet multi-gets (25 pavedieni, partija = 100)
  3. Pēc 5 minÅ«tēm izslēdziet multi-gets (atkal paliek tikai skenÄ“Å”ana)

Mēs veicam divas darbības, vispirms hbase.lru.cache.heavy.eviction.count.limit = 10000 (kas faktiski atspējo funkciju), un pēc tam iestatām limitu = 0 (iespējo to).

Zemāk esoÅ”ajos žurnālos redzams, kā Ŕī funkcija ir ieslēgta, un pārsniegÅ”ana tiek atiestatÄ«ta uz 14ā€“71%. Ik pa laikam slodze samazinās, kas ieslēdz Backpressure un HBase atkal keÅ”atmiņā vairāk bloku.

Reģistrēties RegionServer
izlikts (MB): 0, koeficients 0.0, pieskaitāmās izmaksas (%): -100, lielais izlikÅ”anas skaitÄ«tājs: 0, paÅ”reizējā keÅ”atmiņa DataBlock (%): 100
izlikts (MB): 0, koeficients 0.0, pieskaitāmās izmaksas (%): -100, lielais izlikÅ”anas skaitÄ«tājs: 0, paÅ”reizējā keÅ”atmiņa DataBlock (%): 100
izlikts (MB): 2170, koeficients 1.09, pieskaitāmās izmaksas (%): 985, liels izlikÅ”anas skaitÄ«tājs: 1, paÅ”reizējā keÅ”atmiņa DataBlock (%): 91 < sākums
izlikts (MB): 3763, koeficients 1.08, pieskaitāmās izmaksas (%): 1781, lielais izlikÅ”anas skaitÄ«tājs: 2, paÅ”reizējā keÅ”atmiņa DataBlock (%): 76
izlikts (MB): 3306, koeficients 1.07, pieskaitāmās izmaksas (%): 1553, lielais izlikÅ”anas skaitÄ«tājs: 3, paÅ”reizējā keÅ”atmiņa DataBlock (%): 61
izlikts (MB): 2508, koeficients 1.06, pieskaitāmās izmaksas (%): 1154, lielais izlikÅ”anas skaitÄ«tājs: 4, paÅ”reizējā keÅ”atmiņa DataBlock (%): 50
izlikts (MB): 1824, koeficients 1.04, pieskaitāmās izmaksas (%): 812, lielais izlikÅ”anas skaitÄ«tājs: 5, paÅ”reizējā keÅ”atmiņa DataBlock (%): 42
izlikts (MB): 1482, koeficients 1.03, pieskaitāmās izmaksas (%): 641, lielais izlikÅ”anas skaitÄ«tājs: 6, paÅ”reizējā keÅ”atmiņa DataBlock (%): 36
izlikts (MB): 1140, koeficients 1.01, pieskaitāmās izmaksas (%): 470, lielais izlikÅ”anas skaitÄ«tājs: 7, paÅ”reizējā keÅ”atmiņa DataBlock (%): 32
izlikts (MB): 913, koeficients 1.0, pieskaitāmās izmaksas (%): 356, lielais izlikÅ”anas skaitÄ«tājs: 8, paÅ”reizējā keÅ”atmiņa DataBlock (%): 29
izlikts (MB): 912, koeficients 0.89, pieskaitāmās izmaksas (%): 356, lielais izlikÅ”anas skaitÄ«tājs: 9, paÅ”reizējā keÅ”atmiņa DataBlock (%): 26
izlikts (MB): 684, koeficients 0.76, pieskaitāmās izmaksas (%): 242, lielais izlikÅ”anas skaitÄ«tājs: 10, paÅ”reizējā keÅ”atmiņa DataBlock (%): 24
izlikts (MB): 684, koeficients 0.61, pieskaitāmās izmaksas (%): 242, lielais izlikÅ”anas skaitÄ«tājs: 11, paÅ”reizējā keÅ”atmiņa DataBlock (%): 22
izlikts (MB): 456, koeficients 0.51, pieskaitāmās izmaksas (%): 128, lielais izlikÅ”anas skaitÄ«tājs: 12, paÅ”reizējā keÅ”atmiņa DataBlock (%): 21
izlikts (MB): 456, koeficients 0.42, pieskaitāmās izmaksas (%): 128, lielais izlikÅ”anas skaitÄ«tājs: 13, paÅ”reizējā keÅ”atmiņa DataBlock (%): 20
izlikts (MB): 456, koeficients 0.33, pieskaitāmās izmaksas (%): 128, lielais izlikÅ”anas skaitÄ«tājs: 14, paÅ”reizējā keÅ”atmiņa DataBlock (%): 19
izlikts (MB): 342, koeficients 0.33, pieskaitāmās izmaksas (%): 71, lielais izlikÅ”anas skaitÄ«tājs: 15, paÅ”reizējā keÅ”atmiņa DataBlock (%): 19
izlikts (MB): 342, koeficients 0.32, pieskaitāmās izmaksas (%): 71, lielais izlikÅ”anas skaitÄ«tājs: 16, paÅ”reizējā keÅ”atmiņa DataBlock (%): 19
izlikts (MB): 342, koeficients 0.31, pieskaitāmās izmaksas (%): 71, lielais izlikÅ”anas skaitÄ«tājs: 17, paÅ”reizējā keÅ”atmiņa DataBlock (%): 19
izlikts (MB): 228, koeficients 0.3, pieskaitāmās izmaksas (%): 14, lielais izlikÅ”anas skaitÄ«tājs: 18, paÅ”reizējā keÅ”atmiņa DataBlock (%): 19
izlikts (MB): 228, koeficients 0.29, pieskaitāmās izmaksas (%): 14, lielais izlikÅ”anas skaitÄ«tājs: 19, paÅ”reizējā keÅ”atmiņa DataBlock (%): 19
izlikts (MB): 228, koeficients 0.27, pieskaitāmās izmaksas (%): 14, lielais izlikÅ”anas skaitÄ«tājs: 20, paÅ”reizējā keÅ”atmiņa DataBlock (%): 19
izlikts (MB): 228, koeficients 0.25, pieskaitāmās izmaksas (%): 14, lielais izlikÅ”anas skaitÄ«tājs: 21, paÅ”reizējā keÅ”atmiņa DataBlock (%): 19
izlikts (MB): 228, koeficients 0.24, pieskaitāmās izmaksas (%): 14, lielais izlikÅ”anas skaitÄ«tājs: 22, paÅ”reizējā keÅ”atmiņa DataBlock (%): 19
izlikts (MB): 228, koeficients 0.22, pieskaitāmās izmaksas (%): 14, lielais izlikÅ”anas skaitÄ«tājs: 23, paÅ”reizējā keÅ”atmiņa DataBlock (%): 19
izlikts (MB): 228, koeficients 0.21, pieskaitāmās izmaksas (%): 14, lielais izlikÅ”anas skaitÄ«tājs: 24, paÅ”reizējā keÅ”atmiņa DataBlock (%): 19
izlikts (MB): 228, koeficients 0.2, pieskaitāmās izmaksas (%): 14, lielais izlikÅ”anas skaitÄ«tājs: 25, paÅ”reizējā keÅ”atmiņa DataBlock (%): 19
izlikts (MB): 228, koeficients 0.17, pieskaitāmās izmaksas (%): 14, lielais izlikÅ”anas skaitÄ«tājs: 26, paÅ”reizējā keÅ”atmiņa DataBlock (%): 19
izlikts (MB): 456, koeficients 0.17, pieskaitāmās izmaksas (%): 128, lielais izlikÅ”anas skaitÄ«tājs: 27, paÅ”reizējā keÅ”atmiņa DataBlock (%): 18 < pievienotie saņem (bet tabula tā pati)
izlikts (MB): 456, koeficients 0.15, pieskaitāmās izmaksas (%): 128, lielais izlikÅ”anas skaitÄ«tājs: 28, paÅ”reizējā keÅ”atmiņa DataBlock (%): 17
izlikts (MB): 342, koeficients 0.13, pieskaitāmās izmaksas (%): 71, lielais izlikÅ”anas skaitÄ«tājs: 29, paÅ”reizējā keÅ”atmiņa DataBlock (%): 17
izlikts (MB): 342, koeficients 0.11, pieskaitāmās izmaksas (%): 71, lielais izlikÅ”anas skaitÄ«tājs: 30, paÅ”reizējā keÅ”atmiņa DataBlock (%): 17
izlikts (MB): 342, koeficients 0.09, pieskaitāmās izmaksas (%): 71, lielais izlikÅ”anas skaitÄ«tājs: 31, paÅ”reizējā keÅ”atmiņa DataBlock (%): 17
izlikts (MB): 228, koeficients 0.08, pieskaitāmās izmaksas (%): 14, lielais izlikÅ”anas skaitÄ«tājs: 32, paÅ”reizējā keÅ”atmiņa DataBlock (%): 17
izlikts (MB): 228, koeficients 0.07, pieskaitāmās izmaksas (%): 14, lielais izlikÅ”anas skaitÄ«tājs: 33, paÅ”reizējā keÅ”atmiņa DataBlock (%): 17
izlikts (MB): 228, koeficients 0.06, pieskaitāmās izmaksas (%): 14, lielais izlikÅ”anas skaitÄ«tājs: 34, paÅ”reizējā keÅ”atmiņa DataBlock (%): 17
izlikts (MB): 228, koeficients 0.05, pieskaitāmās izmaksas (%): 14, lielais izlikÅ”anas skaitÄ«tājs: 35, paÅ”reizējā keÅ”atmiņa DataBlock (%): 17
izlikts (MB): 228, koeficients 0.05, pieskaitāmās izmaksas (%): 14, lielais izlikÅ”anas skaitÄ«tājs: 36, paÅ”reizējā keÅ”atmiņa DataBlock (%): 17
izlikts (MB): 228, koeficients 0.04, pieskaitāmās izmaksas (%): 14, lielais izlikÅ”anas skaitÄ«tājs: 37, paÅ”reizējā keÅ”atmiņa DataBlock (%): 17
izlikts (MB): 109, koeficients 0.04, pieskaitāmās izmaksas (%): -46, liels izlikÅ”anas skaitÄ«tājs: 37, paÅ”reizējā keÅ”atmiņa DataBlock (%): 22 < pretspiediens
izlikts (MB): 798, koeficients 0.24, pieskaitāmās izmaksas (%): 299, lielais izlikÅ”anas skaitÄ«tājs: 38, paÅ”reizējā keÅ”atmiņa DataBlock (%): 20
izlikts (MB): 798, koeficients 0.29, pieskaitāmās izmaksas (%): 299, lielais izlikÅ”anas skaitÄ«tājs: 39, paÅ”reizējā keÅ”atmiņa DataBlock (%): 18
izlikts (MB): 570, koeficients 0.27, pieskaitāmās izmaksas (%): 185, lielais izlikÅ”anas skaitÄ«tājs: 40, paÅ”reizējā keÅ”atmiņa DataBlock (%): 17
izlikts (MB): 456, koeficients 0.22, pieskaitāmās izmaksas (%): 128, lielais izlikÅ”anas skaitÄ«tājs: 41, paÅ”reizējā keÅ”atmiņa DataBlock (%): 16
izlikts (MB): 342, koeficients 0.16, pieskaitāmās izmaksas (%): 71, lielais izlikÅ”anas skaitÄ«tājs: 42, paÅ”reizējā keÅ”atmiņa DataBlock (%): 16
izlikts (MB): 342, koeficients 0.11, pieskaitāmās izmaksas (%): 71, lielais izlikÅ”anas skaitÄ«tājs: 43, paÅ”reizējā keÅ”atmiņa DataBlock (%): 16
izlikts (MB): 228, koeficients 0.09, pieskaitāmās izmaksas (%): 14, lielais izlikÅ”anas skaitÄ«tājs: 44, paÅ”reizējā keÅ”atmiņa DataBlock (%): 16
izlikts (MB): 228, koeficients 0.07, pieskaitāmās izmaksas (%): 14, lielais izlikÅ”anas skaitÄ«tājs: 45, paÅ”reizējā keÅ”atmiņa DataBlock (%): 16
izlikts (MB): 228, koeficients 0.05, pieskaitāmās izmaksas (%): 14, lielais izlikÅ”anas skaitÄ«tājs: 46, paÅ”reizējā keÅ”atmiņa DataBlock (%): 16
izlikts (MB): 222, koeficients 0.04, pieskaitāmās izmaksas (%): 11, lielais izlikÅ”anas skaitÄ«tājs: 47, paÅ”reizējā keÅ”atmiņa DataBlock (%): 16
izlikts (MB): 104, koeficients 0.03, pieskaitāmās izmaksas (%): -48, liels izlikÅ”anas skaitÄ«tājs: 47, paÅ”reizējā keÅ”atmiņa DataBlock (%): 21 < pārtraukt izpaužas
izlikts (MB): 684, koeficients 0.2, pieskaitāmās izmaksas (%): 242, lielais izlikÅ”anas skaitÄ«tājs: 48, paÅ”reizējā keÅ”atmiņa DataBlock (%): 19
izlikts (MB): 570, koeficients 0.23, pieskaitāmās izmaksas (%): 185, lielais izlikÅ”anas skaitÄ«tājs: 49, paÅ”reizējā keÅ”atmiņa DataBlock (%): 18
izlikts (MB): 342, koeficients 0.22, pieskaitāmās izmaksas (%): 71, lielais izlikÅ”anas skaitÄ«tājs: 50, paÅ”reizējā keÅ”atmiņa DataBlock (%): 18
izlikts (MB): 228, koeficients 0.21, pieskaitāmās izmaksas (%): 14, lielais izlikÅ”anas skaitÄ«tājs: 51, paÅ”reizējā keÅ”atmiņa DataBlock (%): 18
izlikts (MB): 228, koeficients 0.2, pieskaitāmās izmaksas (%): 14, lielais izlikÅ”anas skaitÄ«tājs: 52, paÅ”reizējā keÅ”atmiņa DataBlock (%): 18
izlikts (MB): 228, koeficients 0.18, pieskaitāmās izmaksas (%): 14, lielais izlikÅ”anas skaitÄ«tājs: 53, paÅ”reizējā keÅ”atmiņa DataBlock (%): 18
izlikts (MB): 228, koeficients 0.16, pieskaitāmās izmaksas (%): 14, lielais izlikÅ”anas skaitÄ«tājs: 54, paÅ”reizējā keÅ”atmiņa DataBlock (%): 18
izlikts (MB): 228, koeficients 0.14, pieskaitāmās izmaksas (%): 14, lielais izlikÅ”anas skaitÄ«tājs: 55, paÅ”reizējā keÅ”atmiņa DataBlock (%): 18
izlikts (MB): 112, koeficients 0.14, pieskaitāmās izmaksas (%): -44, liels izlikÅ”anas skaitÄ«tājs: 55, paÅ”reizējā keÅ”atmiņa DataBlock (%): 23 < pretspiediens
izlikts (MB): 456, koeficients 0.26, pieskaitāmās izmaksas (%): 128, lielais izlikÅ”anas skaitÄ«tājs: 56, paÅ”reizējā keÅ”atmiņa DataBlock (%): 22
izlikts (MB): 342, koeficients 0.31, pieskaitāmās izmaksas (%): 71, lielais izlikÅ”anas skaitÄ«tājs: 57, paÅ”reizējā keÅ”atmiņa DataBlock (%): 22
izlikts (MB): 342, koeficients 0.33, pieskaitāmās izmaksas (%): 71, lielais izlikÅ”anas skaitÄ«tājs: 58, paÅ”reizējā keÅ”atmiņa DataBlock (%): 22
izlikts (MB): 342, koeficients 0.33, pieskaitāmās izmaksas (%): 71, lielais izlikÅ”anas skaitÄ«tājs: 59, paÅ”reizējā keÅ”atmiņa DataBlock (%): 22
izlikts (MB): 342, koeficients 0.33, pieskaitāmās izmaksas (%): 71, lielais izlikÅ”anas skaitÄ«tājs: 60, paÅ”reizējā keÅ”atmiņa DataBlock (%): 22
izlikts (MB): 342, koeficients 0.33, pieskaitāmās izmaksas (%): 71, lielais izlikÅ”anas skaitÄ«tājs: 61, paÅ”reizējā keÅ”atmiņa DataBlock (%): 22
izlikts (MB): 342, koeficients 0.33, pieskaitāmās izmaksas (%): 71, lielais izlikÅ”anas skaitÄ«tājs: 62, paÅ”reizējā keÅ”atmiņa DataBlock (%): 22
izlikts (MB): 342, koeficients 0.33, pieskaitāmās izmaksas (%): 71, lielais izlikÅ”anas skaitÄ«tājs: 63, paÅ”reizējā keÅ”atmiņa DataBlock (%): 22
izlikts (MB): 342, koeficients 0.32, pieskaitāmās izmaksas (%): 71, lielais izlikÅ”anas skaitÄ«tājs: 64, paÅ”reizējā keÅ”atmiņa DataBlock (%): 22
izlikts (MB): 342, koeficients 0.33, pieskaitāmās izmaksas (%): 71, lielais izlikÅ”anas skaitÄ«tājs: 65, paÅ”reizējā keÅ”atmiņa DataBlock (%): 22
izlikts (MB): 342, koeficients 0.33, pieskaitāmās izmaksas (%): 71, lielais izlikÅ”anas skaitÄ«tājs: 66, paÅ”reizējā keÅ”atmiņa DataBlock (%): 22
izlikts (MB): 342, koeficients 0.32, pieskaitāmās izmaksas (%): 71, lielais izlikÅ”anas skaitÄ«tājs: 67, paÅ”reizējā keÅ”atmiņa DataBlock (%): 22
izlikts (MB): 342, koeficients 0.33, pieskaitāmās izmaksas (%): 71, lielais izlikÅ”anas skaitÄ«tājs: 68, paÅ”reizējā keÅ”atmiņa DataBlock (%): 22
izlikts (MB): 342, koeficients 0.32, pieskaitāmās izmaksas (%): 71, lielais izlikÅ”anas skaitÄ«tājs: 69, paÅ”reizējā keÅ”atmiņa DataBlock (%): 22
izlikts (MB): 342, koeficients 0.32, pieskaitāmās izmaksas (%): 71, lielais izlikÅ”anas skaitÄ«tājs: 70, paÅ”reizējā keÅ”atmiņa DataBlock (%): 22
izlikts (MB): 342, koeficients 0.33, pieskaitāmās izmaksas (%): 71, lielais izlikÅ”anas skaitÄ«tājs: 71, paÅ”reizējā keÅ”atmiņa DataBlock (%): 22
izlikts (MB): 342, koeficients 0.33, pieskaitāmās izmaksas (%): 71, lielais izlikÅ”anas skaitÄ«tājs: 72, paÅ”reizējā keÅ”atmiņa DataBlock (%): 22
izlikts (MB): 342, koeficients 0.33, pieskaitāmās izmaksas (%): 71, lielais izlikÅ”anas skaitÄ«tājs: 73, paÅ”reizējā keÅ”atmiņa DataBlock (%): 22
izlikts (MB): 342, koeficients 0.33, pieskaitāmās izmaksas (%): 71, lielais izlikÅ”anas skaitÄ«tājs: 74, paÅ”reizējā keÅ”atmiņa DataBlock (%): 22
izlikts (MB): 342, koeficients 0.33, pieskaitāmās izmaksas (%): 71, lielais izlikÅ”anas skaitÄ«tājs: 75, paÅ”reizējā keÅ”atmiņa DataBlock (%): 22
izlikts (MB): 342, koeficients 0.33, pieskaitāmās izmaksas (%): 71, lielais izlikÅ”anas skaitÄ«tājs: 76, paÅ”reizējā keÅ”atmiņa DataBlock (%): 22
izlikts (MB): 21, koeficients 0.33, pieskaitāmās izmaksas (%): -90, lielais izlikÅ”anas skaitÄ«tājs: 76, paÅ”reizējā keÅ”atmiņa DataBlock (%): 32
izlikts (MB): 0, koeficients 0.0, pieskaitāmās izmaksas (%): -100, lielais izlikÅ”anas skaitÄ«tājs: 0, paÅ”reizējā keÅ”atmiņa DataBlock (%): 100
izlikts (MB): 0, koeficients 0.0, pieskaitāmās izmaksas (%): -100, lielais izlikÅ”anas skaitÄ«tājs: 0, paÅ”reizējā keÅ”atmiņa DataBlock (%): 100

SkenÄ“Å”ana bija nepiecieÅ”ama, lai parādÄ«tu vienu un to paÅ”u procesu attiecÄ«bu diagrammas veidā starp divām keÅ”atmiņas sadaļām - vienu (kurā bloki, kas nekad iepriekÅ” nav pieprasÄ«ti) un vairāku (Å”eit tiek glabāti vismaz vienu reizi ā€œpieprasÄ«tieā€ dati):

Kā palielināt lasÄ«Å”anas ātrumu no HBase lÄ«dz 3 reizēm un no HDFS lÄ«dz 5 reizēm

Un visbeidzot, kā izskatās parametru darbÄ«ba grafika veidā. SalÄ«dzinājumam sākumā keÅ”atmiņa tika pilnÄ«bā izslēgta, pēc tam tika palaists HBase ar keÅ”atmiņu un optimizācijas darbu sākÅ”anas aizkavÄ“Å”anu par 5 minÅ«tēm (30 izlikÅ”anas cikli).

Pilnu kodu var atrast Pull Request HBASE 23887 vietnē github.

Tomēr 300 tÅ«kstoÅ”i nolasÄ«jumu sekundē nav viss, ko ar Å”o aparatÅ«ru var sasniegt Ŕādos apstākļos. Fakts ir tāds, ka, ja jums ir nepiecieÅ”ams piekļūt datiem, izmantojot HDFS, tiek izmantots ShortCircuitCache (turpmāk tekstā SSC) mehānisms, kas ļauj piekļūt datiem tieÅ”i, izvairoties no tÄ«kla mijiedarbÄ«bas.

ProfilÄ“Å”ana parādÄ«ja, ka, lai gan Å”is mehānisms dod lielu peļņu, tas kādā brÄ«dÄ« kļūst arÄ« par saÅ”aurinājumu, jo gandrÄ«z visas smagās darbÄ«bas notiek slēdzenes iekÅ”pusē, kas lielākoties noved pie bloÄ·Ä“Å”anas.

Kā palielināt lasÄ«Å”anas ātrumu no HBase lÄ«dz 3 reizēm un no HDFS lÄ«dz 5 reizēm

To sapratuÅ”i, mēs sapratām, ka problēmu var apiet, izveidojot neatkarÄ«gu SSC masÄ«vu:

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

Un pēc tam strādājiet ar tiem, izņemot krustojumus arī pie pēdējā nobīdes cipara:

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

Tagad jÅ«s varat sākt testÄ“Å”anu. Lai to izdarÄ«tu, mēs nolasÄ«sim failus no HDFS, izmantojot vienkārÅ”u daudzpavedienu lietojumprogrammu. Iestatiet parametrus:

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

Un vienkārŔi izlasiet failus:

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

Å is kods tiek izpildÄ«ts atseviŔķos pavedienos, un mēs palielināsim vienlaicÄ«gi nolasāmo failu skaitu (no 10 lÄ«dz 200 - horizontālā ass) un keÅ”atmiņu skaitu (no 1 lÄ«dz 10 - grafikas). Vertikālā ass parāda paātrinājumu, kas rodas, palielinoties SSC, salÄ«dzinot ar gadÄ«jumu, kad ir tikai viena keÅ”atmiņa.

Kā palielināt lasÄ«Å”anas ātrumu no HBase lÄ«dz 3 reizēm un no HDFS lÄ«dz 5 reizēm

Kā lasÄ«t grafiku: izpildes laiks 100 tÅ«kstoÅ”iem nolasÄ«jumu 64 KB blokos ar vienu keÅ”atmiņu prasa 78 sekundes. Savukārt ar 5 keÅ”atmiņām tas aizņem 16 sekundes. Tie. ir ~5 reizes paātrinājums. Kā redzams no grafika, efekts nav Ä«paÅ”i pamanāms nelielam paralēlu nolasÄ«jumu skaitam, tas sāk spēlēt pamanāmu lomu, kad pavedienu nolasÄ«jumu skaits pārsniedz 50. Tāpat ir pamanāms, ka SSC skaita palielināŔana no 6 un augstāk, nodroÅ”ina ievērojami mazāku veiktspējas pieaugumu.

1. piezīme: tā kā testa rezultāti ir diezgan nepastāvīgi (skatīt zemāk), tika veikti 3 braucieni un iegūtās vērtības tika aprēķinātas vidējās.

2. piezÄ«me. Veiktspējas ieguvums no nejauŔās piekļuves konfigurÄ“Å”anas ir vienāds, lai gan pati piekļuve ir nedaudz lēnāka.

Tomēr ir jāprecizē, ka atŔķirÄ«bā no HBase gadÄ«juma Å”is paātrinājums ne vienmēr ir bezmaksas. Å eit mēs ā€œatbloķējamā€ CPU spēju strādāt vairāk, nevis karāties uz slēdzenēm.

Kā palielināt lasÄ«Å”anas ātrumu no HBase lÄ«dz 3 reizēm un no HDFS lÄ«dz 5 reizēm

Å eit var novērot, ka kopumā keÅ”atmiņu skaita pieaugums rada aptuveni proporcionālu CPU izmantoÅ”anas pieaugumu. Tomēr ir nedaudz vairāk uzvaroÅ”o kombināciju.

Piemēram, aplÅ«kosim tuvāk iestatÄ«jumu SSC = 3. Veiktspējas pieaugums diapazonā ir aptuveni 3.3 reizes. Zemāk ir visu trÄ«s atseviŔķu braucienu rezultāti.

Kā palielināt lasÄ«Å”anas ātrumu no HBase lÄ«dz 3 reizēm un no HDFS lÄ«dz 5 reizēm

Kamēr CPU patēriņŔ palielinās apmēram 2.8 reizes. AtŔķirÄ«ba nav Ä«paÅ”i liela, bet mazā Grēta jau ir laimÄ«ga un varbÅ«t paspēs apmeklēt skolu un nodarbÄ«bas.

Tādējādi tam bÅ«s pozitÄ«va ietekme uz jebkuru rÄ«ku, kas izmanto lielapjoma piekļuvi HDFS (piemēram, Spark u.c.), ja lietojumprogrammas kods ir viegls (t.i., spraudnis atrodas HDFS klienta pusē) un ir brÄ«va CPU jauda. . Lai pārbaudÄ«tu, pārbaudÄ«sim, kādu efektu radÄ«s BlockCache optimizācijas un SSC noregulÄ“Å”anas kombinēta izmantoÅ”ana lasÄ«Å”anai no HBase.

Kā palielināt lasÄ«Å”anas ātrumu no HBase lÄ«dz 3 reizēm un no HDFS lÄ«dz 5 reizēm

Redzams, ka Ŕādos apstākļos efekts nav tik liels kā rafinētajos testos (lasot bez jebkādas apstrādes), taču Å”eit ir pilnÄ«gi iespējams izspiest papildus 80K. Abas optimizācijas kopā nodroÅ”ina lÄ«dz pat 4x paātrinājumu.

Par Ŕo optimizāciju tika izveidots arī PR [HDFS-15202], kas ir apvienota, un Ŕī funkcionalitāte būs pieejama turpmākajos laidienos.

Un visbeidzot, bija interesanti salÄ«dzināt lasÄ«Å”anas veiktspēju lÄ«dzÄ«gai plaÅ”a kolonnu datubāzei Cassandra un HBase.

Lai to paveiktu, mēs palaižām standarta YCSB slodzes testÄ“Å”anas utilÄ«ta gadÄ«jumus no diviem saimniekiem (kopā 800 pavedieni). Servera pusē - 4 RegionServer un Cassandra gadÄ«jumi uz 4 saimniekiem (ne tie, kuros darbojas klienti, lai izvairÄ«tos no viņu ietekmes). RādÄ«jumi tika iegÅ«ti no lieluma tabulām:

HBase ā€” 300 GB HDFS (100 GB tÄ«ri dati)

Cassandra ā€” 250 GB (replikācijas koeficients = 3)

Tie. apjoms bija aptuveni tāds pats (HBase nedaudz vairāk).

HBase parametri:

dfs.client.short.circuit.num = 5 (HDFS klienta optimizācija)

hbase.lru.cache.heavy.eviction.count.limit = 30 - tas nozÄ«mē, ka plāksteris sāks darboties pēc 30 izlikÅ”anas (~5 minÅ«tes)

hbase.lru.cache.heavy.eviction.mb.size.limit = 300 ā€” keÅ”atmiņas un izlikÅ”anas mērÄ·a apjoms

YCSB žurnāli tika parsēti un apkopoti Excel grafikos:

Kā palielināt lasÄ«Å”anas ātrumu no HBase lÄ«dz 3 reizēm un no HDFS lÄ«dz 5 reizēm

Kā redzat, Ŕīs optimizācijas ļauj salÄ«dzināt Å”o datu bāzu veiktspēju Å”ajos apstākļos un sasniegt 450 tÅ«kstoÅ”us nolasÄ«jumu sekundē.

Mēs ceram, ka Ŕī informācija kādam var noderēt aizraujoÅ”ajā cīņā par produktivitāti.

Avots: www.habr.com

Pievieno komentāru