Cara nambah kacepetan maca saka HBase nganti 3 kaping lan saka HDFS nganti 5 kaping

Kinerja dhuwur minangka salah sawijining syarat utama nalika nggarap data gedhe. Kita, ing manajemen pemuatan data ing Sberbank, ngompa meh kabeh transaksi menyang Cloud Data berbasis Hadoop lan mulane kita ngatasi arus informasi sing gedhe banget. Alamiah, kita tansah golek cara kanggo nambah kinerja, lan saiki kita arep kanggo pitutur marang kowe carane kita ngatur kanggo tembelan RegionServer HBase lan HDFS klien, kang ndadekake iku bisa kanggo Ngartekno nambah kacepetan operasi maca.
Cara nambah kacepetan maca saka HBase nganti 3 kaping lan saka HDFS nganti 5 kaping

Nanging, sadurunge pindhah menyang inti saka dandan, iku worth ngomong bab watesan sing, ing asas, ora bisa bypassed yen njagong ing HDD.

Napa HDD lan Waca Akses Acak Cepet Ora Kompatibel
Kaya sing sampeyan ngerteni, HBase, lan akeh database liyane, nyimpen data ing blok kanthi ukuran puluhan kilobyte. Kanthi gawan, iki kira-kira 64 KB. Saiki bayangake yen kita mung kudu entuk 100 bita lan njaluk HBase kanggo menehi data iki nggunakake kunci tartamtu. Amarga ukuran blok ing HFiles 64 KB, panjaluk kasebut bakal 640 kaping luwih gedhe (mung semenit!)

Salajengipun, amarga panyuwunan bakal liwat HDFS lan mekanisme caching metadata ShortCircuitCache (sing ngidini akses langsung menyang file), banjur iki asil maca wis 1 MB saka disk. Nanging, iki bisa diatur kanthi parameter dfs.client.read.shortcircuit.buffer.size lan ing akeh kasus iku ndadekake pangertèn kanggo nyuda Nilai iki, contone, kanggo 126 KB.

Ayo dadi ngomong kita nindakake iki, nanging ing Kajaba iku, nalika kita miwiti maca data liwat java api, karo fungsi kayata FileChannel.read lan takon sistem operasi kanggo maca jumlah tartamtu saka data, subtracts "mung ing kasus" 2 kaping luwih. , i.e. ing 256 KB ing kasus kita. Iki amarga ora ana cara gampang ing java kanggo nyetel gendΓ©ra FADV_RANDOM kanggo nyegah prilaku iki.

AkibatΓ©, kanggo entuk 100 bait, 2600 kaping luwih dikurangi ing sangisore tutup. Iku bakal katon yen solusi iku ketok, ayo kang nyuda ukuran pemblokiran kanggo kilobyte, nyetel flag kasebut lan gain akselerasi gamblang gedhe. Nanging masalahe yaiku kanthi nyuda ukuran blok kaping 2, kita uga nyuda jumlah bita sing dikurangi saben unit wektu kanthi kaping 2.

Sawetara gain saka nyetel gendΓ©ra FADV_RANDOM bisa dipikolehi, nanging mung karo multithreading dhuwur lan ukuran blok 128 KB, nanging iki maksimum saperangan saka puluhan persen:

Cara nambah kacepetan maca saka HBase nganti 3 kaping lan saka HDFS nganti 5 kaping

Tes kasebut ditindakake ing 100 file, saben ukuran 1 GB lan ana ing 10 HDD.

Ayo ngetung apa sing bisa dianggep kanthi kacepetan kaya ngono:
Ayo kita maca saka 10 disk kanthi kacepetan 280 MB / s, i.e. 3 yuta kaping 100 bait. Nanging nalika elinga, kita butuh data sing 2600 kaping kurang saka sing diwaca. Mangkono, kita dibagi 3 yuta dening 2600 lan entuk 1100 cathetan saben detik.

Kuciwane, ta? Kuwi sifate Akses Random akses menyang data ing HDD - preduli saka ukuran pemblokiran. Iki watesan fisik akses acak, lan ora database bisa remet metu liyane ing kahanan kuwi.

