HBase
 sql >> Base de Dados >  >> NoSQL >> HBase

Apache Spark chega ao Apache HBase com módulo HBase-Spark


O projeto SparkOnHBase no Cloudera Labs foi recentemente integrado ao tronco do Apache HBase. Neste post, conheça a história do projeto e como será o futuro do novo módulo HBase-Spark.

O SparkOnHBase foi lançado pela primeira vez no Github em julho de 2014, apenas seis meses após o Spark Summit 2013 e cinco meses após o lançamento do Apache Spark no CDH. Essa conferência foi um grande ponto de virada para mim, porque pela primeira vez percebi que o mecanismo MapReduce tinha um concorrente muito forte. O Spark estava prestes a entrar em uma nova fase empolgante em seu ciclo de vida de código aberto e, apenas um ano depois, é usado em grande escala em 100, se não 1000, de empresas (com mais de 200 delas fazendo isso na plataforma da Cloudera).

O SparkOnHBase surgiu de uma simples solicitação do cliente para ter um nível de interação entre HBase e Spark semelhante ao já disponível entre HBase e MapReduce. Aqui está um breve resumo da funcionalidade que estava no escopo:
  • Acesso total ao HBase em um mapa ou estágio de redução
  • Capacidade de fazer um carregamento em massa
  • Capacidade de fazer operações em massa como obter, colocar, excluir
  • Capacidade de ser uma fonte de dados para mecanismos SQL

A versão inicial do SparkOnHBase foi criada para clientes da Cloudera que concordaram em permitir que o trabalho se tornasse público. Felizmente, recebi ajuda antecipada de colegas membros do Clouderans e do HBase PMC, Jon Hsieh e Matteo Bertozzi, e do membro do Spark PMC, Tathagata Das, para garantir que o design funcionasse tanto para o Apache Spark básico quanto para o Spark Streaming.

Não demorou muito para que outros clientes começassem a usar o SparkOnHBase, principalmente o Edmunds.com com seu aplicativo Spark Streaming em tempo real para o Super Bowl Sunday. Quando outras empresas aderiram, rapidamente ficou claro que um único mantenedor de projeto (ou seja:eu) não seria dimensionado. Felizmente, naquela época, a Cloudera havia anunciado recentemente o Cloudera Labs, que acabou sendo o lar perfeito para o projeto. Simplificando, o Cloudera Labs é um contêiner virtual para projetos de ecossistemas emergentes que são jovens em termos de prontidão, desenvolvimento e ambição empresarial, mas estão em alta demanda por usuários que desejam experimentar as tecnologias mais recentes. SparkOnHBase tornou-se um projeto Cloudera Labs no devido tempo.

Hoje, estou feliz em informar que SparkOnHBase foi recentemente comprometido com o tronco HBase (HBASE-13992). HBASE-13992 adiciona SparkOnHBase ao núcleo HBase sob um novo apelido, o módulo HBase-Spark. Quero agradecer ao vice-presidente da HBase, Andrew Purtell, por seu incentivo e “abrir a porta” para o HBASE-13992 e ao membro do PMC, Sean Busbey, por sua orientação e orientação. Além disso, quero agradecer a Elliott Clark, Enis Soztutar, Michael Stack, Nicolas Liochon, Kostas Sakellis, Ted Yu, Lars Hofhansl e Steve Loughran por suas revisões de código. (Como você pode ver, o SparkOnHBase foi um autêntico esforço da comunidade.)

Notavelmente, com o HBASE-13992, consegui adicionar código Spark e Scala ao projeto Apache HBase pela primeira vez. Foi superdivertido ter o privilégio de construir o primeiro teste unitário Scala na história do HBase!

Agora, vamos mergulhar nos detalhes técnicos.

Dentro do HBASE-13992


No HBASE-13992, você verá que a maior parte do código e design originais do SparkOnHBase permanecem inalterados. A arquitetura básica ainda se mantém, pois a parte central do código é projetada para obter um objeto de conexão HBase em cada Spark Executor.



Embora o básico permaneça, existem três grandes diferenças entre o patch HBASE-13992 e o projeto Cloudera Labs SparkOnHBase:

  • APIs HBase: O HBASE-13992 usa todas as novas APIs do HBase 1.0+.
  • Funções RDD e DStream: Uma das maiores reclamações sobre o SparkOnHBase estava relacionada à forma como as funções eram executadas; Os amantes do Spark queriam fazer ações do HBase diretamente de um RDD ou DStream. No HBASE-13992, esse recurso é incorporado por meio de testes de unidade e exemplos. Além disso, há exemplos de código de funções HBase diretamente de RDDs mais adiante neste post, para que você possa ter uma ideia de como as APIs serão.
  • Fácil foreach e map funções: Agora ficou ainda mais fácil fazer foreachPartition se mapPartition s com uma conexão HBase. Um exemplo seguirá mais adiante nesta postagem.

