Përshëndetje! Unë quhem Danil Lipovoy, ekipi ynë në Sbertech ka filluar të përdorë HBase si një depo për të dhëna operacionale. Gjatë studimit të tij, është grumbulluar përvojë që dëshironim ta sistematizojmë dhe ta përshkruajmë (shpresojmë se do të jetë e dobishme për shumë). Eksperimentet e mëposhtme janë kryer me versionet HBase 1.2.0-cdh5.14.2 dhe 2.0.0-cdh6.0.0-beta1.
- Arkitektura e përgjithshme
- Shkruarja e të dhënave në HBASE
- Leximi i të dhënave nga HBASE
- Caching i të dhënave
- Procesimi me grumbuj MultiGet/MultiPut
- Strategjia e ndarjes së tabelave në zona (splitting)
- Qëndrueshmëria, kompresimi dhe lokaliteti i të dhënave
- Cilësimet dhe performanca
- Testimi i ngarkesës
- Përfundimet
1. Arkitektura e përgjithshme

Master-i rezervë dëgjon heartbeat-in e aktivëve në nodin ZooKeeper dhe në rast se ai zhduket, merr funksionet e master-it për vete.
2. Shkruarja e të dhënave në HBASE
Fillimisht, le të shqyrtojmë rastin më të thjeshtë – shkruarja e një objekti çelës-vlerë në një tabelë përmes put(rowkey). Klienti fillimisht duhet të zbulojë ku ndodhet serveri rrënjësor (Root Region Server – RRS) që ruan tabelën hbase:meta. Informacionin e kësaj e merr nga ZooKeeper. Pas kësaj, ai i drejtohet RRS dhe lexon tabelën hbase:meta, nga e cila nxjerr informacionin se cili RegionServer (RS) është përgjegjës për ruajtjen e të dhënave sipas çelësit të rreshtit rowkey në tabelën që e intereson. Për përdorim të mëtejshëm, tabela meta ruhen në memorie nga klienti dhe kështu, kërkesat e mëvonshme shkojnë më shpejt, direkt te RS.
Më pas, RS, pasi merr kërkesën, së pari e shkruan atë në WriteAheadLog (WAL), që është e nevojshme për rikuperim në rast rënies. Pastaj ruan të dhënat në MemStore. Kjo është një tampon në memorie, i cili mban një grup të rregullt çelesh të këtij rajoni. Tabela mund të ndahet në rajone (particione), secili prej të cilëve mban një grup të pacaktuar çelesh. Kjo lejon që, duke vendosur rajonet në serverë të ndryshëm, të arrijmë një performancë më të lartë. Megjithatë, pavarësisht nga evidenca e kësaj dëshmie, më vonë do të shohim se kjo nuk funksionon në të gjitha rastet.
Pasi të vendoset regjistrimi në MemStore, klientit i kthehet një përgjigje që regjistrimi është ruajtur me sukses. Megjithatë, në realitet ai ruhet vetëm në tampon dhe do të kalojë në disk vetëm pasi të kalojë një interval të caktuar kohor ose në rast të mbushjes së tij me të dhëna të reja.

Gjatë ekzekutimit të operacionit "Fshi" nuk ndodh një fshirje fizike e të dhënave. Ato thjesht shënohen si të fshira, dhe shkatërrimi efektiv ndodh në momentin kur thirret funksioni major compact, për të cilin është shkruar më shumë në p.7.
Skedarët në formatin HFile grumbullohen në HDFS dhe herë pas here startohet procesi minor compact, i cili thjesht bashkon skedarët e vegjël në më të mëdhenj, pa hequr asgjë. Me kalimin e kohës, kjo kthehet në një problem që shfaqet vetëm gjatë leximit të të dhënave (në këtë do të kthehemi më vonë).
Përveç procesit të ngarkimit të përshkruar më sipër, ekziston një procedurë shumë më efikase, që përbën ndoshta pikën më të fortë të këtij DB – BulkLoad. Ajo përfshin faktin që ne formojmë vetë HFiles dhe i vendosim në disk, e cila na lejon të shkallojmë në mënyrë të shkëlqyer dhe të arrijmë shpejtësi të kënaqshme. Në thelb, kufizimi këtu nuk është HBase, por kapaciteti i harduerit. Më poshtë janë rezultatet e ngarkimit në një klasë që përbëhet nga 16 RegionServers dhe 16 NodeManager YARN (CPU Xeon E5-2680 v4 @ 2.40GHz * 64 dërrasa), versioni HBase 1.2.0-cdh5.14.2.