Kepiye carane basis bisa entuk kecepatan sing luwih dhuwur? Kanggo njawab pitakonan iki, ayo padha ndeleng apa sing kedadeyan ing gambar ing ngisor iki:

Cara nambah kacepetan maca saka HBase nganti 3 kaping lan saka HDFS nganti 5 kaping

Kene kita waca sing sawetara menit pisanan kacepetan tenan bab ewu cathetan per detik. Nanging, luwih, amarga kasunyatane luwih akeh sing dikurangi tinimbang sing dijaluk, data disimpen ing buff / cache sistem operasi (linux) lan kacepetan mundhak nganti 60 ewu per detik.

Mangkono, luwih, kita bakal ngatasi akses cepet mung kanggo data sing ana ing cache OS utawa ana ing panyimpenan SSD / NVMe kanthi kecepatan akses sing padha.

Ing kasus kita, kita bakal nganakake tes ing 4 server, saben-saben dikenani biaya kaya ing ngisor iki:

CPU: Xeon E5-2680 v4 @ 2.40GHz 64 utas.
Memori: 730 GB.
versi java: 1.8.0_111

Lan ing kene titik utama yaiku jumlah data ing tabel sing kudu diwaca. Kasunyatane yaiku yen sampeyan maca data saka tabel sing cocog karo cache HBase, mula ora bakal diwaca saka buff / cache sistem operasi. Amarga HBase minangka standar allocates 40% saka memori kanggo struktur disebut BlockCache. Nyatane, iki minangka ConcurrentHashMap, ing ngendi kunci yaiku jeneng file + offset blok, lan nilai kasebut minangka data nyata ing offset iki.

Mangkono, nalika maca mung saka struktur iki, kita ndeleng kacepetan gedhe, kaya yuta panjalukan saben detik. Nanging ayo kang mbayangno sing kita ora bisa menehi atusan gigabyte memori mung kanggo kabutuhan database, amarga akeh liyane migunani sing muter ing server iki.

Contone, ing kasus kita, volume BlockCache ing siji RS kira-kira 12 GB. We ndharat loro RS ing siji simpul, i.e. 96 GB dialokasikan kanggo BlockCache ing kabeh simpul. Lan ing wektu sing padha, ana luwih akeh data, contone, dadi 4 tabel, 130 wilayah saben, ing ngendi file ukuran 800 MB, dikompress dening FAST_DIFF, i.e. total 410 GB (iki data murni, IE tanpa njupuk menyang akun faktor rΓ©plikasi).

Mangkono, BlockCache mung udakara 23% saka total data lan iki luwih cedhak karo kahanan nyata sing diarani BigData. Lan ing kene sing paling menarik diwiwiti - sawise kabeh, jelas yen cache sing luwih sithik, kinerja sing luwih elek. Sawise kabeh, ing cilik saka miss, sampeyan kudu nindakake akèh karya - i.e. mudhun sadurunge nelpon fungsi sistem. Nanging, iki ora bisa nyingkiri, lan mulane ayo nimbang aspek sing beda - apa sing kedadeyan ing data ing cache?

Ayo dadi menakake kahanan lan nganggep yen kita duwe cache sing mung 1 obyek diselehake. Iki minangka conto apa sing kedadeyan nalika nyoba nggarap volume data kaping 3 luwih gedhe tinimbang cache, kita kudu:

1. Selehake blok 1 ing cache
2. Mbusak pamblokiran 1 saka cache
3. Selehake blok 2 ing cache
4. Mbusak pamblokiran 2 saka cache
5. Selehake blok 3 ing cache

Rampung 5 tumindak! Nanging, kahanan iki ora bisa diarani normal, nyatane, kita meksa HBase nindakake akeh karya sing ora ana gunane. Dheweke terus maca data saka cache OS, dilebokake ing BlockCache, supaya bisa langsung dibuwang, amarga bagean data anyar wis teka. Animasi ing wiwitan kiriman nuduhake inti masalah - Penagih Sampah ora ana ing tangga lagu, swasana dadi panas, Greta cilik dadi gupuh ing Swedia sing adoh lan panas. Lan kita wong IT pancene ora seneng yen bocah-bocah sedhih, mula kita mikir apa sing bisa ditindakake.

