2

我正在尝试针对我们位于 Google Cloud Storage 上的压缩数据在 Google Compute 引擎上运行 Hadoop Job。尝试通过 SequenceFileInputFormat 读取数据时,出现以下异常:

hadoop@hadoop-m:/home/salikeeno$ hadoop jar ${JAR} ${PROJECT} ${OUTPUT_TABLE}
14/08/21 19:56:00 INFO jaws.JawsApp: Using export bucket 'askbuckerthroughhadoop' as specified in 'mapred.bq.gcs.bucket'
14/08/21 19:56:00 INFO bigquery.BigQueryConfiguration: Using specified project-id 'regal-campaign-641' for output
14/08/21 19:56:00 INFO gcs.GoogleHadoopFileSystemBase: GHFS version: 1.2.8-hadoop1
14/08/21 19:56:01 WARN mapred.JobClient: Use GenericOptionsParser for parsing the arguments. Applications should implement Tool for the same.
14/08/21 19:56:03 INFO input.FileInputFormat: Total input paths to process : 1
14/08/21 19:56:09 INFO mapred.JobClient: Running job: job_201408211943_0002
14/08/21 19:56:10 INFO mapred.JobClient:  map 0% reduce 0%
14/08/21 19:56:20 INFO mapred.JobClient: Task Id : attempt_201408211943_0002_m_000001_0, Status : FAILED
java.lang.RuntimeException: native snappy library not available
        at org.apache.hadoop.io.compress.SnappyCodec.getDecompressorType(SnappyCodec.java:189)
        at org.apache.hadoop.io.compress.CodecPool.getDecompressor(CodecPool.java:125)
        at org.apache.hadoop.io.SequenceFile$Reader.init(SequenceFile.java:1581)
        at org.apache.hadoop.io.SequenceFile$Reader.<init>(SequenceFile.java:1490)
        at org.apache.hadoop.io.SequenceFile$Reader.<init>(SequenceFile.java:1479)
        at org.apache.hadoop.io.SequenceFile$Reader.<init>(SequenceFile.java:1474)
        at org.apache.hadoop.mapreduce.lib.input.SequenceFileRecordReader.initialize(SequenceFileRecordReader.java:50)
        at org.apache.hadoop.mapred.MapTask$NewTrackingRecordReader.initialize(MapTask.java:521)
        at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:763)
        at org.apache.hadoop.mapred.MapTask.run(MapTask.java:364)
        at org.apache.hadoop.mapred.Child$4.run(Child.java:255)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.Subject.doAs(Subject.java:415)
        at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1190)
        at org.apache.hadoop.mapred.Child.main(Child.java:249)
  1. 似乎 SnappyCodec 不可用。我应该如何在谷歌计算引擎上的 Hadoop 集群中包含/启用 Snappy?
  2. 在部署 Hadoop 集群时,我可以通过 bdutil 脚本部署 Snappy lib(如果必须的话)吗?
  3. 在 Google Compute 引擎上部署的 Hadoop 集群上部署第三方库/jar 的最佳方法是什么?

非常感谢

4

1 回答 1

7

不再需要此过程。

默认情况下,bdutil 部署将包含 Snappy。

供参考,原来的答案:

你的最后一个问题在一般情况下最容易回答,所以我将从那里开始。交付依赖项的一般指导是应用程序应利用分布式缓存将 JAR 和库分发给工作人员(Hadoop 1 或 2)。如果您的代码已经在使用 GenericOptionsParser,您可以使用 -libjars 标志分发 JAR。更长的讨论可以在 Cloudera 的博客上找到,该博客也讨论了胖 JAR: http: //blog.cloudera.com/blog/2011/01/how-to-include-third-party-libraries-in-your-map-reduce -工作/

对于安装和配置其他系统级组件,bdutil 支持扩展机制。一个很好的扩展示例是与 bdutil 捆绑在一起的 Spark 扩展:extensions/spark/spark_env.sh。当运行 bdutil 扩展时添加了 -e 标志,例如,使用 Hadoop 部署 Spark:

./bdutil -e extensions/spark/spark_env.sh deploy    

关于您的第一个和第二个问题:在 GCE 上的 Hadoop 中处理 Snappy 时有两个障碍。首先是由 Apache 构建并与 Hadoop 2 tarball 捆绑在一起的本机支持库是为 i386 构建的,而 GCE 实例是 amd64。Hadoop 1 为两个平台捆绑了二进制文件,但如果不捆绑或修改环境,snappy 就无法定位。由于这种架构差异,在 Hadoop 2 中没有可用的本地压缩器(snappy 或其他),并且在 Hadoop 1 中不容易使用 Snappy。第二个障碍是默认情况下未安装 libsnappy 本身。

