All posts by jiangyu

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就可以了

解决Docker容器中 mpi 日志丢失问题

最近使用Docker跑Tensorflow的时候,经常发现通过docker java api获取不到Tensorflow的日志获取日志的代码如下:

  private class DockerLogReader extends LogContainerResultCallback {
    @Override
    public void onStart(Closeable stream) {
      System.out.println("start");
    }

    @Override
    public void onNext(Frame item) {
      System.out.print(new String(item.getPayload()));
    }

    @Override
    public void onError(Throwable throwable) {
      System.out.print(throwable.getMessage());
    }

    @Override
    public void onComplete() {
      super.onComplete();
      System.out.println("Docker exit.");
    }
  }

正常情况下,代码会走到onNext中,从而收集到Docker中正在运行的TensorFlow的日志,由于使用的是Horovod,所以底层使用的是MPI去运行程序。然后在运行过程中,只打印了Python程序中的日志,而TensorFlow中的日志全部丢失了。
为了解决这一问题,单独起了两个Docker container,然后手动启动mpi,mpi的命令为:

mpirun  --allow-run-as-root -np 2 ***** >stdout 2>stderr

将命令重定向后发现stdout,stderr就是 docker java获取的日志,但是console能够打出日志,查询了mpi的文档,发现了一个选项-tag-output,同时将stderr重定向的stdout中

mpirun -tag-output --allow-run-as-root -np 2 ***** 2>&1

经过修改后,日志全部打印出来。成功解决这一问题。

pyspark with jupyter

首先配置jupyter config文件。

jupyter-notebook --generate-config

修改jupyter config文件

c.NotebookApp.port = 18888
c.NotebookApp.ip = '0.0.0.0'
c.NotebookApp.allow_root = True

当然要配置好spark,emr环境spark已经完全配置正确。配置pyspark参数

export PYSPARK_DRIVER_PYTHON=jupyter
export PYSPARK_DRIVER_PYTHON_OPTS='notebook'

启动pyspark即可。

pyspark --master yarn

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.恢复任务

gperftool安装及使用说明

安装方法
1.从github上下载代码到服务器上
2../autogen.sh
需要提前安装autoconf,libtool,gcc-c++,libunwind。先安装libunwind,下载源码包:

./configure && make && make install
yum install -y autoconf libtool gcc-c++

使用方法

export LD_PRELOAD=/usr/lib/libtcmalloc.so:/usr/lib/libprofiler.so
CPUPROFILE=/tmp/cpu java ****
HEAPPROFILE=/tmp/heap java ****

查看结果:
pprof --text /bin/java /tmp/cpu
pprof --text /bin/java /tmp/heap

解决Mac Os X ssh LC_CTYPE警告问题

自从Mac升级以后,登录到linux服务器上,总会报如下的错误:

warning: setlocale: LC_CTYPE: cannot change locale (UTF-8): No such file or directory

并且中文显示全是乱码,google了一下发现是由于mac ssh过去的时候把LANG环境变量也传递了过去,与服务器的不match导致的。解决方法也很简单,去掉LANG环境变量传输:

sudo vi /etc/ssh/ssh_config
注释掉   SendEnv LANG LC_*

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。所以怀疑是这个程序造成的问题。

结论

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

创建gpu挂载/dev/nvidia开机启动进程

由于GPU机器重启后gpu的device并不会主动挂载,所以需要开机后执行一个脚本,开机自动挂载,以便于后面Docker进行挂载。执行的脚本gpu-service如下:

#!/bin/bash

/sbin/modprobe nvidia

if [ "$?" -eq 0 ]; then
  # Count the number of NVIDIA controllers found.
  NVDEVS=`lspci | grep -i NVIDIA`
  N3D=`echo "$NVDEVS" | grep "3D controller" | wc -l`
  NVGA=`echo "$NVDEVS" | grep "VGA compatible controller" | wc -l`

  N=`expr $N3D + $NVGA - 1`
  for i in `seq 0 $N`; do
    mknod -m 666 /dev/nvidia$i c 195 $i
  done

  mknod -m 666 /dev/nvidiactl c 195 255

else
  exit 1
fi

/sbin/modprobe nvidia-uvm

if [ "$?" -eq 0 ]; then
  # Find out the major device number used by the nvidia-uvm driver
  D=`grep nvidia-uvm /proc/devices | awk '{print $1}'`

  mknod -m 666 /dev/nvidia-uvm c $D 0
else
  exit 1
fi

需要加入新的system服务,方法为

touch /etc/systemd/system/gpu.service
chmod 664 /etc/systemd/system/gpu.service

修改gpu.service文件为

[Unit]
Description=auto run gpu construct
[Service]
Type=simple
ExecStart=/usr/sbin/gpu-service
[Install]
WantedBy=multi-user.target

将gpu-service脚本拷贝到/usr/sbin/gpu-service

mv gpu-service usr/sbin/
chmod 554 /usr/sbin/gpu-service

通过systemctl命令,将gpu-service作为开机自启动命令

systemctl daemon-reload
systemctl enable gpu.service

TensorFlow源码编译问题汇总

根据官网指南,按照官网说明,首先要安装protobuf 3.0+的版本。在configure过程中,按照说明,一步步点击需要的部分。然后通过bazel编译,当然bazel版本要使用0.6以下的版本。
通过bazel编译

bazel build --config=opt --config=cuda //tensorflow/tools/pip_package:build_pip_package

然后报错

ERROR: /mnt/disk1/taokelu/tensorflow-1.3.0/tensorflow/tools/pip_package/BUILD:134:1: error loading package 'tensorflow/contrib/session_bundle': Encountered error while reading extension file 'protobuf.bzl': no such package '@protobuf//': java.io.IOException: Error downloading [https://github.com/google/protobuf/archive/0b059a3d8a8f8aa40dde7bea55edca4ec5dfea66.tar.gz, http://mirror.bazel.build/github.com/google/protobuf/archive/0b059a3d8a8f8aa40dde7bea55edca4ec5dfea66.tar.gz] to /root/.cache/bazel/_bazel_root/d3cc9e5e7119c18dd166b716d8b55c4b/external/protobuf/0b059a3d8a8f8aa40dde7bea55edca4ec5dfea66.tar.gz: Checksum was e5fdeee6b28cf6c38d61243adff06628baa434a22b5ebb7432d2a7fbabbdb13d but wanted 6d43b9d223ce09e5d4ce8b0060cb8a7513577a35a64c7e3dad10f0703bf3ad93 and referenced by '//tensorflow/tools/pip_package:build_pip_package'.

这个错误是sha错误,解决方法是去掉sha比较。

sed -i '\@https://github.com/google/protobuf/archive/0b059a3d8a8f8aa40dde7bea55edca4ec5dfea66.tar.gz@d' tensorflow/workspace.bzl