{"id":55302,"date":"2020-01-17T00:00:00","date_gmt":"2020-01-16T21:00:00","guid":{"rendered":"https:\/\/prohoster.info\/blog\/blog_prohoster\/teoriya-i-praktika-ispolzovaniya-hbase"},"modified":"2020-02-18T14:03:24","modified_gmt":"2020-02-18T11:03:24","slug":"teoriya-i-praktika-ispolzovaniya-hbase","status":"publish","type":"post","link":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/teoriya-i-praktika-ispolzovaniya-hbase","title":{"rendered":"Teoria e pratica dell'uso di HBase","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Buongiorno! Mi chiamo Danil Lipovoy e il nostro team in Sbertech ha iniziato a utilizzare HBase come archivio per i dati operativi. Durante i nostri studi, abbiamo accumulato esperienza che desideriamo sistematizzare e descrivere (speriamo sia utile a molti). Tutti gli esperimenti riportati di seguito sono stati condotti con le versioni HBase 1.2.0-cdh5.14.2 e 2.0.0-cdh6.0.0-beta1. <\/p>\n<ol>\n<li>Architettura generale <\/li>\n<li>Scrittura dei dati in HBASE<\/li>\n<li>Lettura dei dati da HBASE<\/li>\n<li>Caching dei dati<\/li>\n<li>Elaborazione batch dei dati MultiGet\/MultiPut<\/li>\n<li>Strategia di suddivisione delle tabelle in regioni (sharding)<\/li>\n<li>Resilienza, compattazione e localizzazione dei dati<\/li>\n<li>Impostazioni e prestazioni<\/li>\n<li>Test di carico<\/li>\n<li>Conclusioni<\/li>\n<\/ol>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>1. Architettura generale<\/h2>\n<p>\n<img decoding=\"async\" alt=\"Teoria e pratica dell&#039;uso di HBase\" src=\"\/wp-content\/uploads\/2020\/01\/30800d8a48de4c52ff1650a4f1dec4c8.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nIl Master di riserva ascolta il heartbeat del Master attivo sul nodo ZooKeeper e, in caso di scomparsa, assume le funzioni del Master. <\/p>\n<h2>2. Scrittura dei dati in HBASE<\/h2>\n<p>\nIniziamo esaminando il caso pi\u00f9 semplice: la scrittura di un oggetto chiave-valore in una certa tabella tramite put(rowkey). Il client deve prima determinare dove si trova il server della regione radice (Root Region Server - RRS), che memorizza la tabella hbase:meta. Questa informazione viene ottenuta da ZooKeeper. Dopodich\u00e9, si rivolge al RRS e legge la tabella hbase:meta, da cui estrae le informazioni su quale RegionServer (RS) \u00e8 responsabile della memorizzazione dei dati per la chiave rowkey nella tabella di interesse. Per utilizzi futuri, la tabella meta viene memorizzata nella cache dal client, e cos\u00ec i successivi accessi avvengono pi\u00f9 velocemente, direttamente al RS.<\/p>\n<p>Successivamente, il RS, ricevuto il comando, prima di tutto lo scrive nel WriteAheadLog (WAL), necessario per il ripristino in caso di crash. Poi salva i dati in MemStore. Questo \u00e8 un buffer in memoria che contiene un insieme ordinato di chiavi di questa regione. La tabella pu\u00f2 essere suddivisa in regioni (partizioni), ciascuna delle quali contiene un insieme di chiavi non sovrapposto. Questo consente, posizionando le regioni su server diversi, di ottenere prestazioni pi\u00f9 elevate. Tuttavia, nonostante l'evidenza di questa affermazione, vedremo in seguito che non sempre funziona.<\/p>\n<p>Dopo aver posizionato la registrazione in MemStore, al client viene restituita una risposta che indica che la registrazione \u00e8 stata salvata con successo. In realt\u00e0, viene memorizzata solo nel buffer e finir\u00e0 su disco solo dopo che sar\u00e0 trascorso un certo intervallo di tempo o quando sar\u00e0 piena di nuovi dati. <\/p>\n<p><img decoding=\"async\" alt=\"Teoria e pratica dell&#039;uso di HBase\" src=\"\/wp-content\/uploads\/2020\/01\/10f4d5d600a20882690f5cc81322bc41.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nNell'operazione \u00abDelete\u00bb, i dati non vengono fisicamente rimossi. Vengono semplicemente contrassegnati come eliminati, e la loro vera eliminazione avviene al momento della chiamata della funzione major compact, di cui si parla pi\u00f9 dettagliatamente nel paragrafo 7.<\/p>\n<p>I file in formato HFile si accumulano in HDFS e di tanto in tanto viene avviato il processo minor compact, che unisce semplicemente file piccoli in file pi\u00f9 grandi, senza eliminare nulla. Col tempo, questo diventa un problema che si manifesta solo durante la lettura dei dati (ci torneremo pi\u00f9 tardi). <\/p>\n<p>Oltre al processo di caricamento descritto sopra, esiste una procedura molto pi\u00f9 efficiente, che rappresenta probabilmente il punto di forza di questo database: il BulkLoad. Si tratta del caricamento autonomo degli HFiles direttamente su disco, il che consente di scalare in modo eccellente e raggiungere velocit\u00e0 molto soddisfacenti. In sostanza, il limite non \u00e8 HBase, ma le capacit\u00e0 hardware. Di seguito sono riportati i risultati di caricamento su un cluster composto da 16 RegionServer e 16 NodeManager YARN (CPU Xeon E5-2680 v4 @ 2.40GHz * 64 thread), versione HBase 1.2.0-cdh5.14.2. <\/p>\n<p><img decoding=\"async\" alt=\"Teoria e pratica dell&#039;uso di HBase\" src=\"\/wp-content\/uploads\/2020\/01\/4e4452b216eda3269a364ea97c49120f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nQui si pu\u00f2 vedere che aumentando il numero di partizioni (regioni) nella tabella, cos\u00ec come gli executor Spark, otteniamo un incremento della velocit\u00e0 di caricamento. Anche la velocit\u00e0 dipende dalla quantit\u00e0 di scrittura. Blocchi grandi offrono un aumento in termini di MB\/sec, mentre i blocchi piccoli in termini di numero di record inseriti in unit\u00e0 di tempo, a parit\u00e0 di altre condizioni. <\/p>\n<p>\u00c8 anche possibile avviare il caricamento in due tabelle contemporaneamente e ottenere un raddoppio della velocit\u00e0. Qui si osserva che la scrittura di blocchi da 10 KB simultaneamente in due tabelle avviene a una velocit\u00e0 di circa 600 MB\/sec ciascuna (complessivamente 1275 MB\/sec), che corrisponde alla velocit\u00e0 di scrittura in una tabella di 623 MB\/sec (vedi n. 11 sopra).<\/p>\n<p><img decoding=\"async\" alt=\"Teoria e pratica dell&#039;uso di HBase\" src=\"\/wp-content\/uploads\/2020\/01\/9f1b4fc0c80b797111494d400e9ce332.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nTuttavia, il secondo avvio con scritture di 50 KB mostra che la velocit\u00e0 di caricamento cresce gi\u00e0 in modo marginale, il che indica che ci si sta avvicinando ai valori limite. \u00c8 importante notare che non viene praticamente generato alcun carico su HBase; tutto ci\u00f2 che gli \u00e8 richiesto \u00e8 prima fornire i dati da hbase:meta, e dopo il caricamento di HFiles, svuotare i dati di BlockCache e salvare il buffer MemStore su disco, se non \u00e8 vuoto.<\/p>\n<h2>3. Lettura dei dati da HBASE<\/h2>\n<p>\nSe consideriamo che tutte le informazioni da hbase:meta sono gi\u00e0 disponibili per il cliente (vedi punto 2), la richiesta viene inviata direttamente al RS che conserva la chiave necessaria. Inizialmente, la ricerca avviene in MemCache. Indipendentemente dal fatto che ci siano dati o meno, la ricerca avviene anche nel buffer BlockCache e, se necessario, negli HFiles. Se i dati vengono trovati nel file, vengono collocati in BlockCache e nella richiesta successiva verranno restituiti pi\u00f9 rapidamente. La ricerca in HFile avviene abbastanza rapidamente grazie all'uso del filtro di Bloom, cio\u00e8, leggendo un piccolo volume di dati, determina immediatamente se quel file contiene la chiave richiesta e, se non la contiene, passa al successivo.<\/p>\n<p><img decoding=\"async\" alt=\"Teoria e pratica dell&#039;uso di HBase\" src=\"\/wp-content\/uploads\/2020\/01\/a21b1b825a84cfd02507ec334e9452fb.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nRicevuti i dati da queste tre fonti, il RS forma la risposta. In particolare, pu\u00f2 restituire pi\u00f9 versioni trovate dell'oggetto se il cliente richiede la versioning.<\/p>\n<h2>4. Caching dei dati<\/h2>\n<p>\nI buffer MemStore e BlockCache occupano fino all'80% della memoria on-heap dedicata del RS (il resto \u00e8 riservato per le attivit\u00e0 di servizio del RS). Se il modo tipico di utilizzo \u00e8 tale che i processi scrivono e leggono immediatamente questi stessi dati, ha senso ridurre BlockCache e aumentare MemStore, poich\u00e9 durante la scrittura i dati non vengono memorizzati nel cache di lettura, quindi l'uso di BlockCache avverr\u00e0 meno frequentemente. Il buffer BlockCache \u00e8 composto da due parti: LruBlockCache (sempre on-heap) e BucketCache (di solito off-heap o su SSD). \u00c8 consigliabile utilizzare BucketCache quando ci sono molte richieste di lettura e non possono essere memorizzate in LruBlockCache, il che porta a un'attivit\u00e0 intensa del Garbage Collector. Tuttavia, non ci si aspetti un aumento radicale delle prestazioni dall'uso del cache di lettura, ma ne parleremo pi\u00f9 avanti nel punto 8.<\/p>\n<p><img decoding=\"async\" alt=\"Teoria e pratica dell&#039;uso di HBase\" src=\"\/wp-content\/uploads\/2020\/01\/17d7791a998dd7da747cb7089dce1f10.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nBlockCache \u00e8 uno per tutto il RS, mentre MemStore \u00e8 unico per ogni tabella (uno per ogni Column Family).<\/p>\n<p>Come <noindex><a rel=\"nofollow\" href=\"https:\/\/blog.cloudera.com\/blog\/2012\/06\/hbase-write-path\/\">\u00e8 descritto<\/a><\/noindex> In teoria, durante la scrittura i dati non vengono memorizzati nel cache e, in effetti, tali parametri CACHE_DATA_ON_WRITE per la tabella e 'Cache DATA on Write' per il RS sono impostati su false. Tuttavia, in pratica, se si scrivono dati in MemStore, poi si effettua un flush su disco (pulendo in questo modo), quindi si elimina il file risultante, eseguendo una richiesta get otteniamo comunque i dati. Inoltre, anche se si disattiva completamente BlockCache e si riempie la tabella con nuovi dati, poi si provoca un flush di MemStore su disco, si eliminano e si richiedono da un'altra sessione, i dati verranno comunque estratti da qualche parte. Quindi HBase conserva non solo i dati, ma anche misteri enigmatici.<\/p>\n<pre><code class=\"bash\">hbase(main):001:0&gt; crea 'ns:magic', 'cf'\nTabella ns:magic creata\nTempo impiegato 1.1533 secondi\nhbase(main):002:0&gt; metti 'ns:magic', 'key1', 'cf:c', 'provami_a_eliminare'\nTempo impiegato 0.2610 secondi\nhbase(main):003:0&gt; flush 'ns:magic'\nTempo impiegato 0.6161 secondi\nhdfs dfs -mv \/data\/hbase\/data\/ns\/magic\/* \/tmp\/trash\nhbase(main):002:0&gt; ottieni 'ns:magic', 'key1'\n cf:c      timestamp=1534440690218, valore=provami_a_eliminare\n<\/code><\/pre>\n<p>\nIl parametro \"Cache DATA on Read\" \u00e8 impostato su false. Se hai idee, sei il benvenuto a discuterne nei commenti.<\/p>\n<h2>5. Elaborazione batch di dati MultiGet\/MultiPut<\/h2>\n<p>\nL'elaborazione delle richieste singole (Get\/Put\/Delete) \u00e8 un'operazione piuttosto costosa, quindi \u00e8 consigliabile unirle in un List o List, il che consente di ottenere un notevole miglioramento delle prestazioni. Questo \u00e8 particolarmente vero per l'operazione di scrittura, ma quando si legge c'\u00e8 il seguente problema. Nel grafico qui sotto \u00e8 mostrato il tempo di lettura di 50.000 record da MemStore. La lettura \u00e8 stata eseguita in un singolo thread e sull'asse orizzontale \u00e8 mostrato il numero di chiavi nella richiesta. Qui si vede che aumentando fino a mille chiavi in una sola richiesta, il tempo di esecuzione diminuisce, cio\u00e8 la velocit\u00e0 aumenta. Tuttavia, con la modalit\u00e0 MSLAB abilitata per impostazione predefinita, dopo questa soglia si verifica un drastico calo delle prestazioni, e pi\u00f9 grande \u00e8 il volume dei dati nel record, pi\u00f9 lungo \u00e8 il tempo di lavoro. <\/p>\n<p><img decoding=\"async\" alt=\"Teoria e pratica dell&#039;uso di HBase\" src=\"\/wp-content\/uploads\/2020\/01\/42d3a77d66770a7fed03f83fecdca470.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nI test sono stati eseguiti su una macchina virtuale, 8 core, versione HBase 2.0.0-cdh6.0.0-beta1.<\/p>\n<p>La modalit\u00e0 MSLAB \u00e8 progettata per ridurre la frammentazione dell'heap, che si verifica a causa della mescolanza di dati di nuove e vecchie generazioni. Come soluzione al problema, quando MSLAB \u00e8 abilitato, i dati vengono collocati in celle (chunk) relativamente piccole e vengono elaborati a porzioni. Di conseguenza, quando il volume nel pacchetto dati richiesto supera la dimensione assegnata, le prestazioni diminuiscono drasticamente. D'altro canto, disabilitare questa modalit\u00e0 non \u00e8 desiderabile, poich\u00e9 porter\u00e0 a interruzioni a causa di GC nei momenti di intenso lavoro con i dati. Una buona soluzione \u00e8 aumentare la dimensione delle celle, nel caso di scritture attive tramite put contemporaneamente alla lettura. \u00c8 importante notare che il problema non si verifica se dopo la scrittura viene eseguito il comando flush, che scarica MemStore su disco, o se si esegue il caricamento tramite BulkLoad. Nella tabella sottostante \u00e8 mostrato che le richieste da MemStore di dati di dimensioni maggiori (e numero uguale) portano a un rallentamento. Tuttavia, aumentando la chunksize, riportiamo il tempo di elaborazione alla normalit\u00e0.<\/p>\n<p><img decoding=\"async\" alt=\"Teoria e pratica dell&#039;uso di HBase\" src=\"\/wp-content\/uploads\/2020\/01\/0076215bd171257548f8a4c4d4229ba0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nOltre all'aumento del chunksize, aiuta anche la suddivisione dei dati per regioni, ovvero il partizionamento delle tabelle. Questo porta a una minore quantit\u00e0 di richieste per ogni regione e, se inserite in una cella, la risposta rimane buona.<\/p>\n<h2>6. Strategia di partizionamento delle tabelle per regioni (partitioning)<\/h2>\n<p>\nPoich\u00e9 HBase \u00e8 un archivio key-value e la partizione avviene per chiave, \u00e8 fondamentale distribuire i dati uniformemente su tutte le regioni. Ad esempio, la partizione di una tabella in tre parti porter\u00e0 a una divisione dei dati in tre regioni:<\/p>\n<p><img decoding=\"async\" alt=\"Teoria e pratica dell&#039;uso di HBase\" src=\"\/wp-content\/uploads\/2020\/01\/a811ae81e77b48dbf28ed86dbdc35739.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nA volte, ci\u00f2 pu\u00f2 portare a un rallentamento significativo, se i dati caricati in seguito sono per esempio valori long che iniziano nella maggior parte dei casi con la stessa cifra, ad esempio:<\/p>\n<p>1000001<br \/>\n1000002<br \/>\n\u2026<br \/>\n1100003<\/p>\n<p>Poich\u00e9 le chiavi sono memorizzate come array di byte, tutte inizieranno allo stesso modo e si riferiranno a una regione #1 che memorizza questo intervallo di chiavi. Esistono diverse strategie di partizionamento:<\/p>\n<p>HexStringSplit \u2013 Trasforma la chiave in una stringa con codifica esadecimale nell'intervallo \"00000000\" =&gt; \"FFFFFFFF\" riempiendo a sinistra con zeri.<\/p>\n<p>UniformSplit \u2013 Trasforma la chiave in un array di byte con codifica esadecimale nell'intervallo \"00\" =&gt; \"FF\" riempiendo a destra con zeri.<\/p>\n<p>Inoltre, \u00e8 possibile specificare qualsiasi intervallo o insieme di chiavi per la partizione e configurare l'auto-partizionamento. Tuttavia, uno degli approcci pi\u00f9 semplici ed efficaci \u00e8 UniformSplit e l'uso della concatenazione dell'hash, ad esempio la coppia di byte pi\u00f9 significativa derivante dall'elaborazione della chiave tramite la funzione CRC32(rowkey) e la chiave stessa:<\/p>\n<p>hash + rowkey<\/p>\n<p>In questo modo, tutti i dati saranno distribuiti uniformemente su tutte le regioni. Durante la lettura, i primi due byte vengono semplicemente scartati e rimane la chiave originale. Inoltre, il RS controlla la quantit\u00e0 di dati e chiavi nella regione e, al superamento dei limiti, la suddivide automaticamente. <\/p>\n<h2>7. Tolleranza ai guasti e localit\u00e0 dei dati<\/h2>\n<p>\nPoich\u00e9 ogni set di chiavi \u00e8 gestito solo da una regione, la soluzione ai problemi legati alle cadute di RS o all'uscita di esercizio \u00e8 conservare tutti i dati necessari in HDFS. Quando un RS cade, il master lo rileva tramite l'assenza del segnale di heartbeat sul nodo ZooKeeper. Allora assegna la regione a un altro RS e, poich\u00e9 gli HFiles sono conservati nel file system distribuito, il nuovo proprietario li legge e continua a gestire i dati. Tuttavia, poich\u00e9 parte dei dati potrebbe trovarsi in MemStore e non \u00e8 ancora stata trasferita in HFiles, per recuperare la storia delle operazioni si utilizza WAL, che \u00e8 anch'esso conservato in HDFS. Dopo aver applicato le modifiche, l'RS \u00e8 in grado di rispondere alle richieste, ma il trasferimento comporta che parte dei dati e i processi che li gestiscono si trovino su nodi diversi, riducendo cos\u00ec la locality. <\/p>\n<p>La soluzione al problema \u00e8 la major compaction: questa procedura sposta i file sui nodi a cui sono assegnati (dove si trovano le loro regioni), il che provoca un aumento drastico del carico sulla rete e sui dischi durante questa procedura. Tuttavia, in seguito, l'accesso ai dati \u00e8 notevolmente accelerato. Inoltre, la major_compaction unisce tutti gli HFiles in un unico file all'interno della regione e pulisce i dati in base alle impostazioni della tabella. Ad esempio, \u00e8 possibile impostare il numero di versioni dell'oggetto da mantenere o il tempo di vita dopo il quale l'oggetto viene fisicamente eliminato.<\/p>\n<p>Questa procedura pu\u00f2 avere un impatto molto positivo sul funzionamento di HBase. Nella figura sottostante si pu\u00f2 vedere come la performance sia degradata a causa di scritture attive di dati. Qui si nota come 40 thread stessero scrivendo in una tabella e 40 thread leggessero simultaneamente i dati. I thread di scrittura generano sempre pi\u00f9 HFiles, che vengono letti da altri thread. Di conseguenza, occorre eliminare sempre pi\u00f9 dati dalla memoria e alla fine inizia a funzionare il GC, che paralizza praticamente tutto il lavoro. L'avvio della major compaction ha portato alla pulizia dei cumuli formatisi e al ripristino della performance.<\/p>\n<p><img decoding=\"async\" alt=\"Teoria e pratica dell&#039;uso di HBase\" src=\"\/wp-content\/uploads\/2020\/01\/6c93b2c10c197663785d3de0bb185481.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nIl test \u00e8 stato eseguito su 3 DataNode e 4 RS (CPU Xeon E5-2680 v4 @ 2.40GHz * 64 thread). Versione di HBase 1.2.0-cdh5.14.2<\/p>\n<p>\u00c8 importante notare che l'esecuzione della major compaction \u00e8 avvenuta su una tabella \"live\", in cui venivano scritti e letti dati attivamente. Si \u00e8 affermato in rete che questo potrebbe portare a risposte errate durante la lettura dei dati. Per verificare, \u00e8 stato avviato un processo che generava nuovi dati e li scriveva nella tabella. Dopodich\u00e9, venivano subito letti e confrontati per vedere se il valore ottenuto corrispondeva a quello registrato. Durante il funzionamento di questo processo, la major compaction \u00e8 stata eseguita circa 200 volte senza che si registrassero errori. \u00c8 possibile che il problema si manifesti raramente e solo durante un carico elevato, quindi \u00e8 pi\u00f9 sicuro interrompere pianificatamente i processi di scrittura e lettura e eseguire la pulizia evitando tali cali del GC.<\/p>\n<p>Inoltre, la major compaction non influisce sullo stato di MemStore; per il suo svuotamento su disco e la compattazione \u00e8 necessario utilizzare flush (connection.getAdmin().flush(TableName.valueOf(tblName))).<\/p>\n<h2>8. Impostazioni e prestazioni<\/h2>\n<p>\nCome gi\u00e0 detto, HBase ha il maggiore successo dove non deve fare nulla durante l'esecuzione di BulkLoad. In effetti, questo vale per la maggior parte dei sistemi e delle persone. Tuttavia, questo strumento \u00e8 pi\u00f9 adatto per la disposizione massiva di dati in grandi blocchi, mentre se il processo richiede l'esecuzione di molte richieste concorrenti di lettura e scrittura, si utilizzano i comandi Get e Put descritti sopra. Per determinare i parametri ottimali, sono stati effettuati avvii con diverse combinazioni di parametri delle tabelle e impostazioni:<\/p>\n<ul>\n<li>Sono stati avviati 10 thread contemporaneamente per 3 volte di fila (chiamiamolo blocco di thread). <\/li>\n<li>Il tempo di esecuzione di tutti i thread nel blocco \u00e8 stato mediato e rappresentava il risultato finale del lavoro del blocco.<\/li>\n<li>Tutti i thread hanno lavorato sulla stessa tabella. <\/li>\n<li>Prima di ogni avvio del blocco di thread \u00e8 stata eseguita una major compaction.<\/li>\n<li>Ogni blocco ha eseguito solo una delle seguenti operazioni: <\/li>\n<\/ul>\n<p>\n \u2014 Put<br \/>\n \u2014 Get<br \/>\n \u2014 Get+Put<\/p>\n<ul>\n<li>Ogni blocco ha eseguito 50.000 ripetizioni della sua operazione.<\/li>\n<li>La dimensione della registrazione nel blocco era di 100 byte, 1000 byte o 10.000 byte (random).<\/li>\n<li>I blocchi venivano avviati con un numero variabile di chiavi richieste (o una chiave o 10).<\/li>\n<li>I blocchi venivano eseguiti con diverse impostazioni della tabella. Sono stati modificati i parametri:<\/li>\n<\/ul>\n<p>\n \u2014 BlockCache = acceso o spento<br \/>\n \u2014 BlockSize = 65 Kb o 16 Kb<br \/>\n \u2014 Partizioni = 1, 5 o 30<br \/>\n \u2014 MSLAB = acceso o spento<\/p>\n<p>Pertanto, il blocco appare cos\u00ec:<\/p>\n<p>a. La modalit\u00e0 MSLAB veniva accesa\/spenta.<br \/>\nb. \u00c8 stata creata una tabella a cui sono stati impostati i seguenti parametri: BlockCache = true\/none, BlockSize = 65\/16 Kb, Partizioni = 1\/5\/30. <br \/>\nc. \u00c8 stata impostata la compressione GZ.<br \/>\nd. Sono stati avviati 10 thread che eseguivano simultaneamente 1\/10 operazioni put\/get\/get+put su questa tabella, utilizzando record di 100\/1000\/10000 byte, effettuando 50.000 richieste consecutive (chiavi casuali).<br \/>\ne. Il punto d \u00e8 stato ripetuto tre volte.<br \/>\nf. Il tempo di esecuzione di tutti i thread \u00e8 stato mediato. <\/p>\n<p>Sono state verificate tutte le possibili combinazioni. \u00c8 prevedibile che l'aumento della dimensione del record comporti una diminuzione della velocit\u00e0 o che la disattivazione della cache porti a un rallentamento. Tuttavia, l'obiettivo era comprendere la misura e l'importanza dell'influenza di ciascun parametro, quindi i dati raccolti sono stati forniti come input a una funzione di regressione lineare, che consente di valutare l'affidabilit\u00e0 tramite t-statistica. Di seguito sono riportati i risultati delle operazioni di Put. L'insieme completo di combinazioni 2*2*3*2*3 = 144 varianti + 72 poich\u00e9 alcune sono state eseguite due volte. Pertanto, il totale \u00e8 di 216 esecuzioni.<\/p>\n<p><img decoding=\"async\" alt=\"Teoria e pratica dell&#039;uso di HBase\" src=\"\/wp-content\/uploads\/2020\/01\/7a13c7a9b3ff1859976800f5d45cd51b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nIl test \u00e8 stato eseguito su un mini-cluster composto da 3 DataNode e 4 RS (CPU Xeon E5-2680 v4 @ 2.40GHz * 64 thread). Versione HBase 1.2.0-cdh5.14.2.<\/p>\n<p>La massima velocit\u00e0 di inserimento di 3,7 secondi \u00e8 stata ottenuta con la modalit\u00e0 MSLAB disattivata, su una tabella con una sola partizione, con BlockCache attivato, BlockSize = 16, record di 100 byte in pacchetti da 10.<br \/>\nLa minima velocit\u00e0 di inserimento di 82,8 secondi \u00e8 stata ottenuta con la modalit\u00e0 MSLAB attivata, su una tabella con una sola partizione, con BlockCache attivato, BlockSize = 16, record di 10000 byte uno alla volta.<\/p>\n<p>Ora diamo un'occhiata al modello. Vediamo una buona qualit\u00e0 del modello in base all'R2, ma \u00e8 chiaramente evidente che l'estrapolazione qui \u00e8 sconsigliata. Il comportamento reale del sistema alla variazione dei parametri sar\u00e0 non lineare, questo modello \u00e8 necessario non per previsioni, ma per comprendere cosa sia successo entro i parametri definiti. Ad esempio, qui vediamo che secondo il criterio di Student, per l'operazione Put non hanno rilevanza i parametri BlockSize e BlockCache (cosa che \u00e8 del tutto prevedibile):<\/p>\n<p><img decoding=\"async\" alt=\"Teoria e pratica dell&#039;uso di HBase\" src=\"\/wp-content\/uploads\/2020\/01\/2fb65d1809d53f2b47f4f8829a9efc65.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nTuttavia, il fatto che l'aumento del numero di partizioni porti a una diminuzione delle prestazioni \u00e8 piuttosto inaspettato (abbiamo gi\u00e0 osservato l'impatto positivo dell'aumento del numero di partizioni durante il BulkLoad), sebbene sia comprensibile. In primo luogo, per la lavorazione \u00e8 necessario formare richieste a 30 regioni invece di una, e il volume dei dati non \u00e8 tale da generare un guadagno. In secondo luogo, il tempo totale di esecuzione \u00e8 determinato dal RS pi\u00f9 lento; e poich\u00e9 il numero di DataNode \u00e8 inferiore al numero di RS, alcune regioni hanno localit\u00e0 nulla. Ora diamo un'occhiata ai cinque leader:<\/p>\n<p><img decoding=\"async\" alt=\"Teoria e pratica dell&#039;uso di HBase\" src=\"\/wp-content\/uploads\/2020\/01\/8ad7e832879156eaa96e630458405cdc.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nAdesso valutiamo i risultati dell'esecuzione dei blocchi Get:<\/p>\n<p><img decoding=\"async\" alt=\"Teoria e pratica dell&#039;uso di HBase\" src=\"\/wp-content\/uploads\/2020\/01\/8a5dd45422c74e8815011d7e9b805ccb.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nIl numero di partizioni ha perso significato, il che probabilmente si spiega con il fatto che i dati vengono ben memorizzati nella cache e la cache per la lettura \u00e8 il parametro pi\u00f9 significativo (statisticamente). Ovviamente, anche un aumento del numero di messaggi nella richiesta \u00e8 molto utile per le prestazioni. I migliori risultati:<\/p>\n<p><img decoding=\"async\" alt=\"Teoria e pratica dell&#039;uso di HBase\" src=\"\/wp-content\/uploads\/2020\/01\/9d237f9fdbeaf5412daec2fc2fa24b01.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nInfine, diamo un'occhiata al modello di blocco che ha eseguito prima get e poi put:<\/p>\n<p><img decoding=\"async\" alt=\"Teoria e pratica dell&#039;uso di HBase\" src=\"\/wp-content\/uploads\/2020\/01\/75137207a4a69acccad036882794094b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nQui tutti i parametri sono significativi. Ecco i risultati dei leader:<\/p>\n<p><img decoding=\"async\" alt=\"Teoria e pratica dell&#039;uso di HBase\" src=\"\/wp-content\/uploads\/2020\/01\/c166933d81e86f36958e3af58297f876.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<h2>9. Test di carico<\/h2>\n<p>\nInfine, eseguiamo un carico ragionevolmente sostanzioso, ma \u00e8 sempre pi\u00f9 interessante quando c'\u00e8 qualcosa con cui confrontarsi. Sul sito di DataStax, principale sviluppatore di Cassandra, ci sono <noindex><a rel=\"nofollow\" href=\"https:\/\/www.datastax.com\/wp-content\/themes\/datastax-2014-08\/files\/NoSQL_Benchmarks_EndPoint.pdf\">i risultati<\/a><\/noindex> NT di vari archivi NoSQL, tra cui HBase versione 0.98.6-1. Il caricamento \u00e8 stato effettuato con 40 thread, dimensione dei dati 100 byte, dischi SSD. I risultati del test delle operazioni Read-Modify-Write hanno mostrato i seguenti risultati.<\/p>\n<p><img decoding=\"async\" alt=\"Teoria e pratica dell&#039;uso di HBase\" src=\"\/wp-content\/uploads\/2020\/01\/521e9dff60f462e6dabebc1234e028be.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n Da quello che ho capito, la lettura \u00e8 stata effettuata a blocchi di 100 registrazioni e per 16 nodi, il test di DataStax per HBase ha mostrato una prestazione di 10.000 operazioni al secondo. <\/p>\n<p>\u00c8 fortunato che anche nel nostro cluster ci siano 16 nodi, ma non \u00e8 molto \u201efortunato\u201c che ognuno di essi abbia 64 core (thread), mentre nel test di DataStax ce n'erano solo 4. D'altra parte, loro hanno dischi SSD, mentre noi abbiamo HDD e una versione pi\u00f9 recente di HBase, e l'utilizzo della CPU durante il carico aumentava praticamente in modo non significativo (visivamente del 5-10 percento). Tuttavia, proviamo a partire con questa configurazione. Le impostazioni delle tabelle sono predefinite, la lettura viene effettuata nell'intervallo delle chiavi da 0 a 50 milioni in modo casuale (ossia, ogni volta un nuovo). Nella tabella ci sono 50 milioni di record, suddivisi in 64 partizioni. Le chiavi sono hashate tramite crc32. Le impostazioni delle tabelle sono predefinite, MSLAB \u00e8 attivo. Avviamo 40 thread, ciascun thread legge un insieme di 100 chiavi casuali e subito scrive 100 byte generati su queste chiavi. <\/p>\n<p><img decoding=\"async\" alt=\"Teoria e pratica dell&#039;uso di HBase\" src=\"\/wp-content\/uploads\/2020\/01\/776490f01121cc434135f733311b7722.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n Setup: 16 DataNode e 16 RS (CPU Xeon E5-2680 v4 @ 2.40GHz * 64 thread). Versione HBase 1.2.0-cdh5.14.2.<\/p>\n<p>Il risultato medio si avvicina a 40 mila operazioni al secondo, il che \u00e8 significativamente meglio rispetto al test di DataStax. Tuttavia, per scopi sperimentali possiamo modificare leggermente le condizioni. \u00c8 piuttosto improbabile che tutto il lavoro venga eseguito esclusivamente su una sola tabella, e solo con chiavi uniche. Supponiamo che ci sia un certo insieme di chiavi \u201ecalde\u201c che genera il carico principale. Proveremo quindi a creare un carico con record pi\u00f9 grandi (10 KB), anche in batch da 100, in 4 tabelle diverse, limitando l'intervallo delle chiavi richieste a 50 mila. Nel grafico sottostante \u00e8 mostrato l'avvio di 40 thread, ciascun thread legge un insieme di 100 chiavi e immediatamente riscrive 10 KB casuali su queste chiavi. <\/p>\n<p><img decoding=\"async\" alt=\"Teoria e pratica dell&#039;uso di HBase\" src=\"\/wp-content\/uploads\/2020\/01\/30d29f1b98663e3c07cb2be20e93876a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nSetup: 16 DataNode e 16 RS (CPU Xeon E5-2680 v4 @ 2.40GHz * 64 thread). Versione HBase 1.2.0-cdh5.14.2.<\/p>\n<p>Durante il carico \u00e8 stata eseguita pi\u00f9 volte la major compaction, come mostrato sopra, senza questa procedura le prestazioni degraderebbero gradualmente, tuttavia durante l'esecuzione si genera anche un carico aggiuntivo. I cali di prestazioni sono causati da diverse ragioni. A volte i thread terminavano il lavoro e, mentre venivano riavviati, si verificava una pausa; altre volte applicazioni esterne creavano carico sul cluster.<\/p>\n<p>La lettura e la scrittura simultanee rappresentano uno degli scenari pi\u00f9 complessi per HBase. Se si eseguono solo richieste di tipo put di piccole dimensioni, ad esempio di 100 byte, raggruppandole in pacchetti di 10-50.000 unit\u00e0, si possono ottenere centinaia di migliaia di operazioni al secondo, e lo stesso vale per le richieste di sola lettura. \u00c8 importante notare che i risultati sono radicalmente migliori rispetto a quelli ottenuti da DataStax, soprattutto grazie alle richieste in blocco da 50.000.<\/p>\n<p><img decoding=\"async\" alt=\"Teoria e pratica dell&#039;uso di HBase\" src=\"\/wp-content\/uploads\/2020\/01\/412bda50a55093224169f048ea2f863a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nSetup: 16 DataNode e 16 RS (CPU Xeon E5-2680 v4 @ 2.40GHz * 64 thread). Versione HBase 1.2.0-cdh5.14.2.<\/p>\n<h2>10. Conclusioni<\/h2>\n<p>\nQuesto sistema \u00e8 abbastanza flessibile, tuttavia l'impatto di un gran numero di parametri rimane ancora sconosciuto. Parte di essi \u00e8 stata testata, ma non \u00e8 stata inclusa nel set di risultati. Ad esempio, esperimenti preliminari hanno mostrato una significativa insignificanza di un parametro come DATA_BLOCK_ENCODING, che codifica le informazioni utilizzando i valori delle celle adiacenti, il che \u00e8 abbastanza comprensibile per i dati generati casualmente. In caso di utilizzo di un grande numero di oggetti ripetuti, il guadagno pu\u00f2 essere significativo. In generale, si pu\u00f2 dire che HBase d\u00e0 l'impressione di essere un database piuttosto serio e ben progettato, che pu\u00f2 essere molto performante nelle operazioni con grandi blocchi di dati. Soprattutto se esiste la possibilit\u00e0 di temporizzare i processi di lettura e scrittura.<\/p>\n<p>Se qualcosa non \u00e8 sufficientemente chiaro, sono disponibile a fornire ulteriori dettagli. Ti invitiamo a condividere la tua esperienza o a discutere se non sei d'accordo su qualche punto.<br \/>\n<br \/>Fonte: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/sberbank\/blog\/420425\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0414\u043e\u0431\u0440\u044b\u0439 \u0434\u0435\u043d\u044c! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u0414\u0430\u043d\u0438\u043b \u041b\u0438\u043f\u043e\u0432\u043e\u0439, \u043d\u0430\u0448\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0432 \u0421\u0431\u0435\u0440\u0442\u0435\u0445\u0435 \u043d\u0430\u0447\u0430\u043b\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c HBase \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445. \u0412 \u0445\u043e\u0434\u0435 \u0435\u0433\u043e \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u0430\u043a\u043e\u043f\u0438\u043b\u0441\u044f \u043e\u043f\u044b\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u043e\u043f\u0438\u0441\u0430\u0442\u044c (\u043d\u0430\u0434\u0435\u0435\u043c\u0441\u044f, \u0447\u0442\u043e \u043c\u043d\u043e\u0433\u0438\u043c \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0435\u0437\u043d\u043e). \u0412\u0441\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0435 \u043d\u0438\u0436\u0435 \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u044b \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u043b\u0438\u0441\u044c \u0441 \u0432\u0435\u0440\u0441\u0438\u044f\u043c\u0438 HBase 1.2.0-cdh5.14.2 \u0438 2.0.0-cdh6.0.0-beta1. \u041e\u0431\u0449\u0430\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0417\u0430\u043f\u0438\u0441\u044c \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 HBASE \u0427\u0442\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 HBASE [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-55302","post","type-post","status-publish","format-standard","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0414\u043e\u0431\u0440\u044b\u0439 \u0434\u0435\u043d\u044c! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u0414\u0430\u043d\u0438\u043b \u041b\u0438\u043f\u043e\u0432\u043e\u0439, \u043d\u0430\u0448\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0432 \u0421\u0431\u0435\u0440\u0442\u0435\u0445\u0435 \u043d\u0430\u0447\u0430\u043b\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c HBase \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/teoriya-i-praktika-ispolzovaniya-hbase\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"it_IT\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0422\u0435\u043e\u0440\u0438\u044f \u0438 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f HBase | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0414\u043e\u0431\u0440\u044b\u0439 \u0434\u0435\u043d\u044c! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u0414\u0430\u043d\u0438\u043b \u041b\u0438\u043f\u043e\u0432\u043e\u0439, \u043d\u0430\u0448\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0432 \u0421\u0431\u0435\u0440\u0442\u0435\u0445\u0435 \u043d\u0430\u0447\u0430\u043b\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c HBase \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/teoriya-i-praktika-ispolzovaniya-hbase\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-01-16T21:00:00+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-02-18T11:03:24+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Teoria e pratica dell'uso di HBase | ProHoster","description":"Buon pomeriggio! Mi chiamo Danil Lipovoy, il nostro team in SberTech ha iniziato a utilizzare HBase come archivio per i dati operativi.","canonical_url":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/teoriya-i-praktika-ispolzovaniya-hbase","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"it_IT","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0422\u0435\u043e\u0440\u0438\u044f \u0438 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f HBase | ProHoster","og:description":"\u0414\u043e\u0431\u0440\u044b\u0439 \u0434\u0435\u043d\u044c! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u0414\u0430\u043d\u0438\u043b \u041b\u0438\u043f\u043e\u0432\u043e\u0439, \u043d\u0430\u0448\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0432 \u0421\u0431\u0435\u0440\u0442\u0435\u0445\u0435 \u043d\u0430\u0447\u0430\u043b\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c HBase \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445.","og:url":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/teoriya-i-praktika-ispolzovaniya-hbase","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-01-16T21:00:00+00:00","article:modified_time":"2020-02-18T11:03:24+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"55302","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 19:46:28","updated":"2022-09-28 08:11:41","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/55302","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/comments?post=55302"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/55302\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media?parent=55302"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/categories?post=55302"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/tags?post=55302"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}