sql >> Base de Datos >  >> NoSQL >> HBase

Apache Spark llega a Apache HBase con el módulo HBase-Spark

El proyecto SparkOnHBase en Cloudera Labs se fusionó recientemente con el tronco de Apache HBase. En esta publicación, conozca la historia del proyecto y cómo se ve el futuro para el nuevo módulo HBase-Spark.

SparkOnHBase se envió por primera vez a Github en julio de 2014, solo seis meses después de Spark Summit 2013 y cinco meses después de que Apache Spark se envió por primera vez en CDH. Esa conferencia fue un gran punto de inflexión para mí, porque por primera vez me di cuenta de que el motor MapReduce tenía un competidor muy fuerte. Spark estaba a punto de entrar en una nueva fase emocionante en su ciclo de vida de código abierto, y solo un año después, se usa a escala masiva en 100, si no 1000, de empresas (con más de 200 de ellas haciéndolo en la plataforma de Cloudera).

SparkOnHBase surgió de una simple solicitud de un cliente para tener un nivel de interacción entre HBase y Spark similar al que ya está disponible entre HBase y MapReduce. Aquí hay un resumen rápido de la funcionalidad que estaba en el alcance:

  • Acceso completo a HBase en un mapa o etapa reducida
  • Capacidad de hacer una carga masiva
  • Capacidad de realizar operaciones masivas como obtener, colocar, eliminar
  • Capacidad de ser una fuente de datos para motores SQL

El lanzamiento inicial de SparkOnHBase se creó para los clientes de Cloudera que acordaron permitir que el trabajo se hiciera público. Afortunadamente, obtuve ayuda temprana de otros miembros de Clouderans y HBase PMC, Jon Hsieh y Matteo Bertozzi, y del miembro de Spark PMC, Tathagata Das, para asegurarme de que el diseño funcionaría tanto para Apache Spark básico como para Spark Streaming.

No pasó mucho tiempo antes de que otros clientes comenzaran a usar SparkOnHBase, sobre todo Edmunds.com con su aplicación Spark Streaming en tiempo real para el domingo del Super Bowl. Cuando otras empresas se sumaron, rápidamente se hizo evidente que un solo mantenedor de proyecto (es decir, yo) no iba a escalar. Afortunadamente, en ese momento, Cloudera había anunciado recientemente Cloudera Labs, que resultó ser el hogar perfecto para el proyecto. En pocas palabras, Cloudera Labs es un contenedor virtual para proyectos de ecosistemas emergentes que son jóvenes en términos de preparación, desarrollo y ambición empresarial, pero que tienen una gran demanda por parte de los usuarios que desean probar las últimas tecnologías. SparkOnHBase se convirtió en un proyecto de Cloudera Labs a su debido tiempo.

Hoy, me complace informar que SparkOnHBase se comprometió recientemente con el enlace troncal HBase (HBASE-13992). HBASE-13992 agrega SparkOnHBase al núcleo de HBase bajo un nuevo nombre, el módulo HBase-Spark. Quiero agradecer al vicepresidente de HBase, Andrew Purtell, por su aliento y "abrir la puerta" para HBASE-13992 y al miembro de PMC, Sean Busbey, por su tutoría y orientación. Además, quiero agradecer a Elliott Clark, Enis Soztutar, Michael Stack, Nicolas Liochon, Kostas Sakellis, Ted Yu, Lars Hofhansl y Steve Loughran por sus revisiones de código. (Como puede ver, SparkOnHBase fue un auténtico esfuerzo de la comunidad).

En particular, con HBASE-13992, pude agregar código Spark y Scala al proyecto Apache HBase por primera vez. ¡Fue súper divertido tener el privilegio de construir la primera prueba de unidad de Scala en la historia de HBase!

Ahora, profundicemos en los detalles técnicos.

Dentro de HBASE-13992

En HBASE-13992, verá que la mayor parte del código y el diseño originales de SparkOnHBase no se modificaron. La arquitectura básica aún se mantiene, ya que la parte central del código está diseñada para obtener un objeto de conexión HBase en cada Spark Executor.