Nanging apa yen ora kabeh pamblokiran diselehake ing cache, nanging mung persentasi tartamtu saka wong-wong mau, supaya cache ora kebanjiran? Ayo diwiwiti kanthi nambahake sawetara baris kode ing sisih ndhuwur fungsi push BlockCache:

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

Makna ing kene yaiku ing ngisor iki, offset minangka posisi blok ing file lan digit pungkasan kasebut disebarake kanthi acak lan merata saka 00 nganti 99. Mulane, kita bakal ngliwati mung sing ana ing kisaran sing dibutuhake.

Contone, atur cacheDataBlockPercent = 20 lan deleng apa sing kedadeyan:

Cara nambah kacepetan maca saka HBase nganti 3 kaping lan saka HDFS nganti 5 kaping

Asil ana. Ing grafik ing ngisor iki, dadi jelas kenapa akselerasi iki kedadeyan - kita nyimpen akeh sumber daya GC tanpa nindakake tenaga kerja Sisyphean kanggo nyelehake data ing cache mung kanggo langsung mbuwang asu Martian:

Cara nambah kacepetan maca saka HBase nganti 3 kaping lan saka HDFS nganti 5 kaping

Ing wektu sing padha, panggunaan CPU mundhak, nanging luwih sithik tinimbang kinerja:

Cara nambah kacepetan maca saka HBase nganti 3 kaping lan saka HDFS nganti 5 kaping

Sampeyan uga kudu dicathet yen blok sing disimpen ing BlockCache beda-beda. Umume, udakara 95%, yaiku data dhewe. Lan liyane minangka metadata, kaya saringan Bloom utawa LEAF_INDEX lan lsp.. Data iki ora cukup, nanging migunani banget, amarga sadurunge ngowahi langsung menyang data, HBase nuduhake meta kanggo mangerteni apa perlu katon luwih kene lan yen mangkono, ing ngendi persis blok kapentingan kasebut.

Mulane, ing kode kita ndeleng mriksa kondisi buf.getBlockType().isData() lan thanks kanggo meta iki, kita bakal tetep ing cache.

Saiki ayo nambah beban lan ing wektu sing padha rada nyetel fitur kasebut. Ing tes pisanan, kita nggawe persentase cutoff = 20 lan BlockCache rada kurang. Saiki ayo nyetel dadi 23% lan tambahake 100 utas saben 5 menit kanggo ndeleng nalika kejenuhan kedadeyan:

Cara nambah kacepetan maca saka HBase nganti 3 kaping lan saka HDFS nganti 5 kaping

Ing kene kita weruh yen versi asli meh langsung tekan langit-langit ing babagan 100 ewu panjalukan per detik. Dene tambalan menehi akselerasi nganti 300 ewu. Ing wektu sing padha, jelas yen akselerasi luwih cepet ora "gratis" maneh, dene panggunaan CPU uga saya akeh.

Nanging, iki dudu solusi sing elegan banget, amarga kita ora ngerti luwih dhisik apa persentase blok sing bakal disimpen, gumantung saka profil beban. Mulane, mekanisme dileksanakake kanggo nyetel parameter iki kanthi otomatis gumantung saka aktivitas operasi maca.

Telung opsi wis ditambahake kanggo ngontrol iki:

hbase.lru.cache.heavy.eviction.count.limit - nyetel kaping pirang-pirang proses evicting data saka cache kudu diwiwiti sadurunge kita miwiti nggunakake optimasi (i.e. skip pamblokiran). Kanthi gawan, padha karo MAX_INT = 2147483647 lan tegese fitur kasebut ora bakal bisa digunakake kanthi nilai iki. Amarga proses eviction diwiwiti saben 5 - 10 detik (gumantung saka beban) lan 2147483647 * 10 / 60 / 60 / 24 / 365 = 680 taun. Nanging, kita bisa nyetel parameter iki dadi 0 lan nggawe fitur bisa langsung sawise wiwitan.

