HBase
 sql >> Database >  >> NoSQL >> HBase

Apache Spark arriva su Apache HBase con il modulo HBase-Spark

Il progetto SparkOnHBase in Cloudera Labs è stato recentemente unito al trunk Apache HBase. In questo post, scopri la storia del progetto e come sarà il futuro del nuovo modulo HBase-Spark.

SparkOnHBase è stato trasferito per la prima volta su Github nel luglio 2014, appena sei mesi dopo lo Spark Summit 2013 e cinque mesi dopo la prima spedizione di Apache Spark in CDH. Quella conferenza è stata un grande punto di svolta per me, perché per la prima volta mi sono reso conto che il motore MapReduce aveva un concorrente molto forte. Spark stava per entrare in una nuova entusiasmante fase del suo ciclo di vita open source e, solo un anno dopo, viene utilizzato su vasta scala da centinaia se non migliaia di aziende (con oltre 200 di loro che lo fanno sulla piattaforma di Cloudera).

SparkOnHBase nasce da una semplice richiesta del cliente di avere un livello di interazione tra HBase e Spark simile a quello già disponibile tra HBase e MapReduce. Ecco un breve riepilogo della funzionalità che era nell'ambito di applicazione:

  • Accesso completo a HBase in una mappa o in una fase di riduzione
  • Possibilità di eseguire un carico di massa
  • Possibilità di eseguire operazioni in blocco come ottenere, inserire, eliminare
  • Possibilità di essere una fonte di dati per i motori SQL

La versione iniziale di SparkOnHBase è stata creata per un cliente Cloudera che aveva accettato di rendere pubblico il lavoro. Per fortuna, ho ricevuto aiuto in anticipo dai colleghi di Clouderans e dai membri di HBase PMC Jon Hsieh e Matteo Bertozzi e dal membro di Spark PMC Tathagata Das, per assicurarmi che il design funzionasse sia per Apache Spark di base che per Spark Streaming.

Non passò molto tempo prima che altri clienti iniziassero a utilizzare SparkOnHBase, in particolare Edmunds.com con la sua applicazione Spark Streaming in tempo reale per il Super Bowl Sunday. Quando altre società sono salite a bordo, è diventato subito chiaro che un singolo responsabile del progetto (vale a dire:me) non avrebbe scalato. Fortunatamente, in quel momento, Cloudera aveva recentemente annunciato Cloudera Labs, che si è rivelata la casa perfetta per il progetto. In parole povere, Cloudera Labs è un contenitore virtuale per progetti ecosistemici emergenti che sono giovani in termini di prontezza, sviluppo e ambizione aziendale, ma sono molto richiesti dagli utenti che vogliono provare le ultime tecnologie. SparkOnHBase è diventato un progetto di Cloudera Labs a tempo debito.

Oggi sono felice di segnalare che SparkOnHBase è stato recentemente impegnato nel trunk HBase (HBASE-13992). HBASE-13992 aggiunge SparkOnHBase al core HBase con un nuovo moniker, il modulo HBase-Spark. Voglio ringraziare il vicepresidente di HBase Andrew Purtell per il suo incoraggiamento e "aver aperto la porta" per HBASE-13992 e il membro del PMC Sean Busbey per il suo tutoraggio e guida. Inoltre, voglio ringraziare Elliott Clark, Enis Soztutar, Michael Stack, Nicolas Liochon, Kostas Sakellis, Ted Yu, Lars Hofhansl e Steve Loughran per le loro revisioni del codice. (Come puoi vedere, SparkOnHBase è stato un autentico sforzo della community.)

In particolare, con HBASE-13992, sono stato in grado di aggiungere per la prima volta il codice Spark e Scala al progetto Apache HBase. È stato super divertente avere il privilegio di costruire il primo unit test di Scala nella storia di HBase!

Ora, tuffiamoci nei dettagli tecnici.

All'interno di HBASE-13992

In HBASE-13992, vedrai che la maggior parte del codice e del design originali di SparkOnHBase sono rimasti invariati. L'architettura di base è ancora valida, in quanto la parte principale del codice è progettata per ottenere un oggetto di connessione HBase in ogni Spark Executor.

Sebbene rimangano le basi, ci sono tre differenze principali tra la patch HBASE-13992 e il progetto SparkOnHBase di Cloudera Labs:

  • API HBase: HBASE-13992 utilizza tutte le nuove API HBase 1.0+ in tutto.
  • Funzioni RDD e DStream: Uno dei maggiori reclami su SparkOnHBase relativo al modo in cui le funzioni sono state eseguite; Gli amanti di Spark volevano eseguire azioni HBase direttamente da un RDD o DStream. In HBASE-13992, tale capacità è integrata tramite unit test ed esempi. Inoltre, più avanti in questo post ci sono esempi di codice di funzioni HBase direttamente dagli RDD, così puoi avere un'idea dell'aspetto delle API.
  • Facile foreach e map funzioni: Ora è ancora più semplice fare foreachPartition se mapPartition s con una connessione HBase. Un esempio seguirà più avanti in questo post.

