DMLC和Petuum并行计算框架的搭建与使用

        DMLC的ps-lite以及Petuum的bosen两者都是目前比较流行的Parameter Server计算框架的实现,PS(Parameter Server)计算框架在并行机器学习系统中被广泛使用,之前并行机器学习领域比较流行的是基于MPI的All Reduce计算框架,AR(All Reduce)计算框架下,算法需要严格同步,节点之间需要等待; 而PS不需要严格同步,通过一些方法在一定的Error Bound条件下完成异步训练。
        由于是在实际中用到并行模型进行CTR预估训练,因此选择基于ps-lite的difacto以及基于bosen实现的mlr,前者是并行版本的factorization machine, 这个模型也是我在2014年参加Cretio在kaggle上举办的广告CTR预估竞赛时用过的,取得了17名的成绩,现在也被越来越多的公司在实际中使用;后者是并行版本的logistics regression模型,这个是最普遍被使用的模型。
     1 difacto
     编译dmlc-core,编译之前要将difacto_dmlc/dmlc-core/make/config.mk中关于使用HDFS的选项设置为:USE_HDFS = 1
      编译ps-lite, ps-lite依赖6个第三方库:gflags glog protobuf zmq lz4 cityhash。 由于所使用的机器不能连接外网,因此我先将这六个库先下载到ps-lite文件夹下,并且修改difacto_dmlc/ps-lite/make/deps.mk文件,避免在编译之前将已经下载好的第三方库给删除了。
      编译FM模型,进入文件夹:difacto_dmlc/src/difacto,执行命令:make即可,得到的可执行文件在build文件夹中。
    使用yarn提交job, run_yarn.sh内容为:
    ../../dmlc-core/tracker/dmlc_yarn.py –jobname dmlc_wxs –vcores 1 -mem 512 -n 2 -s 1 build/difacto.dmlc guide/dmlc.fm.conf –log_dir=log –sync_timeout 500 -alsologtostderr -v 10
     其中dmlc.fm.conf中内容为:
     train_data = “hdfs:///dmlc/data/agaricus.txt.train”
     val_data = “hdfs:///dmlc/data/agaricus.txt.test”
     model_out = “hdfs:///dmlc/data/out/”
     max_data_pass = 3
    在执行sh run_yarn.sh之前,记得将训练数据和测试数据放到dmlc.fm.conf中指定的路径下。
     过程中遇到过以下几个问题:

     (1)重新编译dmlc-core会遇到错误提示:
    In file included from src/io.cc:17:0: src/io/hdfs_filesys.h:10:18: 致命错误:hdfs.h:没有那个文件或目录 #include <hdfs.h>
  解决方法:设置HADOOP_HDFS_HOME的环境变量为:export HADOOP_HDFS_HOME=/home/worker/xiaoshu/hadoop/hadoop-2.7.1即可。
    2 mlr:
    第一次使用petuum是在2014年的6月份,当时在360搜索广告算法组实习做广告CTR预估。可以用三种方式使用petuum提供的算法:1,Local: 数据放在local机器上,单机训练;2,HDFS + ssh:将数据放到hdfs上,使用ssh提交job并行训练;3,HDFS + YARN,将数据放到hdfs上,使用yarn提交job并行训练。
     2.1  local模式:
        修改launch.py中train_file, test_file, output_file_prefix(输出路径),执行./launch.py
     2.2 HDFS+ssh模式:
        进入文件夹:petuum/bosen, 将defns.mk.template文件名修改为defns.mk,并将其中关于HDFS选项uncomment:  HAS_HDFS = -DHAS_HADOOP # Uncomment this line to enable hadoop。然后make 即可。
        随后进入:petuum/bosen/app/mlr文件夹,执行make命令编译mlr模型。
        进入petuum/bosen/app/mlr/script文件夹,修改launch.py中的几项配置:
   “train_file”: “hdfs://10.101.2.88:9000/user/worker/petuum/mlr/covtype.scale.train.small”
       “test_file”: “hdfs://10.101.2.88:9000/user/worker/petuum/mlr/covtype.scale.test.small”
        “output_file_prefix”: “hdfs://10.101.2.88:9000/user/worker/petuum/mlr/out”
     2.3 HDFS+YARN模式:
        需要用到launch_on_yarn.py和run_local.py这两个文件,只需要修改 run_local.py中的某些配置就可以:
   “train_file”: “hdfs://10.101.2.88:9000/user/worker/petuum/mlr/covtype.scale.train.small”
    “test_file”: “hdfs://10.101.2.88:9000/user/worker/petuum/mlr/covtype.scale.test.small”
    “output_file_prefix”: “hdfs://10.101.2.88:9000/user/worker/petuum/mlr/out”
        然后执行:./launch_on_yarn.py
       遇到的一些问题:
    (1)copy到新机器上直接运行./launch.py,会出现:
        /home/worker/xiaoshu/petuum_local/bosen/app/mlr/bin/mlr_main: error while loading shared libraries: libboost_thread.so.1.58.0: cannot open shared object file: No such file or directory
        重新make就行了。
    (2)执行./launch_on_local_with_hdfs.py
      重新在boson中make,成功;然后在mL中make,提示/usr/bin/ld: cannot find -lhdfs:
      进入/home/worker/xiaoshu/hadoop/hadoop-2.7.1/lib/native,里面有libhadoop.a libhadoop.so    libhadooputils.a  libhdfs.so libhadooppipes.a  libhadoop.so.1.0.0  libhdfs.a         libhdfs.so.0.0.0。
     执行:sudo cp * /usr/lib, 并执行sudo config生效
    (3)在执行./launch_on_local_with_hdfs.py,提示:Environment variable CLASSPATH not set! getJNIEnv: getGlobalJNIEnv failed F0810 04:20:17.638351 39658 hdfs.hpp:185] Cannot connect to HDFS. Host: 10.101.2.88, port: 9000
      执行:export CLASSPATH=`hadoop classpath –glob`:$CLASSPATH;然后即可成功执行./launch_on_local_with_hdfs.py