Agora, vamos dar um rápido minuto e percorrer as diferenças entre a base de código SparkOnHBase e o patch HBASE-13992. Aqui está um exemplo rápido de bulkDelete do SparkOnHBase:
val hbaseContext = new HBaseContext(sc, config);
hbaseContext.bulkDelete[Array[Byte]](rdd,
                  tableName,
                  putRecord => new Delete(putRecord),
                  4);

Observe que neste exemplo estamos chamando uma função diretamente do objeto HBaseContext, mesmo que a operação estivesse realmente sendo executada no RDD. Então agora vamos olhar para o módulo HBase-Spark para o mesmo código:
val hbaseContext = new HBaseContext(sc, config)
rdd.hbaseBulkDelete(hbaseContext,
                  tableName,
                  putRecord => new Delete(putRecord),
                  4)

A grande diferença é que o hbaseBulkDelete método vem direto do RDD. Além disso, essa abordagem deixa a porta aberta para as seguintes opções com um futuro JIRA:
val hbaseContext = new HBaseContext(sc, config)
rdd.hbaseBulkDelete(tableName)

Isso é o mais limpo possível por enquanto, mas o objetivo é torná-lo ainda mais simples e limpo.

Vamos também dar uma olhada rápida nas funções foreach e map no HBASE-13992. Você pode ver no ForeachPartition exemplo abaixo que temos um iterador e um HBase Connection objeto. Isso nos dará poder total para fazer qualquer coisa com o HBase à medida que iteramos nossos valores:
val hbaseContext = new HBaseContext(sc, config)
rdd.hbaseForeachPartition(hbaseContext, (it, conn) => {
      val bufferedMutator = conn.getBufferedMutator(TableName.valueOf("t1"))
      ...
      bufferedMutator.flush()
      bufferedMutator.close()
    })

Finalmente, aqui está um exemplo de uma função de partição de mapa onde podemos obter um objeto de conexão à medida que iteramos nossos valores:
val getRdd = rdd.hbaseMapPartitions(hbaseContext, (it, conn) => {
        val table = conn.getTable(TableName.valueOf("t1"))
        var res = mutable.MutableList[String]()
        ...
      })

Trabalho futuro


Os seguintes JIRAs estão na minha lista de tarefas:

HBASE-14150 – Adicionar BulkLoad funcionalidade para o módulo HBase-Spark

Em breve poderemos fazer cargas em massa diretamente de RDDs com código que parece tão simples quanto:
 rdd.hbaseBulkLoad (tableName,
             t => {
            Seq((new KeyFamilyQualifier(t.rowKey, t.family, t.qualifier), t.value)).
            iterator
            },
      stagingFolder)

HBASE-14181 – Adicionar Spark DataFrame DataSource ao módulo HBase-Spark

Com este patch, poderemos integrar diretamente o Spark SQL ao HBase e fazer coisas legais como pushdown de seleção de filtro e coluna, juntamente com pushdown de intervalo de varredura. O objetivo de obter a interação Spark SQL e HBase é tão simples quanto o seguinte:
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))

Existem outros JIRAs projetados para tornar o código mais fácil de usar e tornar o teste de unidade mais abrangente. Meu objetivo pessoal é poder relatar em uma postagem de blog de acompanhamento todo o grande progresso que estamos fazendo. O objetivo é transformar o Spark no cidadão de primeira classe que merece ser em relação ao HBase, solidificando-o ainda mais como o substituto do MapReduce na indústria. Substituir o MapReduce pelo Spark nos permitirá fazer ainda mais processamento em clusters HBase, sem adicionar a preocupação de que haverá mais contenção de E/S de disco.

Levará algum tempo até que o módulo HBase-Spark se torne uma versão do HBase. Enquanto isso, há planos de retroportar parte do código do módulo HBase-Spark para o SparkOnHBase no Cloudera Labs. Atualmente, o SparkOnHBase funciona no CDH 5.3 e 5.4, e o objetivo será atualizar o SparkOnHBase com os avanços do módulo HBase-Spark para a próxima versão secundária do CDH no final de 2015.

Ted Malaska é arquiteto de soluções na Cloudera, colaborador do Spark, Apache Flume e Apache HBase e coautor do livro O'Reilly, Arquiteturas de aplicativos Hadoop.