Projekt SparkOnHBase w Cloudera Labs został niedawno połączony z łączem Apache HBase. W tym poście poznaj historię projektu i jak wygląda przyszłość nowego modułu HBase-Spark.
SparkOnHBase został po raz pierwszy wypchnięty na Github w lipcu 2014 r., zaledwie sześć miesięcy po Spark Summit 2013 i pięć miesięcy po pierwszym wysłaniu Apache Spark w CDH. Ta konferencja była dla mnie dużym punktem zwrotnym, ponieważ po raz pierwszy zdałem sobie sprawę, że silnik MapReduce ma bardzo silnego konkurenta. Spark miał wejść w ekscytującą nową fazę swojego cyklu życia oprogramowania open source, a zaledwie rok później jest używany na masową skalę w setkach, jeśli nie tysiącach firm (ponad 200 robi to na platformie Cloudera).
SparkOnHBase powstał z prostej prośby klienta o poziom interakcji między HBase i Spark podobny do tego, który jest już dostępny między HBase i MapReduce. Oto krótkie podsumowanie funkcjonalności, która była w zakresie:
- Pełny dostęp do HBase na mapie lub zredukowany etap
- Możliwość ładowania zbiorczego
- Możliwość wykonywania operacji zbiorczych, takich jak pobieranie, umieszczanie, usuwanie
- Możliwość bycia źródłem danych dla silników SQL
Wstępne wydanie SparkOnHBase zostało zbudowane dla klientów Cloudera, którzy zgodzili się na upublicznienie pracy. Na szczęście otrzymałem wczesną pomoc od innych członków Clouderans i HBase PMC, Jona Hsieha i Matteo Bertozziego, oraz członka Spark PMC Tathagaty Dasa, aby upewnić się, że projekt będzie działał zarówno dla podstawowego Apache Spark, jak i Spark Streaming.
Nie minęło dużo czasu, zanim inni klienci zaczęli używać SparkOnHBase — w szczególności Edmunds.com z aplikacją Spark Streaming w czasie rzeczywistym na Super Bowl Sunday. Kiedy dołączyły inne firmy, szybko stało się jasne, że jeden opiekun projektu (mianowicie:ja) nie będzie się skalował. Na szczęście w tamtym czasie firma Cloudera ogłosiła niedawno Cloudera Labs, które okazały się idealnym domem dla projektu. Mówiąc prościej, Cloudera Labs to wirtualny kontener dla powstających projektów ekosystemowych, które są młode pod względem gotowości korporacyjnej, rozwoju i ambicji, ale są bardzo poszukiwane przez użytkowników, którzy chcą wypróbować najnowsze technologie. SparkOnHBase stał się w odpowiednim czasie projektem Cloudera Labs.
Dzisiaj z przyjemnością donoszę, że SparkOnHBase został niedawno przydzielony do trunka HBase (HBASE-13992). HBASE-13992 dodaje SparkOnHBase do rdzenia HBase pod nowym pseudonimem, moduł HBase-Spark. Chciałbym podziękować wiceprezesowi HBase Andrew Purtellowi za zachętę i „otwarcie drzwi” dla HBASE-13992 i członka PMC Seana Busbeya za jego mentoring i wskazówki. Chciałbym również podziękować Elliottowi Clarkowi, Enisowi Soztutarowi, Michaelowi Stackowi, Nicolasowi Liochonowi, Kostasowi Sakellisowi, Tedowi Yu, Larsowi Hofhanslowi i Steve'owi Loughranowi za ich przeglądy kodu. (Jak widać, SparkOnHBase był autentycznym wysiłkiem społeczności.)
Warto zauważyć, że dzięki HBASE-13992 mogłem po raz pierwszy w historii dodać kod Spark i Scala do projektu Apache HBase. Możliwość zbudowania pierwszego testu jednostkowego Scala w historii HBase była super zabawą!
Przejdźmy teraz do szczegółów technicznych.
Wewnątrz HBASE-13992
W HBASE-13992 zobaczysz, że większość oryginalnego kodu i projektu z SparkOnHBase pozostaje niezmieniona. Podstawowa architektura nadal obowiązuje, ponieważ główna część kodu jest zaprojektowana tak, aby uzyskać obiekt połączenia HBase w każdym Spark Executor.
Chociaż podstawy pozostają, istnieją trzy główne różnice między łatką HBASE-13992 a projektem Cloudera Labs SparkOnHBase:
- Interfejsy API HBase: HBASE-13992 używa wszystkich nowych interfejsów API HBase 1.0+ w całym tekście.
- Funkcje RDD i DStream: Jedna z największych skarg dotyczących SparkOnHBase dotyczyła sposobu wykonywania funkcji; Miłośnicy Sparka chcieli, aby działania HBase były prosto z RDD lub DStream. W HBASE-13992 ta możliwość jest wbudowana za pomocą testów jednostkowych i przykładów. Ponadto w dalszej części tego wpisu znajdują się przykłady kodu funkcji HBase bezpośrednio z RDD, dzięki czemu możesz poczuć, jak będą wyglądać interfejsy API.
- Łatwe
foreach
imap
funkcje: Teraz jeszcze łatwiej jest zrobićforeachPartition
s imapPartition
s z połączeniem HBase. Przykład zostanie podany w dalszej części tego postu.
Teraz poświęćmy chwilę i przejrzyjmy różnice między bazą kodu SparkOnHBase a poprawką HBASE-13992. Oto krótki przykład bulkDelete
od SparkOnHBase:
val hbaseContext = new HBaseContext(sc, config); hbaseContext.bulkDelete[Array[Byte]](rdd, tableName, putRecord => new Delete(putRecord), 4);
Zauważ, że w tym przykładzie wywołujemy funkcję bezpośrednio z obiektu HBaseContext, mimo że operacja była naprawdę wykonywana na RDD. Spójrzmy teraz na moduł HBase-Spark dla tego samego kodu:
val hbaseContext = new HBaseContext(sc, config) rdd.hbaseBulkDelete(hbaseContext, tableName, putRecord => new Delete(putRecord), 4)
Duża różnica polega na tym, że hbaseBulkDelete
metoda pochodzi prosto z RDD. Takie podejście pozostawia również otwarte drzwi dla następujących opcji w przyszłej JIRA:
val hbaseContext = new HBaseContext(sc, config) rdd.hbaseBulkDelete(tableName)
Na razie jest tak czysty, jak tylko mogę, ale celem jest, aby było jeszcze więcej proste i czyste.
Rzućmy też okiem na funkcje foreach i mapy w HBASE-13992. Możesz zobaczyć w ForeachPartition
przykład poniżej, że mamy iterator i HBase Connection
obiekt. To da nam pełną moc do zrobienia czegokolwiek z HBase podczas iteracji naszych wartości:
val hbaseContext = new HBaseContext(sc, config) rdd.hbaseForeachPartition(hbaseContext, (it, conn) => { val bufferedMutator = conn.getBufferedMutator(TableName.valueOf("t1")) ... bufferedMutator.flush() bufferedMutator.close() })
Na koniec, oto przykład funkcji partycji mapy, w której możemy uzyskać obiekt połączenia podczas iteracji naszych wartości:
val getRdd = rdd.hbaseMapPartitions(hbaseContext, (it, conn) => { val table = conn.getTable(TableName.valueOf("t1")) var res = mutable.MutableList[String]() ... })
Praca w przyszłości
Na mojej liście rzeczy do zrobienia znajdują się następujące JIRA:
HBASE-14150 – Dodaj BulkLoad
funkcjonalność modułu HBase-Spark
Wkrótce będziemy mogli wykonywać masowe ładowanie bezpośrednio z RDD z kodem, który wygląda tak prosto, jak:
rdd.hbaseBulkLoad (tableName, t => { Seq((new KeyFamilyQualifier(t.rowKey, t.family, t.qualifier), t.value)). iterator }, stagingFolder)
HBASE-14181 – Dodaj źródło danych Spark DataFrame do modułu HBase-Spark
Dzięki tej poprawce będziemy mogli bezpośrednio zintegrować Spark SQL z HBase i robić fajne rzeczy, takie jak przesuwanie w dół wyboru filtrów i kolumn, a także przesuwanie zakresu skanowania. Cel uzyskania interakcji Spark SQL i HBase jest tak prosty, jak poniżej:
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))
Istnieją inne JIRA zaprojektowane tak, aby ułatwić korzystanie z kodu i uczynić test jednostkowy bardziej wszechstronnym. Moim osobistym celem jest możliwość zrelacjonowania w kolejnym poście na blogu wszystkich wielkich postępów, jakie robimy. Celem jest przekształcenie Sparka w pierwszorzędnego obywatela, na który zasługuje w odniesieniu do HBase, dodatkowo umacniając go jako zamiennik MapReduce w branży. Zastąpienie MapReduce Spark pozwoli nam na jeszcze więcej przetwarzania w klastrach HBase, bez obawy, że będzie więcej rywalizacji o IO dysków.
Minie trochę czasu, zanim moduł HBase-Spark przejdzie do wersji HBase. W międzyczasie planuje się backport części kodu z modułu HBase-Spark do SparkOnHBase w Cloudera Labs. Obecnie SparkOnHBase działa na CDH 5.3 i 5.4, a celem będzie aktualizacja SparkOnHBase za pomocą udoskonaleń modułu HBase-Spark dla nadchodzącego wydania pomocniczego CDH, które nastąpi później w 2015 roku.
Ted Malaska jest architektem rozwiązań w Cloudera, współtwórcą Spark, Apache Flume i Apache HBase oraz współautorem książki O’Reilly, Architektury aplikacji Hadoop.