Ora, prendiamoci un minuto veloce ed esaminiamo le differenze tra la base di codice SparkOnHBase e la patch HBASE-13992. Ecco un rapido esempio di bulkDelete da SparkOnHBase:

val hbaseContext = new HBaseContext(sc, config);
hbaseContext.bulkDelete[Array[Byte]](rdd,
                  tableName,
                  putRecord => new Delete(putRecord),
                  4);

Si noti che in questo esempio stiamo chiamando una funzione direttamente dall'oggetto HBaseContext, anche se l'operazione è stata effettivamente eseguita sull'RDD. Quindi ora diamo un'occhiata al modulo HBase-Spark per lo stesso codice:

val hbaseContext = new HBaseContext(sc, config)
rdd.hbaseBulkDelete(hbaseContext,
                  tableName,
                  putRecord => new Delete(putRecord),
                  4)

La grande differenza è che hbaseBulkDelete il metodo viene direttamente dall'RDD. Inoltre, questo approccio lascia la porta aperta alle seguenti opzioni con una futura JIRA:

val hbaseContext = new HBaseContext(sc, config)
rdd.hbaseBulkDelete(tableName)

Per ora è il più pulito possibile, ma l'obiettivo è renderlo ancora di più semplice e pulito.

Diamo anche una rapida occhiata alle funzioni foreach e map in HBASE-13992. Puoi vedere in ForeachPartition esempio di seguito che abbiamo un iteratore e un HBase Connection oggetto. Questo ci darà il pieno potere di fare qualsiasi cosa con HBase mentre ripetiamo i nostri valori:

val hbaseContext = new HBaseContext(sc, config)
rdd.hbaseForeachPartition(hbaseContext, (it, conn) => {
      val bufferedMutator = conn.getBufferedMutator(TableName.valueOf("t1"))
      ...
      bufferedMutator.flush()
      bufferedMutator.close()
    })

Infine, ecco un esempio di una funzione di partizione della mappa in cui possiamo ottenere un oggetto connessione mentre ripetiamo i nostri valori:

val getRdd = rdd.hbaseMapPartitions(hbaseContext, (it, conn) => {
        val table = conn.getTable(TableName.valueOf("t1"))
        var res = mutable.MutableList[String]()
        ...
      })

Lavori futuri

Le seguenti JIRA sono nella mia lista delle cose da fare:

HBASE-14150 – Aggiungi BulkLoad funzionalità al modulo HBase-Spark

Presto saremo in grado di eseguire carichi in blocco direttamente dagli RDD con un codice che sembra semplice come:

 rdd.hbaseBulkLoad (tableName,
             t => {
            Seq((new KeyFamilyQualifier(t.rowKey, t.family, t.qualifier), t.value)).
            iterator
            },
      stagingFolder)

HBASE-14181 – Aggiungi Spark DataFrame DataSource al modulo HBase-Spark

Con questa patch, saremo in grado di integrare direttamente Spark SQL con HBase e fare cose interessanti come il pushdown di selezione di filtri e colonne, insieme al pushdown dell'intervallo di scansione. L'obiettivo di ottenere l'interazione Spark SQL e HBase è semplice come il seguente:

val df = sqlContext.load("org.apache.hadoop.hbase.spark",
      Map("hbase.columns.mapping" -> "KEY_FIELD STRING :key, A_FIELD STRING c:a, B_FIELD STRING c:b,",
      "hbase.table" -> "t1"))
df.registerTempTable("hbaseTmp")

sqlContext.sql("SELECT KEY_FIELD FROM hbaseTmp " +
      "WHERE " +
      "(KEY_FIELD = 'get1' and B_FIELD < '3') or " +
      "(KEY_FIELD <= 'get3' and B_FIELD = '8')").foreach(r => println(" - " + r))

Esistono altri JIRA progettati per rendere il codice più facile da usare e rendere lo unit test più completo. Il mio obiettivo personale è poter riferire in un post di follow-up sul blog tutti i grandi progressi che stiamo facendo. L'obiettivo è trasformare Spark nel cittadino di prima classe che merita di essere rispetto a HBase, consolidandolo ulteriormente come sostituto di MapReduce nel settore. La sostituzione di MapReduce con Spark ci consentirà di eseguire ancora più elaborazioni sui cluster HBase, senza aggiungere la preoccupazione che ci saranno più conflitti di I/O del disco.

Ci vorrà del tempo prima che il modulo HBase-Spark diventi una versione di HBase. Nel frattempo, ci sono piani per eseguire il backport di parte del codice dal modulo HBase-Spark in SparkOnHBase in Cloudera Labs. Attualmente, SparkOnHBase funziona su CDH 5.3 e 5.4 e l'obiettivo sarà aggiornare SparkOnHBase con i progressi del modulo HBase-Spark per la prossima versione minore CDH più avanti nel 2015.

Ted Malaska è un Solutions Architect presso Cloudera, un collaboratore di Spark, Apache Flume e Apache HBase e coautore del libro di O'Reilly, Architetture delle applicazioni Hadoop.