HBase、MapReduce和CLASSPATH

2018-03-31 14:49 更新

HBase,MapReduce和CLASSPATH

默認(rèn)情況下,部署到 MapReduce 集群的 MapReduce 作業(yè)無權(quán)訪問 $HBASE_CONF_DIR 類或 HBase 類下的 HBase 配置。

要為 MapReduce 作業(yè)提供他們需要的訪問權(quán)限,可以添加 hbase-site.xml_to _ $ HADOOP_HOME / conf,并將 HBase jar 添加到 $ HADOOP_HOME / lib 目錄。然后,您需要在群集中復(fù)制這些更改?;蛘吣憧梢跃庉?$ HADOOP_HOME / conf / hadoop-env.sh,并將 hbase 依賴添加到HADOOP_CLASSPATH 變量中。這兩種方法都不推薦使用,因?yàn)樗鼤?huì)使用 HBase 引用污染您的 Hadoop 安裝。它還需要您在 Hadoop 可以使用 HBase 數(shù)據(jù)之前重新啟動(dòng) Hadoop 集群。

推薦的方法是讓 HBase 添加它的依賴 jar 并使用 HADOOP_CLASSPATHor -libjars。

自 HBase 0.90.x 以來,HBase 將其依賴 JAR 添加到作業(yè)配置本身。依賴關(guān)系只需要在本地 CLASSPATH 可用,從這里它們將被拾取并捆綁到部署到MapReduce 集群的 fat 工作 jar 中。一個(gè)基本的技巧就是將完整的 hbase 類路徑(所有 hbase 和依賴 jar 以及配置)傳遞給 mapreduce 作業(yè)運(yùn)行器,讓hbase 實(shí)用程序從完整類路徑中選取需要將其添加到 MapReduce 作業(yè)配置中的源代碼。 