克服这两个问题的最简单方法是创建自己的 Hadoop tarball,其中包含 amd64 原生 Hadoop 库以及 libsnappy。下面的步骤应该可以帮助您执行此操作并暂存生成的 tarball 以供 bdutil 使用。

首先,使用 Debian Wheezy 反向移植映像启动一个新的 GCE VM,并授予 VM 服务帐户对云存储的读/写访问权限。我们将使用它作为我们的构建机器,一旦我们完成构建/存储二进制文件,我们就可以安全地丢弃它。

使用 Snappy 构建 Hadoop 1.2.1

SSH 到您的新实例并运行以下命令,检查过程中是否有任何错误:

sudo apt-get update
sudo apt-get install pkg-config libsnappy-dev libz-dev libssl-dev gcc make cmake automake autoconf libtool g++ openjdk-7-jdk maven ant

export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64/

wget http://apache.mirrors.lucidnetworks.net/hadoop/common/hadoop-1.2.1/hadoop-1.2.1.tar.gz

tar zxvf hadoop-1.2.1.tar.gz 
pushd hadoop-1.2.1/

# Bundle libsnappy so we don't have to apt-get install it on each machine
cp /usr/lib/libsnappy* lib/native/Linux-amd64-64/

# Test to make certain Snappy is being loaded and is working:
bin/hadoop jar ./hadoop-test-1.2.1.jar testsequencefile -seed 0 -count 1000 -compressType RECORD xxx -codec org.apache.hadoop.io.compress.SnappyCodec -check

# Create a new tarball of Hadoop 1.2.1:
popd
rm hadoop-1.2.1.tar.gz
tar zcvf hadoop-1.2.1.tar.gz hadoop-1.2.1/

# Store the tarball on GCS: 
gsutil cp hadoop-1.2.1.tar.gz gs://<some bucket>/hadoop-1.2.1.tar.gz

使用 Snappy 构建 Hadoop 2.4.1

SSH 到您的新实例并运行以下命令,检查过程中是否有任何错误:

sudo apt-get update
sudo apt-get install pkg-config libsnappy-dev libz-dev libssl-dev gcc make cmake automake autoconf libtool g++ openjdk-7-jdk maven ant

export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64/

# Protobuf 2.5.0 is required and not in Debian-backports
wget http://protobuf.googlecode.com/files/protobuf-2.5.0.tar.gz
tar xvf protobuf-2.5.0.tar.gz
pushd protobuf-2.5.0/ && ./configure && make && sudo make install && popd
sudo ldconfig

wget http://apache.mirrors.lucidnetworks.net/hadoop/common/hadoop-2.4.1/hadoop-2.4.1-src.tar.gz

# Unpack source
tar zxvf hadoop-2.4.1-src.tar.gz
pushd hadoop-2.4.1-src

# Build Hadoop
mvn package -Pdist,native -DskipTests -Dtar
pushd hadoop-dist/target/
pushd hadoop-2.4.1/

# Bundle libsnappy so we don't have to apt-get install it on each machine
cp /usr/lib/libsnappy* lib/native/

# Test that everything is working:
bin/hadoop jar share/hadoop/common/hadoop-common-2.4.1-tests.jar org.apache.hadoop.io.TestSequenceFile -seed 0 -count 1000 -compressType RECORD xxx -codec org.apache.hadoop.io.compress.SnappyCodec -check

popd

# Create a new tarball with libsnappy:
rm hadoop-2.4.1.tar.gz
tar zcf hadoop-2.4.1.tar.gz hadoop-2.4.1/

# Store the new tarball on GCS:
gsutil cp hadoop-2.4.1.tar.gz gs://<some bucket>/hadoop-2.4.1.tar.gz

popd
popd

更新 bdutil_env.sh 或 hadoop2_env.sh

一旦您拥有捆绑了正确本机库的 Hadoop 版本,我们可以通过更新 Hadoop 1 的 bdutil_env.sh 或 Hadoop 2 的 hadoop2_env.sh 将 bdutil 指向新的 Hadoop tarball。在任何一种情况下,打开适当的文件并查找一个块:

# URI of Hadoop tarball to be deployed. Must begin with gs:// or http(s)://
# Use 'gsutil ls gs://hadoop-dist/hadoop-*.tar.gz' to list Google supplied options
HADOOP_TARBALL_URI='gs://hadoop-dist/hadoop-1.2.1-bin.tar.gz'

并将指向的 URI 更改为我们在上面存储 tarball 的 URI:例如,

HADOOP_TARBALL_URI='gs://<some bucket>/hadoop-1.2.1.tar.gz'
于 2014-08-22T02:42:12.100 回答