Category Archives: hadoop

Hadoop CGroup 设置

hadoop 2.8 CGroup的设置,CentOS7 默认的CGroup位置在/sys/fs/cgroup/cpu 等,如果Hadoop不设置自动mount,而是使用默认mount位置的话,会mount到/sys/fs/cgroup/cpu/hadoop-yarn,所以如果要在Hadoop2.8版本请做以下操作:

假设以Hadoop用户启动YARN:
mkdir -p /sys/fs/cgroup/cpu/hadoop-yarn
chown -R hadoop:hadoop /sys/fs/cgroup/cpu/hadoop-yarn

修改如下配置:
yarn.nodemanager.container-executor.class   org.apache.hadoop.yarn.server.nodemanager.LinuxContainerExecutor
yarn.nodemanager.linux-container-executor.resources-handler.class  org.apache.hadoop.yarn.server.nodemanager.util.CgroupsLCEResourcesHandler
yarn.nodemanager.linux-container-executor.group hadoop

然后重启Node Manager就可以了

NameNode元数据恢复流程

最近在为用户解决问题的时候发现的,个别用户删除了namenode standby的所有元数据,为了恢复数据可以做以下操作:
1.停止任务
2.namenode 进入safemode

hdfs dfsadmin -safemode enter

3.nameonde存储元数据

hdfs dfsadmin -saveNamespace

4.备份active元数据

备份 /mnt/disk1/hdfs 下所有数据

5.拷贝active数据到standby
将/mnt/disk1/hdfs 数据拷贝到standby
6.重启standby
7.重启成功后,退出safemode

hdfs dfsadmin -safemode leave

8.恢复任务

Aliyun EMR 值班问题解决汇总–DataNode不断掉线问题

在最近给一个大用户排查问题的过程中,发现了这个问题。

现象

客户的DataNode在40分钟内相继有5台掉线,导致了大量的块under replica,客户认为是Hadoop DataNode问题,向我们反馈。

排查

看了客户的ganglia后发现客户的进程总数在那段时间不断增加,直到超过了ulimit。先查看了NameNode的日志,发现这一时期DataNode心跳都超时了,导致了DataNode被认为dead。再查看了一下DataNode的日志,有大量的无法创建线程日志

2017-12-15 10:58:01,078 WARN org.apache.hadoop.hdfs.server.datanode.DataNode: Unexpected exception in block pool Block pool ****** (Datanode Uuid ******) service to ******
java.lang.OutOfMemoryError: unable to create new native thread
    at java.lang.Thread.start0(Native Method)
    at java.lang.Thread.start(Thread.java:714)
    at org.apache.hadoop.hdfs.server.datanode.DataNode.transferBlock(DataNode.java:1922)
    at org.apache.hadoop.hdfs.server.datanode.DataNode.transferBlocks(DataNode.java:1930)
    at org.apache.hadoop.hdfs.server.datanode.BPOfferService.processCommandFromActive(BPOfferService.java:657)
    at org.apache.hadoop.hdfs.server.datanode.BPOfferService.processCommandFromActor(BPOfferService.java:615)
    at org.apache.hadoop.hdfs.server.datanode.BPServiceActor.processCommand(BPServiceActor.java:858)
    at org.apache.hadoop.hdfs.server.datanode.BPServiceActor.offerService(BPServiceActor.java:672)
    at org.apache.hadoop.hdfs.server.datanode.BPServiceActor.run(BPServiceActor.java:824)
    at java.lang.Thread.run(Thread.java:745)

这个错误一般是由下面两方面造成的
1.ulimit设置不合理,设置 /etc/security/limits.d/20-nproc.conf (CentOs 7), /etc/security/limits.conf
2.异常程序耗尽资源
排查了一下ulimit,是正常的。再查看了一下DataNode的其它日志,并没有发现态度异常,gc情况也是正常的,于是怀疑是异常任务导致的。
于是查看了一下客户的NodeManager日志,发现了异常的任务日志:

2017-12-15 11:00:26,023 WARN org.apache.hadoop.yarn.server.nodemanager.DefaultContainerExecutor: Exception from container-launch with container ID: container_****** and exit code: 52
ExitCodeException exitCode=52:
        at org.apache.hadoop.util.Shell.runCommand(Shell.java:545)
        at org.apache.hadoop.util.Shell.run(Shell.java:456)
        at org.apache.hadoop.util.Shell$ShellCommandExecutor.execute(Shell.java:722)
        at org.apache.hadoop.yarn.server.nodemanager.DefaultContainerExecutor.launchContainer(DefaultContainerExecutor.java:212)
        at org.apache.hadoop.yarn.server.nodemanager.containermanager.launcher.ContainerLaunch.call(ContainerLaunch.java:302)
        at org.apache.hadoop.yarn.server.nodemanager.containermanager.launcher.ContainerLaunch.call(ContainerLaunch.java:82)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)