Nanging, ana uga beban ing parameter iki. Yen kita duwe sifat beban kayata maca jangka pendek (umpamane nalika awan) lan maca jangka panjang (ing wayah wengi) terus diselingi, mula kita bisa nguripake fitur kasebut mung nalika operasi maca jangka panjang ing proses.

Contone, kita ngerti manawa maca jangka pendek biasane udakara 1 menit. Ora perlu miwiti mbuwang blok, cache ora bakal duwe wektu dadi lungse, banjur kita bisa nyetel parameter iki, contone, 10. Iki bakal nyebabake kasunyatan manawa optimasi bakal diwiwiti mung nalika maca aktif dawa. wis diwiwiti, i. sawise 100 detik. Mangkono, yen kita duwe maca jangka pendek, kabeh blok bakal mlebu ing cache lan bakal kasedhiya (kajaba sing bakal diusir dening algoritma standar). Lan nalika maca jangka panjang, fitur kasebut urip lan kita bakal entuk kinerja sing luwih apik.

hbase.lru.cache.heavy.eviction.mb.size.limit - nyetel pira megabyte sing pengin dilebokake ing cache (lan diusir kanthi alami) sajrone 10 detik. Fitur kasebut bakal nyoba nggayuh nilai kasebut lan njaga. Intine, yen kita nyurung gigabyte menyang cache, banjur gigabyte kudu diusir, lan iki, kaya sing kita deleng ing ndhuwur, larang banget. Nanging, sampeyan ora kudu nyoba nyetel iku cilik banget, amarga iki bakal mimpin kanggo metu durung wayahe saka mode skipping pemblokiran. Kanggo server kuat (kira-kira 20-40 inti fisik), iku optimal kanggo nyetel bab 300-400 MB. Kanggo kelas menengah (~ 10 intine) 200-300 MB. Kanggo sistem sing ringkih (2-5 intine), 50-100 MB bisa normal (ora dites ing sistem kasebut).

Ayo ndeleng cara kerjane: umpamane nyetel hbase.lru.cache.heavy.eviction.mb.size.limit = 500, ana sawetara beban (maca) banjur saben ~ 10 detik ngetung jumlah bita sing diusir. kanthi rumus:

Overhead = Jumlah Byte Bebas (MB) * 100 / Limit (MB) - 100;

Yen nyatane 2000 MB diusir, banjur Overhead padha karo:

2000 * 100 / 500 - 100 = 300%

Algoritma nyoba ndhukung ora luwih saka sawetara puluhan persen, saengga fitur kasebut bakal nyuda persentase blok sing di-cache, saengga bisa ngetrapake mekanisme tuning otomatis.

Nanging, yen beban wis mudhun, umpamane mung 200 MB sing diusir lan Overhead dadi negatif (sing diarani overshooting):

200 * 100 / 500 - 100 = -60%

Fitur kasebut, sebaliknya, bakal nambah persentase blok cache nganti Overhead dadi positif.

Ing ngisor iki minangka conto carane katon ing data nyata. Ora perlu nyoba kanggo nggayuh 0%, ora mungkin. Iku apik banget nalika kira-kira 30 - 100%, iki mbantu supaya ora metu prematur saka mode optimasi sajrone bledosan jangka pendek.

hbase.lru.cache.heavy.eviction.overhead.coefficient - nyetel sepira cepet kita pengin entuk asil. Yen kita ngerti manawa maca kita biasane dawa lan ora pengin ngenteni, kita bisa nambah rasio iki lan entuk kinerja sing luwih cepet.

Contone, kita nyetel koefisien iki = 0.01. Iki tegese nduwur sirah (ndeleng ndhuwur) bakal ping pingan dening nomer iki asil lan persentasi saka pamblokiran cached bakal suda. Ayo dadi ngomong sing Overhead = 300%, lan koefisien = 0.01, banjur persentasi saka pamblokiran cache bakal suda dening 3%.