Këtu shihet se duke rritur numrin e particioneve (rajoneve) në tabelë, si dhe ekzekutorëve Spark, merrni një rritje të shpejtësisë së ngarkimit. Gjithashtu, shpejtësia varet nga sasia e shkrimit. Bloket e mëdha japin një rritje në matjen MB/s, ndërsa ato të vogla në numrin e regjistrimeve të futur në njësi kohe, në kushte të tjera të barabarta.
Gjithashtu, mund të nisni ngarkimin në dy tabela njëkohësisht dhe të merrni dyfishim të shpejtësisë. Më poshtë shihet se shkrimi i blokut 10 KB menjëherë në dy tabela po ndodh me një shpejtësi prej rreth 600 MB/s në secilën (në total 1275 MB/s), që përputhet me shpejtësinë e shkrimit në një tabelë 623 MB/s (shih. nr. 11 më sipër).

Ndërsa, ekzekutimi i dytë me shkrime në 50 KB tregon se shpejtësia e ngarkimit po rritet vetëm pak, që tregon se po afrohemi pranë vlerave maksimale. Gjithashtu, duhet të kemi parasysh se HBASE nuk ka ngarkesë të madhe këtu, gjithçka që kërkohet prej tij është fillimisht të japë të dhënat nga hbase:meta, e më pas, pas vendosjes së HFiles, të shlyejë të dhënat BlockCache dhe të ruajë tamponin MemStore në disk, nëse ai nuk është bosh.
3. Leximi i të dhënave nga HBASE
Nëse merret parasysh se të gjitha informacionet nga hbase:meta tashmë i ka klienti (shiko p.2), atëherë kërkesa shkon menjëherë në atë RS ku ruhet çelësi i nevojshëm. Fillimisht, kërkimi bëhet në MemCache. Pavarësisht nëse ka ose jo të dhëna atje, kërkimi kryhet gjithashtu në tamponin BlockCache dhe, sipas nevojës, në HFiles. Nëse të dhënat gjenden në skedarin, ato vendosen në BlockCache dhe në kërkesën e ardhshme do të kthehen më shpejt. Kërkimi në HFile ndodh mjaft shpejt falë përdorimit të filtrit Bloom, dmth, pasi lexon një sasi të vogël të dhënash, ai menjëherë përcakton nëse ky skedar ka çelësin e nevojshëm dhe nëse jo, kalon te i ardhshmi.

Duke marrë të dhënat nga këto tri burime, RS formon përgjigjen. Në veçanti, ai mund të dërgojë menjëherë disa versione të gjetura të objektit nëse klienti ka kërkuar versionim.
4. Ruajtja e të dhënave në cache
Tamponët MemStore dhe BlockCache zënë deri në 80% të memories on-heap të RS (të tjerat janë rezervuar për detyrat shërbyese të RS). Nëse përdorimi tipik është se proceset shkruajnë dhe menjëherë lexojnë këto të dhëna, ka kuptim të zvogëlohet BlockCache dhe të rritet MemStore, pasi kur shkruhen të dhënat në cache ato nuk hynë në memorjen për lexim, kështu që përdorimi i BlockCache do të ndodhë më rrallë. Tamponi BlockCache përbëhet nga dy pjesë: LruBlockCache (përherë on-heap) dhe BucketCache (zakonisht off-heap ose në SSD). BucketCache duhet përdorur kur ka shumë kërkesa për lexim dhe ato nuk përshtaten në LruBlockCache, që çon në punën aktive të Garbage Collector. Megjithatë, nuk duhet pritur një rritje radikale të performancës nga përdorimi i caches për lexim, për këtë do të rikthehemi në p. 8.