Si bien se mantienen los aspectos básicos, existen tres diferencias principales entre el parche HBASE-13992 y el proyecto SparkOnHBase de Cloudera Labs:

  • API de HBase: HBASE-13992 utiliza todas las nuevas API HBase 1.0+ en todo momento.
  • Funciones RDD y DStream: Una de las mayores quejas sobre SparkOnHBase estaba relacionada con la forma en que se ejecutaban las funciones; Los amantes de Spark querían hacer acciones HBase directamente desde un RDD o DStream. En HBASE-13992, esa capacidad se integra mediante pruebas unitarias y ejemplos. Además, hay ejemplos de código de funciones HBase directamente desde RDD más adelante en esta publicación, para que pueda tener una idea de cómo se verán las API.
  • Fácil foreach y map funciones: Ahora es aún más fácil hacer foreachPartition s y mapPartition s con una conexión HBase. Un ejemplo seguirá más adelante en esta publicación.

Ahora, tomemos un minuto rápido y analicemos las diferencias entre el código base de SparkOnHBase y el parche HBASE-13992. Aquí hay un ejemplo rápido de bulkDelete de SparkOnHBase:

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

Tenga en cuenta que en este ejemplo estamos llamando a una función directamente desde el objeto HBaseContext, aunque la operación realmente se estaba ejecutando en el RDD. Así que ahora veamos el módulo HBase-Spark para el mismo código:

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

La gran diferencia es que hbaseBulkDelete El método sale directamente del RDD. Además, este enfoque deja la puerta abierta a las siguientes opciones con un futuro JIRA:

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

Esto es lo más limpio que puedo obtener por ahora, pero el objetivo es hacerlo aún más sencillo y limpio.

También echemos un vistazo rápido a las funciones foreach y map en HBASE-13992. Puedes ver en el ForeachPartition ejemplo a continuación que tenemos un iterador y una HBase Connection objeto. Esto nos dará pleno poder para hacer cualquier cosa con HBase mientras iteramos sobre nuestros valores:

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

Finalmente, aquí hay un ejemplo de una función de partición de mapa donde podemos obtener un objeto de conexión a medida que iteramos sobre nuestros valores:

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

Trabajo futuro

Los siguientes JIRA están en mi lista de tareas pendientes:

HBASE-14150:agregar BulkLoad funcionalidad al módulo HBase-Spark

Pronto podremos realizar cargas masivas directamente desde RDD con un código tan simple como:

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

HBASE-14181:agregue el origen de datos Spark DataFrame al módulo HBase-Spark

Con este parche, podremos integrar directamente Spark SQL con HBase y hacer cosas geniales como la selección de filtros y columnas, junto con el rango de escaneo. El objetivo de lograr la interacción entre Spark SQL y HBase es tan simple como lo siguiente:

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))

Hay otros JIRA diseñados para facilitar el uso del código y hacer que la prueba unitaria sea más completa. Mi objetivo personal es poder informar en una publicación de blog de seguimiento con todo el gran progreso que estamos logrando. El objetivo es convertir a Spark en el ciudadano de primera clase que merece ser con respecto a HBase, consolidándolo aún más como el reemplazo de MapReduce en la industria. Reemplazar MapReduce con Spark nos permitirá realizar aún más procesamiento en clústeres de HBase, sin agregar la preocupación de que habrá más contención de E/S de disco.

Tomará tiempo antes de que el módulo HBase-Spark se convierta en una versión de HBase. Mientras tanto, hay planes para transferir parte del código del módulo HBase-Spark a SparkOnHBase en Cloudera Labs. Actualmente, SparkOnHBase funciona en CDH 5.3 y 5.4, y el objetivo será actualizar SparkOnHBase con los avances del módulo HBase-Spark para la próxima versión secundaria de CDH más adelante en 2015.

Ted Malaska es arquitecto de soluciones en Cloudera, colaborador de Spark, Apache Flume y Apache HBase, y coautor del libro de O'Reilly, Arquitecturas de aplicaciones de Hadoop.