Hadoop 集群安装过程

        最近研究并行机器学习并将在工作中用来训练CTR模型,因此申请了3台机器(ReadHeat系统),准备把目前比较流行的Parameter server并行计算框架搭建起来,由于会用到HDFS和YARN,因此先安装Hadoop集群,其中一台机器作为master,其余两台机器作为slave。。
    这里初步记录一下搭建Hadoop环境的过程,也欢迎大家提出意见和问题进行交流。
一,环境设置
    1,安装Java,执行命令:yum install java,然后通过whereis java命令可以看到idk所在的路径。
    对三台机器分别进行环境变量的设置:
    有两种方式:
        对所有用户生效:sudo vi /etc/profile,添加
        export JAVA_HOME=/usr/local/jdk1.7/
        export PATH=$JAVA_HOME/bin:$PATH
        然后:  source /etc/profile
        只对当前用户有效:sudo vi ~/.bashrc,添加:
        export JAVA_HOME=/usr/local/jdk1.7/
        export PATH=$JAVA_HOME/bin:$PATH
        然后source ~/.bashrc
    2,修改hosts文件(在三台机器上都进行下面的操作)
        sudo vi /etc/hosts
        添加(或者修改):
        10.101.2.88 master
        10.101.2.89 slave1
        10.101.2.90 slave2
        IP和hostname之间空格分隔。
      3,修改hostname文件(在三台机器上都进行下面的操作)
        sudo vi /etc/hostname
        在master主机上此文件中内容修改为:master
        在slave1主机上此文件中内容修改为:slave1
         在slave2主机上此文件中内容修改为:slave2
      4,ssh免密码登录:
        说明:master必须能免密码登录slave1, slave2, 并且要能免密码登录本机。
        ssh-keygen
        ssh-copy-id worker@10.101.2.89(slave1)
        ssh-copy-id worker@10.101.2.90(slave2)
        cat ~/.ssh/id_rsa.pub>>~/.ssh/authorized_keys(如果authorized_keys中已经有master的rsa,一定要先删除)
