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

Hadoop 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_*

创建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

TensorFlow on Docker构建问题汇总

1.Docker仓库缓存位置

默认Docker会存储在/var/lib/docker/,如果系统盘过小,很容易导致磁盘写满。为了改变存储位置,需要修改启动脚本。对于CentOS来说,修改/usr/lib/systemd/system/docker.service加入如下一行,-g

ExecStart=/usr/bin/dockerd-current 
          -g /mnt/disk1/docker_home 

2.打开管理端口

由于安全原因,默认现在是不打开2375端口,为了使用Docker-java等管理工具,需要打开端口,方法同上,修改/usr/lib/systemd/system/docker.service

    --userland-proxy-path=/usr/libexec/docker/docker-proxy-current 
    -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock   

3.环境变量等问题

通过Commit等方式或者传入的环境变量或多或少有问题,需要通过Dockerfile写法,进行设置。比如TensorFlow,需要配置HADOOP_HDFS_HOME,LD_LIBRARY_PATH以及CLASSPATH等来读取HADOOP数据,但是通过-e传递参数方式,并不起作用。

4.Nvidia驱动安装问题

如果希望在Docker内部能够使用GPU,则应该在宿主机(host)以及Docker Container内部都安装相同的cuda版本以及cudnn版本。同时,在启动container的时候需要将GPU设备映射到container,需要映射的设备有

--device /dev/nvidia0:/dev/nvidia0 --device /dev/nvidiactl:/dev/nvidiactl --device /dev/nvidia-uvm:/dev/nvidia-uvm

但是,有个问题,如果重启的时候,这三个设备默认没有加载,通过以下脚本启动加载。

#!/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

5.整体的Dockerfile

FROM centos:7.3.1611

RUN     yum update -y
RUN     yum install -y java-1.8.0-openjdk-devel.x86_64
RUN     yum install -y vim
RUN     yum install -y wget
RUN     yum -y install epel-release
RUN     yum install -y python-pip
RUN     yum -y install python-devel
RUN     pip install --upgrade pip

ADD ./hadoop-2.7.2-1.2.8.tar.gz /usr/local

RUN     mkdir /install

COPY ./cuda-repo-rhel7-8-0-local-ga2-8.0.61-1.x86_64-rpm /install
COPY ./cuda-repo-rhel7-8-0-local-cublas-performance-update-8.0.61-1.x86_64-rpm /install

RUN     rpm -i /install/cuda-repo-rhel7-8-0-local-ga2-8.0.61-1.x86_64-rpm
RUN     yum -y install cuda
RUN     rpm -i /install/cuda-repo-rhel7-8-0-local-cublas-performance-update-8.0.61-1.x86_64-rpm
RUN     yum -y install cuda-cublas-8-0

ADD ./cudnn-8.0-linux-x64-v6.0.tar.gz /install

RUN     cp /install/cuda/include/cudnn.h /usr/local/cuda/include/
RUN     cp -d /install/cuda/lib64/libcudnn* /usr/local/cuda/lib64/
RUN     chmod a+r /usr/local/cuda/include/cudnn.h /usr/local/cuda/lib64/libcudnn*


ENV JAVA_HOME /etc/alternatives/java_sdk_1.8.0
ENV HADOOP_HOME /usr/local/hadoop-2.7.2-1.2.8
ENV HADOOP_HDFS_HOME $HADOOP_HOME
ENV LD_LIBRARY_PATH /usr/local/cuda/lib64:${JAVA_HOME}/jre/lib/amd64/server:$LD_LIBRARY_PATH
ENV PATH $JAVA_HOME/bin:$HADOOP_HOME/bin:$PATH

Linux 各种包download only

一、pip download

pip donwload package

二、yum downloadonly

首先安装包downloadonly包

yum install yum-plugin-downloadonly

使用方法:

yum install --downloadonly --downloaddir=<directory> <package>

解决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>

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

Install Nvidia CUDA on Aliyun ECS

1.首先确认硬件存在Nvidia GPU,并且操作系统版本兼容,我们选取的是CentOS 7版本,所以没有问题

lspci | grep -i nvidia

2.安装cuda toolkit
从官网下载,http://developer.nvidia.com/cuda-downloads,下载后选择对应的平台,我选取的是centos7,对应了cuda toolkit为9。

rpm -i cuda-repo-rhel7-9-0-local-9.0.176-1.x86_64.rpm
yum install cuda

这样安装好了cuda。

3.加入PATH等

export PATH=/usr/local/cuda/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH

4.reboot服务器,然后验证一下

[root@emr-worker-1 release]# nvidia-smi -L
GPU 0: Tesla M40 (UUID: GPU-5ac5582f-b7cb-225a-b698-2c1da3cb1646)

至此,安装完成。