Logika "Backpressure" sing padha uga ditrapake kanggo nilai negatif saka Overhead (overshooting). Wiwit fluktuasi jangka pendek ing volume maca lan evictions tansah bisa, mekanisme iki ngidini sampeyan supaya metu durung wayahe saka mode Optimization. Backpressure nduweni logika terbalik: sing luwih kuat overshooting, luwih akeh blok sing di-cache.

Cara nambah kacepetan maca saka HBase nganti 3 kaping lan saka HDFS nganti 5 kaping

Kode implementasine

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

Coba saiki kabeh iki ing conto nyata. Kita duwe skenario tes ing ngisor iki:

  1. Miwiti Scan (25 thread, batch = 100)
  2. Sawise 5 menit, tambahake multi-get (25 thread, batch = 100)
  3. Sawise 5 menit, mateni multi-get (mung pindai maneh)

We do loro roto, pisanan hbase.lru.cache.heavy.eviction.count.limit = 10000 (sing bener mateni fitur), lan banjur nyetel watesan = 0 (mbisakake).

Ing log ing ngisor iki, kita waca carane fitur diuripake, ngreset Overshooting kanggo 14-71%. Saka wektu kanggo wektu mbukak irungnya, kang nguripake Backpressure lan HBase cache liyane pamblokiran maneh.

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

Pindai dibutuhake kanggo nuduhake proses sing padha ing bentuk grafik hubungan antarane rong bagean saka cache - siji (ing blok sing durung nate dijaluk) lan multi (data "dijaluk" paling ora sapisan. disimpen ing kene):

Cara nambah kacepetan maca saka HBase nganti 3 kaping lan saka HDFS nganti 5 kaping

Lan pungkasane, carane paramèter bisa digunakake ing wangun grafik. Kanggo mbandhingake, cache rampung dipateni ing wiwitan, banjur ana peluncuran HBase kanthi caching lan wektu tundha wiwitan optimasi kanthi 5 menit (30 siklus eviction).

Kode lengkap bisa ditemokake ing Pull Request HBASE-23887 ing github.

Nanging, 300 ewu maca per detik ora kabeh sing bisa ditindakake ing hardware iki ing kahanan kasebut. Kasunyatane yaiku yen sampeyan kudu ngakses data liwat HDFS, mekanisme ShortCircuitCache (sabanjurΓ© SSC) digunakake, sing ngidini sampeyan ngakses data kanthi langsung, ngindhari interaksi jaringan.

Profil wis ditampilake sing sanajan mekanisme iki menehi gain amba, iku uga dadi bottleneck ing sawetara titik, amarga meh kabeh operasi abot dumadi nang kunci, kang ndadΓ©kakΓ© kanggo kunci paling wektu.

Cara nambah kacepetan maca saka HBase nganti 3 kaping lan saka HDFS nganti 5 kaping

Nyadari iki, kita nyadari manawa masalah kasebut bisa diatasi kanthi nggawe macem-macem SSC independen:

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

Banjur nggarap wong-wong mau, ora kalebu persimpangan uga kanthi digit offset pungkasan:

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

Saiki sampeyan bisa miwiti tes. Kanggo nindakake iki, kita bakal maca file saka HDFS kanthi aplikasi multi-threaded sing prasaja. Kita nyetel paramèter:

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

Lan mung maca 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);
}

Kode iki dieksekusi ing benang kapisah lan kita bakal nambah jumlah file sing diwaca bebarengan (saka 10 nganti 200 - sumbu horisontal) lan jumlah cache (saka 1 nganti 10 - grafis). Sumbu vertikal nuduhake akselerasi sing Tambah ing SSC menehi relatif kanggo cilik nalika ana mung siji cache.

Cara nambah kacepetan maca saka HBase nganti 3 kaping lan saka HDFS nganti 5 kaping

Cara maca grafik: 100k maca ing blok 64K kanthi cache siji butuh 78 detik kanggo ngrampungake. Dene karo 5 caches butuh 16 detik. Sing. ana percepatan ~ 5 kaping. Nalika sampeyan bisa ndeleng saka grafik, ing nomer cilik saka maca podo, efek ora banget ngelingke, iku wiwit muter peran ngelingke nalika thread maos luwih saka 50. Iku uga ngelingke sing nambah nomer SSC saka 6 lan ndhuwur menehi gain kinerja Ngartekno kurang.