这是一个spark任务,查看了一下spark任务异常退出值,52代表了OutOfMemory Error,同时看了一下这个程序监控的proc情况,发现了虚拟内存到110G。所以怀疑是这个程序造成的问题。

结论

最后将我们的结论很快反馈给了客户,让用户检查一下程序,客户找到了相关人员,发现是由于使用线程没有释放,不断生成线程导致的,把异常程序停止后集群恢复正常。

解决Jersey 2.x Jersey 1.x冲突问题– UriBuilder问题

最近在使用Java Docker来控制Docker的过程中发现了一个问题,因为Java Docker使用的是Jersey 2.x,maven pom如下:

<dependency>
    <groupId>com.github.docker-java</groupId>
    <artifactId>docker-java</artifactId>
    <version>3.0.13</version>
</dependency>

而集群中Hadoop的依赖都是Jersey 1.x。所以在引用的过程中提示如下错误:

Exception in thread "main" java.lang.AbstractMethodError: javax.ws.rs.core.UriBuilder.uri(Ljava/lang/String;)Ljavax/ws/rs/core/UriBuilder;
        at javax.ws.rs.core.UriBuilder.fromUri(UriBuilder.java:119)
        at org.glassfish.jersey.client.JerseyWebTarget.<init>(JerseyWebTarget.java:71)
        at org.glassfish.jersey.client.JerseyClient.target(JerseyClient.java:290)
        at org.glassfish.jersey.client.JerseyClient.target(JerseyClient.java:76)
        at com.github.dockerjava.jaxrs.JerseyDockerCmdExecFactory.init(JerseyDockerCmdExecFactory.java:237)
        at com.github.dockerjava.core.DockerClientImpl.withDockerCmdExecFactory(DockerClientImpl.java:161)
        at com.github.dockerjava.core.DockerClientBuilder.build(DockerClientBuilder.java:45)

很明显这是Jersey版本mismatch导致的,在解决这一过程中,走了不少弯路,包括采用了maven shade plugin来解决,采用exclude一些jar包来解决等,都没有解决问题。
最后还是从错误出发,这个错误的原因是fromUri这个方法是一个抽象方法,没有实现,也就是只有抽象方法,没有实现类。
再把代码看一下,在Jersery 2.x中的实现为:

public abstract UriBuilder uri(String var1);

它的实现类为org.glassfish.jersey.uri.internal.JerseyUriBuilder,看到这一部分,大概了解到原因是缺少了实现类。于是加入相应的dependency到pom中

        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-server</artifactId>
            <version>2.23.1</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet-core</artifactId>
            <version>2.23.1</version>
        </dependency>

加入后再打包,解决这一问题。

Hadoop Native库安装文档

我们常用的Hadoop native一般是LZO和Snappy,下面说明一下这两个Native库的安装。
一、首先是Snappy
(一)、源码部分
1、下载Snappy的源码,地址是[snappy](http://google.github.io/snappy/),最新版本是1.1.3。
2、下载到服务器上后进行源码编译

./configure -prefix=/usr/local/snappy
make && make install

3、随后所有的库文件生成到/usr/local/snappy目录下

cp -nd /usr/local/snappy/lib/* /lib64
ldconfig

把所有的动态链接库文件拷贝到/lib64下,保留软链接,并使之生效.
(二)Hadoop snappy
Hadoop snappy已经很早前就merge到trunk代码中,所以编译起来比较简单。在hadoop的源码目录,执行

mvn package -Pdist -Pnative -DskipTests -Drequire.snappy

native动态链接库目录在hadoop-dist/target/hadoop-2.4.0/lib/native下面,包含了snappy等等。

二、LZO
(一)、源码部分
1、下载lzo源码

 wget http://www.oberhumer.com/opensource/lzo/download/lzo-2.04.tar.gz

2、解压后编译

./configure --enable-shared --prefix /usr/local/lzo
make && make install

3、随后所有的库文件生成到/usr/local/lzo目录下

cp -nd /usr/local/snappy/lzo/* /lib64
ldconfig

把所有的动态链接库文件拷贝到/lib64下,保留软链接,并使之生效.
(二)、Hadoop LZO部分
1、下载
Hadoop LZO需要单独编译,不与Hadoop源码一起编译,下载地址在[Hadoop lzo](https://github.com/twitter/hadoop-lzo)
2、编译

C_INCLUDE_PATH=/usr/local/lzo/include
LIBRARY_PATH=/usr/local/lzo/lib
mvn clean package -DskipTests

3、在target里面有所需要的jar包,同时native库在target/native/Linux-amd64-64/lib下面

cp -nd target/native/Linux-amd64-64/lib $HADOOP_HOME/lib/native
cp hadoop-lzo-*.jar  $HADOOP_HOME/share/hadoop/httpfs/tomcat/webapps/webhdfs/WEB-INF/lib/
cp hadoop-lzo-*.jar %HADOOP_HOME/share/hadoop/tools/lib/
cp hadoop-lzo-*.jar %HADOOP_HOME/share/hadoop/common/lib/