BlockCache është një për të gjithë RS, ndërsa MemStore është specifik për secilën tabelë (një për çdo Column Family).
Si Në teori, kur shkruhen të dhënat në cache ato nuk hynë dhe në të vërtetë, parametrat CACHE_DATA_ON_WRITE për tabelën dhe "Cache DATA on Write" për RS janë vendosur në false. Megjithatë, në praktikë, nëse shkruhen të dhëna në MemStore, më pas ato hidhen në disk (duke pastruar kështu), duke fshirë skedarin e krijuar, atëherë duke kryer një kërkesë get, ne do të marrim me sukses të dhënat. Për më tepër, madje edhe nëse plotësisht çaktivizohet BlockCache dhe tabelën e mbushim me të dhëna të reja, pastaj arrijmë të hedhim MemStore në disk, t'i fshijmë ato dhe të kërkojmë nga një seancë tjetër, ato përsëri do të nxirren nga ndonjë vend. Pra, HBase ruan jo vetëm të dhëna, por edhe mistere të çuditshme.
hbase(main):001:0> create 'ns:magic', 'cf'
Created table ns:magic
Took 1.1533 seconds
hbase(main):002:0> put 'ns:magic', 'key1', 'cf:c', 'try_to_delete_me'
Took 0.2610 seconds
hbase(main):003:0> flush 'ns:magic'
Took 0.6161 seconds
hdfs dfs -mv /data/hbase/data/ns/magic/* /tmp/trash
hbase(main):002:0> get 'ns:magic', 'key1'
cf:c timestamp=1534440690218, value=try_to_delete_me
Parametri «Cache DATA on Read» është vendosur false. Nëse keni ide, jeni të mirëpritur të diskutoni këtë në komentet.
5. Procesimi i të dhënave MultiGet/MultiPut
Procesi i kërkesave të vetme (Get/Put/Delete) është një operacion mjaft i kushtueshëm, prandaj është e rekomandueshme t'i gruponi ata kur është e mundur në List ose List, që lejon një rritje të konsiderueshme në performancë. Kjo është veçanërisht e rëndësishme për operacionin e shkruar, ndërsa gjatë leximit ka një problem tjetër. Në grafikun më poshtë është treguar koha e leximit të 50,000 regjistrave nga MemStore. Leximi është kryer në një rrjedhë dhe në aksin horizontal është numri i çelëseve në kërkesë. Këtu shihet se kur numri rritet deri në një mijë çelësa në një kërkesë, koha e ekzekutimit bie, domethënë shpejtësia rritet. Megjithatë, në modalitetin MSLAB të aktivizuar në mënyrë përDefault, pas këtij kufiri fillon një rënie drastike e performancës, dhe sa më shumë të dhëna të jenë në regjistrim, aq më e madhe është koha e punës.

Testet janë kryer në një virtual, 8 bërthama, versione HBase 2.0.0-cdh6.0.0-beta1.
Modaliteti MSLAB është krijuar për të reduktuar fragmentimin e heap-it, i cili ndodh për shkak të përzierjes së të dhënave të brezit të ri dhe të vjetër. Si zgjidhje e problematikës, me aktivizimin e MSLAB, të dhënat vendosen në qeliza relativisht të vogla (chunk) dhe trajtohen në grupe. Si rezultat, kur vëllimi në paketën e kërkuar të të dhënave tejkalon përmasën e caktuar, performanca bie drastikisht. Nga ana tjetër, çaktivizimi i këtij modaliteti gjithashtu nuk është i dëshirueshëm, pasi do të çojë në ndalime për shkak të GC gjatë periudhave të punës intensive me të dhëna. Një zgjidhje e mirë është rritja e përmasës së qelizës, në rastin e shkrimit aktiv përmes put në të njëjtën kohë me leximin. Duhet theksuar se problemi nuk ndodh nëse pas regjistrimit ekzekutohet komanda flush që shkarkon MemStore në disk ose nëse bëhet ngarkimi përmes BulkLoad. Në tabelën më poshtë tregohet se kërkesat nga MemStore për të dhëna më të mëdha (dhe me numra të njëjtë) çojnë në ngadalësim. Megjithatë, duke rritur chunksize, e kthejmë kohën e përpunimit në normalitet.

Përveç rritjes së chunksize, ndihmon ndarja e të dhënave sipas rajoneve, pra ndarja e tabelave. Kjo çon në faktin se për çdo rajon vijnë më pak kërkesa dhe nëse ato vendosen në një cel duke mbetur një përgjigje e mirë.
6. Strategjia e ndarjes së tabelave në rajone (spiliting)
Duke qenë se HBase është një magazinë me çelës dhe vlerë dhe ndarja bëhet sipas çelësit, është shumë e rëndësishme të ndahet e dhënat njëlloj në të gjitha rajonet. Për shembull, ndarja e kësaj tabele në tri pjesë do të çonte në ndarjen e të dhënave në tre rajone:

Ndonjëherë, kjo çon në një ngadalësim të papritur, nëse të dhënat e ngarkuara më vonë do të kenë formën, për shembull, të vlerave të gjata, shumë prej të cilave fillojnë me të njëjtën shifër, p.sh.:
1000001
1000002
…
1100003
Duke qenë se çelësit ruhen si një array bytes, të gjithë do të fillojnë njëlloj dhe do të përkasin një rajoni #1 që mban këtë gamë çelësish. Ekzistojnë disa strategji ndarjeje:
HexStringSplit – Kthen çelësin në një varg me kodimin hexadecimal në gamën "00000000" => "FFFFFFFF" dhe e mbush atë me zero nga ana e majtë.
UniformSplit – Kthen çelësin në një array bytes me kodimin hexadecimal në gamën "00" => "FF" dhe e mbush atë me zero nga ana e djathtë.
Për më tepër, është e mundur të specifikohet ndonjë gamë ose grup çelësish për ndarje dhe të konfigurohet autospiliting. Megjithatë, një nga qasjet më të thjeshta dhe më efektive është UniformSplit dhe përdorimi i konkatenimit të hashit, për shembull, dy bajtët më të lartë nga kalimi i çelësit përmes funksionit CRC32(rowkey) dhe vetë rowkey:
hash + rowkey
Kështu, të gjitha të dhënat do të shpërndahen njëlloj në rajone. Kur lexohet, dy bajtët e parë thjesht hiqen dhe mbetet çelësi origjinal. Gjithashtu, RS kontrollon sasinë e të dhënave dhe çelësave në rajon dhe kur tejkalohen limitet automatizmi e ndan atë në pjesë.
7. Qëndrueshmëria dhe lokalizimi i të dhënave
Përderisa çdo grup çelësash është përgjegjës vetëm për një rajon, zgjidhja për problemet që lidhen me rëniet e RS ose disfatimet është ruajtja e të dhënave të nevojshme në HDFS. Kur ndodh rënia e RS, master-i e zb discovers këtë përmes mungesës së heartbeat në nodin ZooKeeper. Atëherë ai emëron një rajon të shërbyer tjetër RS dhe, për shkak se HFiles ruhen në sistemin e dosjeve të shpërndara, pronari i ri i lexon ato dhe vazhdon të shërbejë të dhënat. Megjithatë, pasi një pjesë e të dhënave mund të jetë në MemStore dhe nuk ka arritur të kalojë në HFiles, për të rikuperuar historinë e operacioneve përdoret WAL, e cila gjithashtu ruhet në HDFS. Pas aplikimit të ndryshimeve, RS është në gjendje të përgjigjet në kërkesa, megjithatë kalimi çon në atë që një pjesë e të dhënave dhe proceset që i shërbejnë ato përfundimisht ndodhen në nodë të ndryshme, dmth. lokaliteti zvogëlohet.
Zgjidhja për problemin është major compaction – kjo procedurë transferon skedarët në ato nodë që janë përgjegjëse për to (aty ku janë vendosur rajonet e tyre), si rezultat, gjatë kësaj procedure ngarkesa në rrjet dhe disqet rritet ndjeshëm. Megjithatë, në të ardhmen, qasja në të dhëna thelbësisht shpejtohet. Për më tepër, major_compaction kryen bashkimin e të gjitha HFiles në një skedar të vetëm brenda rajonit, si dhe pastron të dhënat në përputhje me cilësimet e tavolines. Për shembull, mund të përcaktohet numri i versioneve të objektit që duhet të ruhen ose koha e jetës së tij, pas skadimit të së cilës objekti fshihet fizikisht.
Kjo procedurë mund të ketë një ndikim të rëndësishëm pozitiv në funksionimin e HBase. Në figurën më poshtë tregohet se si ka degraduar performanca si rezultat i shkruarjes aktive të të dhënave. Këtu tregohet si në një tavolinë 40 rrjedha shkruanin dhe 40 rrjedha lexonin të dhëna në të njëjtën kohë. Rrjedhat e shkruara formojnë gjithnjë e më shumë HFiles, të cilat lexohen nga rrjedhat e tjera. Si rezultat, gjithnjë e më shumë të dhëna duhet të fshihen nga memoria dhe në fund fillon të punojë GC, i cili praktikisht paralizon të gjithë punën. Aktivizimi i major compaction çoi në pastrimin e grumbujve të krijuar dhe rikthimin e performancës.

Testi u krye në 3 DataNode dhe 4 RS (CPU Xeon E5-2680 v4 @ 2.40GHz * 64 rrjedha). Versioni i HBase është 1.2.0-cdh5.14.2
Është e rëndësishme të theksohet se lançimi i major compaction u realizua në një tabelë "të gjallë", në të cilën po shkruheshin dhe lexoheshin të dhëna aktivisht. Në rrjet është thënë se kjo mund të çojë në përgjigje të pasaktë gjatë leximit të të dhënave. Për të verifikuar, u lançua një proces që gjeneronte të dhëna të reja dhe i shkruante ato në tabelë. Pas kësaj, menjëherë lexohej dhe verifikohej nëse vlera e marrë përputhej me atë që ishte shkruar. Gjatë funksionimit të këtij procesi, major compaction u lançua rreth 200 herë dhe asnjë dështim nuk u regjistrua. Mundësisht problemi shfaqet shpesh vetëm gjatë ngarkesës së lartë, prandaj është më e sigurt të ndalen planifikisht proceset e shkrimit dhe leximit dhe të bëhet pastrimi pa lejuar rënie të tillë GC.
Gjithashtu, major compaction nuk ndikon në gjendjen e MemStore, për të shkarkuar atë në disk dhe për kompaktiikim duhet të përdoret flush (connection.getAdmin().flush(TableName.valueOf(tblName))).
8. Rregullat dhe performanca
Siç u tha më parë, HBase arrin suksesin më të madh aty ku nuk i nevojitet të bëjë asgjë, gjatë ekzekutimit të BulkLoad. Megjithatë, kjo vlen për shumicën e sistemeve dhe njerëzve. Sidoqoftë, ky instrument është më shumë i përshtatshëm për vendosjen masive të të dhënave në blloqe të mëdha, ndonëse nëse procesi kërkon ekzekutimin e shumë kërkesave konkurruese për lexim dhe shkrim, përdoren komandat e përshkruara më sipër Get dhe Put. Për të përcaktuar parametrat optimalë, janë realizuar ekzekutime me kombinime të ndryshme parametrash tabelash dhe konfigurimesh:
- Të dhjetë derivate janë lançuar njëkohësisht 3 herë radhazi (le të eci si një bllok derivate).
- Koha e punës së të gjithë derivateve në bllok u mesatrua dhe ishte rezultati përfundimtar i punës së bllokut.
- Të gjithë derivate punuan me të njëjtën tabelë.
- Para çdo lançimi të bllokut të derivateve, u realizua një major compaction.
- Çdo bllok zhvilloi vetëm një nga operacionet e mëposhtme:
— Put
— Get
— Get+Put
- Çdo bllok realizoi 50,000 përsëritje të operacionit të tij.
- Madhësia e shkrimit në bllok ishte 100 byte, 1000 byte ose 10000 byte (random).
- Blloqet u zhvilluan me numra të ndryshëm çelësash të kërkuar (ose një çelës ose 10).
- Blloqet u lançuan me konfigurime të ndryshme të tabelës. Parametrat u ndryshuan:
— BlockCache = ishte aktivizuar ose çaktivizuar
— BlockSize = 65 KB ose 16 KB
— Partita = 1, 5 ose 30
— MSLAB = ishte aktivizuar ose çaktivizuar
Kështu blloku duket kështu:
a. Aktivizohej/çaktivizohej moda MSLAB.
b. U krijua një tabelë, për të cilën u vendosën parametrat e mëposhtëm: BlockCache = true/none, BlockSize = 65/16 Kb, Particione = 1/5/30.
c. U vendos kompresimi GZ.
d. U nisën 10 procese njëkohësisht që bënë 1/10 operacione put/get/get+put në këtë tabelë me shënime me 100/1000/10000 byte, duke realizuar 50,000 kërkesa radhazi (çelësat ishin rastësorë).
e. Pika d u përsëriti tri herë.
f. Koha e funksionimit të të gjitha proceseve u mesua.
U kontrolluan të gjitha kombinimet e mundshme. Është parashikueshmërisht që me rritjen e madhësisë së shënimeve, shpejtësia do të bjerë ose se çaktivizimi i caching do të çojë në ngadalësim. Megjithatë, qëllimi ishte të kuptohej shkalla dhe rëndësia e ndikimit të çdo parametri, ndaj të dhënat e mbledhura u paraqitën në funksionin e regresionit linear, i cili ofron mundësinë për të vlerësuar saktësinë përmes statistikës t. Më poshtë janë rezultatet e punës së blloqeve që kryejnë operacione Put. Grupi i plotë i kombinimeve 2*2*3*2*3 = 144 variante + 72 pasi disa u realizuan dy herë. Prandaj, në total 216 nisje:

Testimi u realizua në një mini-klaster përbërë nga 3 DataNode dhe 4 RS (CPU Xeon E5-2680 v4 @ 2.40GHz * 64 procese). Versioni HBase 1.2.0-cdh5.14.2.
Shpejtësia më e lartë e futjes, 3.7 sekonda, u arrit në mënyrë që MSLAB të ishte i disaktivizuar, në një tabelë me një particion, me BlockCache të aktivizuar, BlockSize = 16, shënime me 100 byte në 10 copa në paketë.
Shpejtësia më e ulët e futjes, 82.8 sekonda, u arrit kur MSLAB ishte i aktivizuar, në një tabelë me një particion, me BlockCache të aktivizuar, BlockSize = 16, shënime me 10000 byte në 1 copë.
Tani le të shohim modelin. Ne shohim një cilësi të mirë të modelit sipas R2, por është krejtësisht e qartë që ekstrapolimi këtu është i papërshtatshëm. Sjellja reale e sistemit kur ndodhin ndryshime në parametra do të jetë jo lineare, ky model nuk është për parashikime, por për të kuptuar se çfarë ndodhi brenda parametrave të caktuar. Për shembull, këtu ne shohim sipas kriterit të Studentit, që për operacionin Put, parametrat BlockSize dhe BlockCache nuk kanë rëndësi (çka në përgjithësi është krejtësisht e parashikueshme):

A surprising discovery is that an increase in the number of partitions leads to reduced performance (we've already seen the positive impact of increasing partitions during BulkLoad), although it's understandable. First, processing requires forming requests to 30 regions instead of one, and the data volume isn't sufficient to gain an advantage from this. Secondly, the overall execution time is determined by the slowest RS, and since the number of DataNodes is less than the number of RS, some regions have zero locality. Now, let's look at the top five leaders:

Now let's evaluate the results of the Get blocks execution:

The significance of the number of partitions has diminished, likely because data is well-cached and the cache for reading is the most significant (statistically) parameter. Naturally, increasing the number of messages in a request is also quite beneficial for performance. The best results:

And finally, let's take a look at the block model that first executed get and then put:

Here, all parameters are significant. And the results of the leaders:

9. Load testing
And finally, let's run a reasonably decent load, but it's always more interesting when there's something to compare against. On the DataStax website – the key developer of Cassandra, there is an overview of several NoSQL storage systems, including HBase version 0.98.6-1. The loading was done with 40 threads, data size of 100 bytes, SSD drives. The testing results for Read-Modify-Write operations showed these outcomes.

As far as I understand, reading was performed in blocks of 100 records, and for 16 HBase nodes, the DataStax test showed a performance of 10,000 operations per second.
Është fat që klasteri jonë ka gjithashtu 16 nodë, por nuk është shumë "fat" që në secilën ka 64 bërthama (rrjedha), ndërsa në testin DataStax vetëm 4. Nga ana tjetër, ata kanë disqe SSD, ndërsa ne HDD dhe një version më të ri HBase dhe shfrytëzimi i CPU gjatë ngarkesës nuk u rrit dukshëm (vizualisht me 5-10 përqind). Megjithatë, do të përpiqemi të fillojmë në këtë konfigurim. Cilësimet e tabelave janë të paracaktuara, leximi bëhet në një gamë çelësash nga 0 në 50 milion raste rastësore (dmth. në thelb çdo herë krejt i ri). Në tabelë ka 50 milion të dhëna, të ndara në 64 parti. Çelësat janë të hedhura me crc32. Cilësimet e tabelave janë të paracaktuara, MSLAB është aktivizuar. Çeli 40 rrjedha, secila rrjedhë lexon një grup prej 100 çelësash rastësorë dhe menjëherë shkruan 100 byte të gjeneruara mbi këta çelësa.

Standi: 16 DataNode dhe 16 RS (CPU Xeon E5-2680 v4 @ 2.40GHz * 64 rrjedha). Versioni HBase 1.2.0-cdh5.14.2.
Rezultati mesatar është afërsisht 40 mijë operacione në sekondë, që është përshtatshëm më mirë sesa në testin DataStax. Megjithatë, për qëllime eksperimentale mund të ndryshojmë disa kushte. Është mjaft e pamundur që e gjithë puna të bëhet ekskluzivisht me një tabelë, si edhe vetëm me çelësa unikë. Le të supozojmë se ka një grup "të nxehtë" çelësash që gjeneron ngarkesën kryesore. Prandaj, do të përpiqemi të krijojmë ngarkesë me të dhëna më të mëdha (10 KB), gjithashtu në grupe prej 100, në 4 tabela të ndryshme dhe duke kufizuar gamën e çelësave të kërkuar në 50 mijë. Në grafikën më poshtë tregohet dyzimi i 40 rrjedhave, secila rrjedhë lexon një grup prej 100 çelësash dhe menjëherë shkruan rastësorë 10 KB mbi këta çelësa.

Standi: 16 DataNode dhe 16 RS (CPU Xeon E5-2680 v4 @ 2.40GHz * 64 rrjedha). Versioni HBase 1.2.0-cdh5.14.2.
Gjatë ngarkesës, disa herë u realizua major compaction, siç u tregua më sipër pa këtë procedurë, performanca do të degradojë gradualisht, megjithatë gjatë ekzekutimit gjithashtu krijohet ngarkesë shtesë. Rëniet shkaktohen nga arsye të ndryshme. Ndonjëherë rrjedhat përfundonin punën dhe ndërsa ato rinisnin, ndodhte një pauzë, ndonjëherë aplikacione të jashtme krijonin ngarkesë në klaster.
Leximi dhe menjëherë shkruaj është një nga skenarët më të vështira të punës për HBase. Nëse bëni vetëm kërkesa put të vogla, për shembull 100 byte, duke i bashkuar ato në grupe prej 10-50 mijë, mund të arrini qindra mijëra operacione në sekondë, dhe situata është e njëjtë me kërkesat që janë vetëm për lexim. Ështe e rëndësishme të theksohet se rezultatet janë radikalisht më të mira se ato që arriti DataStax, kryesisht falë kërkesave në grupe prej 50 mijë.

Standi: 16 DataNode dhe 16 RS (CPU Xeon E5-2680 v4 @ 2.40GHz * 64 rrjedha). Versioni HBase 1.2.0-cdh5.14.2.
10. Përfundimet
Ky sistem është mjaft fleksibël për t’u konfiguruar, megjithatë ndikimi i një numri të madh parametrash ende mbetet i panjohur. Disa prej tyre janë testuar, por nuk janë përfshirë në grupin e rezultatet. Për shembull, eksperimente paraprake treguan një rëndësi të vogël të parametrave si DATA_BLOCK_ENCODING, i cili kodon informacionin duke përdorur vlerat nga qelizat fqinjë, e cila është krejt e arsyeshme për të dhënat e gjeneruara rastësisht. Në rastin e përdorimit të një numri të madh objektesh të përsëritura, fitimi mund të jetë i konsiderueshëm. Në përgjithësi, mund të thuhet se HBase duket si një DB e mjaftueshme serioze dhe e menduar mirë, që mund të jetë shumë efektive kur operon me blloqe të mëdha të dhënash. Sidomos nëse ka mundësi të shpërndahen në kohë proceset e leximit dhe shkruarjes.
Nëse diçka sipas jush nuk është shpjeguar mjaftueshëm, jam i gatshëm të flas në detaje. Ju inkurajojmë të ndihmoni me përvojën tuaj ose të diskutoni nëse nuk jeni dakord me diçka.
Burimi: habr.com