Cathetan 1: amarga asil tes cukup molah malih (pirsani ing ngisor iki), 3 diluncurake lan nilai sing dipikolehi rata-rata.

Wigati 2: Gain kinerja saka setelan akses acak padha, sanajan akses dhewe rada alon.

Nanging, kudu dijlentrehake manawa, ora kaya kasus HBase, akselerasi iki ora mesthi gratis. Kene kita luwih "mbukak kunci" kemampuan CPU kanggo nindakake karya, tinimbang nggantung ing kunci.

Cara nambah kacepetan maca saka HBase nganti 3 kaping lan saka HDFS nganti 5 kaping

Ing kene sampeyan bisa ndeleng manawa umume, tambah akeh cache menehi paningkatan panggunaan CPU kira-kira proporsional. Nanging, ana sawetara kombinasi menang liyane.

Contone, ayo kang njupuk nyedhaki dipikir ing setelan SSC = 3. Tambah ing kinerja ing sawetara bab 3.3 kaping. Ing ngisor iki minangka asil saka kabeh telung kapisah.

Cara nambah kacepetan maca saka HBase nganti 3 kaping lan saka HDFS nganti 5 kaping

Dene konsumsi CPU mundhak udakara 2.8 kaping. Bedane ora patiya gedhe, nanging Greta cilik wis seneng lan bisa uga ana wektu kanggo sekolah lan pelajaran.

Mangkono, iki bakal duwe efek positif ing sembarang alat sing nggunakake akses akeh HDFS (contone, Spark, etc.), kasedhiya yen kode aplikasi iku entheng (i.e. plugging ing sisih klien HDFS) lan ana daya CPU free. Kanggo mriksa, ayo nyoba apa efek gabungan saka optimasi BlockCache lan tuning SSC kanggo maca saka HBase bakal menehi.

Cara nambah kacepetan maca saka HBase nganti 3 kaping lan saka HDFS nganti 5 kaping

Ing kene sampeyan bisa ndeleng manawa ing kahanan kaya ngono, efek kasebut ora kaya ing tes sing ditapis (maca tanpa diproses), nanging bisa uga nambah 80K ing kene. Bebarengan, loro optimasi menehi akselerasi nganti 4 kaping.

PR uga digawe kanggo optimasi iki [HDFS-15202], sing wis digabung lan fungsi iki bakal kasedhiya ing rilis sabanjure.

Lan pungkasane, menarik kanggo mbandhingake kinerja maca database kolom lebar sing padha Cassandra lan HBase.

Kanggo nindakake iki, conto utilitas uji beban YCSB standar diluncurake saka rong host (total 800 utas). Ing sisih server - 4 conto RegionServer lan Cassandra ing 4 host (ora ing ngendi klien mlaku kanggo nyegah pengaruhe). Wacan teka saka tabel ukuran:

HBase - 300 GB ing HDFS (100 GB data mentah)

Cassandra - 250 GB (faktor replikasi = 3)

Sing. volume ana bab padha (ing HBase sethitik liyane).

Pilihan Hbase:

dfs.client.short.circuit.num = 5 (optimasi klien HDFS)

hbase.lru.cache.heavy.eviction.count.limit = 30 - iki tegese tembelan bakal wiwit digunakake sawise 30 evictions (~ 5 menit)

hbase.lru.cache.heavy.eviction.mb.size.limit = 300 - volume target cache lan eviction

Log YCSB wis diurai lan dikompilasi menyang grafik Excel:

Cara nambah kacepetan maca saka HBase nganti 3 kaping lan saka HDFS nganti 5 kaping

Nalika sampeyan bisa ndeleng, data optimasi ndadekake iku bisa kanggo equalize kinerja database iki ing kahanan lan entuk 450 maca saben detik.

Kulo pengen informasi iki bisa migunani kanggo wong ing Course saka perjuangan macem kanggo kinerja.

Source: www.habr.com

Add a comment