下面的示例針對(duì)名為 usertable 的表運(yùn)行捆綁的 HBase RowCounter MapReduce 作業(yè)。它設(shè)置為 HADOOP_CLASSPATH 需要在 MapReduce 上下文中運(yùn)行的 jar 包(包括配置文件,如 hbase-site.xml)。確保為您的系統(tǒng)使用正確版本的 HBase JAR;請(qǐng)?jiān)谙旅娴拿钚兄刑鎿Q VERSION 字符串 w/本地 hbase 安裝的版本。反引號(hào)(`符號(hào))使 shell 執(zhí)行子命令,設(shè)置輸入 hbase classpath 為 HADOOP_CLASSPATH。這個(gè)例子假設(shè)你使用 BASH 兼容的 shell。

$ HADOOP_CLASSPATH=`${HBASE_HOME}/bin/hbase classpath` \
  ${HADOOP_HOME}/bin/hadoop jar ${HBASE_HOME}/lib/hbase-mapreduce-VERSION.jar \
  org.apache.hadoop.hbase.mapreduce.RowCounter usertable

上述的命令將針對(duì) hadoop 配置指向的群集上的本地配置指向的 hbase 群集啟動(dòng)行計(jì)數(shù) mapreduce 作業(yè)。

hbase-mapreduce.jar 的主要內(nèi)容是一個(gè) Driver(驅(qū)動(dòng)程序),它列出了幾個(gè)與 hbase 一起使用的基本 mapreduce 任務(wù)。例如,假設(shè)您的安裝是hbase 2.0.0-SNAPSHOT:

$ HADOOP_CLASSPATH=`${HBASE_HOME}/bin/hbase classpath` \
  ${HADOOP_HOME}/bin/hadoop jar ${HBASE_HOME}/lib/hbase-mapreduce-2.0.0-SNAPSHOT.jar
An example program must be given as the first argument.
Valid program names are:
  CellCounter: Count cells in HBase table.
  WALPlayer: Replay WAL files.
  completebulkload: Complete a bulk data load.
  copytable: Export a table from local cluster to peer cluster.
  export: Write table data to HDFS.
  exportsnapshot: Export the specific snapshot to a given FileSystem.
  import: Import data written by Export.
  importtsv: Import data in TSV format.
  rowcounter: Count rows in HBase table.
  verifyrep: Compare the data from tables in two different clusters. WARNING: It doesn't work for incrementColumnValues'd cells since the timestamp is changed after being appended to the log.

您可以使用上面列出的縮短名稱作為 mapreduce 作業(yè),如下面的行計(jì)數(shù)器作業(yè)重新運(yùn)行(再次假設(shè)您的安裝為 hbase 2.0.0-SNAPSHOT):

$ HADOOP_CLASSPATH=`${HBASE_HOME}/bin/hbase classpath` \
  ${HADOOP_HOME}/bin/hadoop jar ${HBASE_HOME}/lib/hbase-mapreduce-2.0.0-SNAPSHOT.jar \
  rowcounter usertable

您可能會(huì)發(fā)現(xiàn)更多有選擇性的 hbase mapredcp 工具輸出;它列出了針對(duì) hbase 安裝運(yùn)行基本 mapreduce 作業(yè)所需的最小 jar 集。它不包括配置。如果您希望MapReduce 作業(yè)找到目標(biāo)群集,則可能需要添加這些文件。一旦你開始做任何實(shí)質(zhì)的事情,你可能還必須添加指向額外的 jar 的指針。只需在運(yùn)行 hbase mapredcp 時(shí)通過系統(tǒng)屬性 Dtmpjars 來指定附加項(xiàng)。

對(duì)于不打包它們的依賴關(guān)系或調(diào)用 TableMapReduceUtil#addDependencyJars 的作業(yè),以下命令結(jié)構(gòu)是必需的:

$ HADOOP_CLASSPATH=`${HBASE_HOME}/bin/hbase mapredcp`:${HBASE_HOME}/conf hadoop jar MyApp.jar MyJobMainClass -libjars $(${HBASE_HOME}/bin/hbase mapredcp | tr ':' ',') ...

注意

如果您從構(gòu)建目錄運(yùn)行 HBase 而不是安裝位置,該示例可能無法運(yùn)行。您可能會(huì)看到類似以下的錯(cuò)誤:

java.lang.RuntimeException: java.lang.ClassNotFoundException: org.apache.hadoop.hbase.mapreduce.RowCounter$RowCounterMapper

如果發(fā)生這種情況,請(qǐng)嘗試按如下方式修改該命令,以便在構(gòu)建環(huán)境中使用來自 target/ 目錄的 HBase JAR 。

$ HADOOP_CLASSPATH=${HBASE_BUILD_HOME}/hbase-mapreduce/target/hbase-mapreduce-VERSION-SNAPSHOT.jar:`${HBASE_BUILD_HOME}/bin/hbase classpath` ${HADOOP_HOME}/bin/hadoop jar ${HBASE_BUILD_HOME}/hbase-mapreduce/target/hbase-mapreduce-VERSION-SNAPSHOT.jar rowcounter usertable

HBase MapReduce 用戶在 0.96.1 和 0.98.4 的通知

一些使用 HBase 的 MapReduce 作業(yè)無法啟動(dòng)。該癥狀是類似于以下情況的異常:

Exception in thread "main" java.lang.IllegalAccessError: class
    com.google.protobuf.ZeroCopyLiteralByteString cannot access its superclass
    com.google.protobuf.LiteralByteString
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:792)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at
    org.apache.hadoop.hbase.protobuf.ProtobufUtil.toScan(ProtobufUtil.java:818)
    at
    org.apache.hadoop.hbase.mapreduce.TableMapReduceUtil.convertScanToString(TableMapReduceUtil.java:433)
    at
    org.apache.hadoop.hbase.mapreduce.TableMapReduceUtil.initTableMapperJob(TableMapReduceUtil.java:186)
    at
    org.apache.hadoop.hbase.mapreduce.TableMapReduceUtil.initTableMapperJob(TableMapReduceUtil.java:147)
    at
    org.apache.hadoop.hbase.mapreduce.TableMapReduceUtil.initTableMapperJob(TableMapReduceUtil.java:270)
    at
    org.apache.hadoop.hbase.mapreduce.TableMapReduceUtil.initTableMapperJob(TableMapReduceUtil.java:100)
...

這是由 HBASE-9867 中引入的優(yōu)化導(dǎo)致的,它無意中引入了類加載器依賴性。

這會(huì)影響兩個(gè)作業(yè),即使用 libjars 選項(xiàng)和  "fat jar" (在嵌套的 lib 文件夾中打包其運(yùn)行時(shí)依賴項(xiàng))。

為了滿足新的加載器要求,hbase-protocol.jar 必須包含在 Hadoop 的類路徑中。以下內(nèi)容包括用于歷史目的。

通過在 Hadoop 的 lib 目錄中包括對(duì) hbase-protocol.jar 協(xié)議的引用,通過 symlink 或?qū)?nbsp;jar 復(fù)制到新的位置,可以解決整個(gè)系統(tǒng)。

這也可以通過 HADOOP_CLASSPATH 在作業(yè)提交時(shí)將它包含在環(huán)境變量中來實(shí)現(xiàn)。啟動(dòng)打包依賴關(guān)系的作業(yè)時(shí),以下所有三個(gè)啟動(dòng)命令均滿足此要求:

$ HADOOP_CLASSPATH=/path/to/hbase-protocol.jar:/path/to/hbase/conf hadoop jar MyJob.jar MyJobMainClass
$ HADOOP_CLASSPATH=$(hbase mapredcp):/path/to/hbase/conf hadoop jar MyJob.jar MyJobMainClass
$ HADOOP_CLASSPATH=$(hbase classpath) hadoop jar MyJob.jar MyJobMainClass

對(duì)于不打包它們的依賴關(guān)系的 jar,下面的命令結(jié)構(gòu)是必需的:

$ HADOOP_CLASSPATH=$(hbase mapredcp):/etc/hbase/conf hadoop jar MyApp.jar MyJobMainClass -libjars $(hbase mapredcp | tr ':' ',') ...
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)