二, 安装Hadoop
    1, 下载hadoop-2.7.2, 解压到master机器的任意一个文件夹中
        cd hadoop-2.7.2
        mkdir hdfs;
        mkdir hdfs/name;
        mkdir hdfs/data;
        mkdir tmp
    2, 修改配置文件:
        2.1 ,进入hadoop-2.7.1/etc/hadoop文件夹,core-site配置文件如下:
    <configuration>
    <property>
         <name>hadoop.tmp.dir</name>
         <value>/home/worker/xiaoshu/hadoop/hadoop-2.7.1/tmp</value>
     </property>
     <property>
         <name>fs.defaultFS</name>
         <value>hdfs://master:9000</value>
     </property>
     <property>
        <name>fs.hdfs.impl</name>
        <value>org.apache.hadoop.hdfs.DistributedFileSystem</value>
        <description>The FileSystem for hdfs: uris.</description>
     </property>
</configuration>
    2.2,hdfs-site.xml配置内容如下:
<configuration>
    <property>
            <name>dfs.namenode.name.dir</name>
            <value>/home/worker/xiaoshu/hadoop/hadoop-2.7.1/hdfs/name</value>
    </property>
    <property>
            <name>dfs.datanode.data.dir</name>
            <value>/home/worker/xiaoshu/hadoop/hadoop-2.7.1/hdfs/data</value>
    </property>
    <property>
            <name>dfs.replication</name>
            <value>2</value>
    </property>
    <property>
        <name>dfs.permissions</name>
        <value>false</value>
    </property>
</configuration>
    2.3,yarn-site.xml配置内容如下:
<configuration>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name>
<value>org.apache.hadoop.mapred.shuffleHandler</value>
</property>
<property>
<name>yarn.nodemanager.vmem-pmem-ratio</name>
<value>100</value>
</property>
<property>
<name>yarn.resourcemanager.address</name>
<value>master:8032</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.address</name>
<value>master:8030</value>
</property>
<property>
        <name>yarn.resourcemanager.resource-tracker.address</name>
                <value>master:8031</value>
                    </property>
<property>
        <name>yarn.resourcemanager.admin.address</name>
                <value>master:8033</value>
                    </property>
<property>
        <name>yarn.resourcemanager.webapp.address</name>
                <value>master:8088</value>
                    </property>
</configuration>
    2.4,mapred-site.xml配置内容如下:
<configuration>
    <property>
    <name>mapreduce.framework.name</name>
    <value>yarn</value>
    </property>
</configuration>
    配置完毕之后,将hadoop-2.7.2文件夹分别copy到slave1和slave2机器上,文件夹所在路径最好路径相同。
    3, 格式化namenode:
    只在master机器上执行:
    (格式化之前:要在hadoop-2.7.1/重新创建hdfs文件夹)
    ssh master ‘/home/worker/xiaoshu/hadoop/hadoop-2.7.1/bin/hdfs namenode -format -clusterId cluster1’
    4,启动namenode,datanode和resourceManager、nodeManager
    4.1 启动namenode:
    在master上执行:
    ssh master ‘/home/worker/xiaoshu/hadoop/hadoop-2.7.1/sbin/hadoop-daemon.sh start namenode’
    4.2 启动slave1上的datanode:
    在master上执行:
    ssh slave1 ‘/home/worker/xiaoshu/hadoop/hadoop-2.7.1/sbin/hadoop-daemon.sh start datanode’
    4.3 启动slave2上的datanode:
    ssh slave2 ‘/home/worker/xiaoshu/hadoop/hadoop-2.7.1/sbin/hadoop-daemon.sh start datanode’
    4.4 启动YARN:
    在master上执行:
    ssh master ‘/home/worker/xiaoshu/hadoop/hadoop-2.7.1/sbin/start-yarn.sh’
    最后,在master上输入jps,看到:
    5863 ResourceManager
    5657 NameNode
    5545 Jps
    在两个slave上输入jps看到:
    37136 NodeManager
    37009 DataNode
    86469 Jps
    出现以上结果表明hadoop集群已经安装成功。
    master节点上有NameNode,slave节点上有DataNode说明HDFS已经正常启动;master节点上有ResourceManager,slave节点上有NodeManager,说明YARN已经正常启动。