Spark学习手册(一):HDFS支撑的Spark环境搭建与尝试

  用于大数据分析的,虽然在前面说过数据分析和数据挖掘的核心贵在算法,但是对于折腾帝来说搭建体验一下还是可以的吧~需要注意的是Spark是可以脱离Hadoop在单机上运行,但总觉得单机跑不出Spark的味道,所以顺便把Hadhoop也搞一份玩玩!  
  Spark是可以同Hadoop的HDFS和YARN集合到一起玩的,这里先只涉及用Spark跑HDFS方面的东西。

一、LXC集群环境搭建

  本来想用KVM建立两个DataNode,然后host主机做NameNode的,但根据腿毛兄建议可以用LXC轻量级的虚拟化,想想也是这么回事,这种简单的事搞个虚拟机太浪费了,网上一搜果真还真有。相比较KVM的全虚拟化,LXC基于容器共享一个内核和很多系统组件,当开启多个实例的时候可以大大节约共用的资源,磁盘也类似是host主机文件系统chroot的一个目录,相比完全虚拟化创建一个磁盘镜像完全隔离也显得轻量节省太多了。当然,除了LXC,Docker就是用go语言基于LXC产生的企业级的容器虚拟化方案,但最终偶还是选择了LXC——人嘛,总是要有点追求滴!
  还有,virt-manager+libvirtd是支持链接管理LXC容器的,对于创建应用容器很方便,但是对于系统容器,默认不能创建文件系统;当然你可以用lxc-create的方式进行编译创建,也可以用lxc-create下载官方最新构建好的系统镜像,比如:

1
2
lxc-create -t download -n alpha -- --list
lxc-create -t download -n debian8_node101 -f /etc/lxc/guest.conf --dir=/home/user/Machines/LXC_ROOTFS/debian8_node101 -- -d debian -r jessie -a amd64

  但是这种命令行方式创建的容器十分的“裸”,网络参数啥的需要自己手动设定,没耐心的还真需要点功夫,十分的麻烦。于是个人偷了个懒:

  • 网站 下载好自己想要的发行版的rootfs.tar.xz镜像;
  • 用root权限解压到自己指定的rootfs目录:
    xz rootfs.tar.xz
    sudo tar xvfp rootfs.tar #注意root权限解压
    sudo mv rootfs /home/user/Machines/LXC_ROOTFS/debian8_node101
  • virt-manager创建系统容器的时候,指定到这个目录来;
  • 默认系统root没有密码,但是virt-manager没密码的话还不让你登陆,丫的只能chroot然后改密码:
    chroot /home/user/Machines/LXC_ROOTFS/debian8_node101 /bin/bash
    passwd root

  然后就好了,virt-manager中可以方便的选择网络是NAT模式的,而且公用KVM虚拟机的NAT网段,在WIN7虚拟机里面也可以跟LXC“私通”,很爽吧。
  关于系统镜像,个人反复比较一下,决定用的debian 8(jesse):fedora的镜像200多M,所以系统比较的臃肿;centos7最小,但是很多软件(比如python3)默认不支持,添加源也比较麻烦;就选择了debian stable算比较折中(又一次背叛了自己的信仰……)。
  PS:Debian和Fedora新版系统在virt-manager下终端登陆有问题,放弃了,目前用的Ubuntu 1404(在此请原谅我的堕落)……
  图1:Virt-Manager关机LXC容器,网络默认是配好的(记住,Virtual-manager还支持链接远程的KVM和LXC的,需要远程主机添加Libvirt的kvm/LXC的相关驱动)
virt-manager登陆管理LXC容器

二、Hadoop环境搭建

  Hadoop主要由HDFS和MapReduce组成,前者负责一个分布式的文件系统,后者负责计算中的Map和Reduce过程,如果映射到Hadoop具体的机器节点中,那么就是NameNode-DataNode负责HDFS的控制和承载,ResourceManager和NodeManager负责MapReduce的管理和承载,系统中还可以有WebAppProxy(主要是为了安全考虑),JobHistoryServer等节点。这里主要想要HDFS为Spark提供数据,所以只需要NameNode和DataNode就可以了,Hadoop可以折腾的东西很多,看看项目主页 就知道了,留着以后折腾吧。
  当然,分布式文件系统除了HDFS,还有阿里和腾讯的两个TFS,HDFS大家用的比较多比较主流吧.
  所以在系统中配置了4台主机(不考虑主从备份),安排如下

ubuntu1404_node01 通用计算节点(Spark)
ubuntu1404_node02 NameNode
ubuntu1404_node03 DataNode
ubuntu1404_node04 DataNode

图2:Virt-Manager打开的四个计算容器
四个容器全部开启

2.1 准备工作

准备工作都比较简单,主要是Linux的基础配置,这里就简单罗列下来:

  • 在/etc/hostname中设置对应主机名;
    在主机/etc/network/interfaces设置静态IP,并将主机名和IP映射写入每个机器的/etc/hosts
    还需要注意的是,在每个主机的/etc/hosts中,把127.0.1.1对应本机hostname的那行注释掉,不然NameNode无法自动启动DataNode。
  • ssh免密码互通登陆
    adduser hdfs
    passwd hdfs #hdfs
    ssh-keygen -t dsa -P ‘’ -f ~/.ssh/id_dsa
    cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys
    chmod 0600 ~/.ssh/authorized_keys
    然后把各个主机的公钥都整合到同一个authorized_keys文件,拷贝到各个主机,这样各个主机的hdfs用户就可以互通免密码了。
  • Orace Jave环境安装(Java 1.7,参见这里)
    1
    2
    export JAVA_HOME=/usr/lib/jvm/java-7-oracle
    export PATH=$PATH:$JAVA_HOME/bin

2.2 HDFS配置

  • 下载最新版本
    wget http://mirrors.ustc.edu.cn/apache/hadoop/common/hadoop-2.7.2/hadoop-2.7.2.tar.gz
    将其解压到每个节点的/home/hdfs/hadoop目录下,设置环境变量

    1
    2
    export HADOOP_HOME=/home/hdfs/hadoop
    export HADOOP_PREFIX=/home/hdfs/hadoop
  • 配置 $HADOOP_HOME/etc/hadoop/下的文件(按照xml格式写), 各个主机上配置如下

    • NameNode:
      文件【etc/hadoop/core-site.xml】
      fs.defaultFS hdfs://ubuntu1404_node02:9000
      文件【etc/hadoop/slave】
      ubuntu1404_node03
      ubuntu1404_node04
      文件【etc/hadoop/hdfs-site.xml】
      dfs.namenode.name.dir file:///home/hdfs/hadoopinfra/hdfs/namenode
      dfs.permissions.superusergroup hdfs
    • DataNode:
      文件【etc/hadoop/core-site.xml】
      fs.defaultFS hdfs://ubuntu1404_node02:9000
      文件【etc/hadoop/hdfs-site.xml】
      dfs.datanode.data.dir file:///home/hdfs/hadoopinfra/hdfs/datanode
      dfs.permissions.superusergroup hdfs
  • 相应的,在对应的主机上准备好上面的文件路径
    mkdir -p /home/hdfs/hadoopinfra/hdfs/namenode
    mkdir -p /home/hdfs/hadoopinfra/hdfs/datanode
  • 设置
    在配置文件etc/hadoop/hadoop-env.sh顶部,设置如下环境变量:
    1
    2
    3
    4
    export JAVA_HOME=/usr/lib/jvm/java-7-oracle
    export HADOOP_HOME=/home/hdfs/hadoop
    export HADOOP_CONF_DIR=/home/hdfs/hadoop/etc/hadoop
    export HADOOP_PID_DIR=/home/hdfs/hadoop/pids

2.3 HDFS测试

  hdfs的访问,一种是在命令行的模式下,可以格式化,创建目录等操作,就像传统的linux文件系统的方式。直接文件系统的命令是不行的;还有一种就是API的方式,用于集成到程序当中。
  这里先用命令行的方式来测试验证

  • 从NameNode启动服务器
      启动的方式有手动启动,或者自动启动。推荐设置salve文件,把所有DataNode机器的名字都加进去,这样,只需要一条命令就可以启动所有的DataNode节点。
    1
    2
    $ hadoop/sbin/stop-dfs.sh #停止
    $ hadoop/sbin/start-dfs.sh #启动

图3:NameNode启动DataNode
NameNode启动DataNode
图4:Host主机上开启了大量的Java线程
Host主机上开启了大量的Java线程
图5:浏览器打开ubuntu1404-node02:50070,登陆NameNode进行HDFS浏览和管理
网页HDFS浏览和管理

  • 命令行验证
    内容都是直白,就不解释了:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    hdfs@ubuntu1404-node02:~$ hadoop/bin/hdfs namenode -format
    hdfs@ubuntu1404-node02:~$ hadoop/bin/hdfs dfs -mkdir -p testdir
    hdfs@ubuntu1404-node02:~$ hadoop/bin/hdfs dfs -ls
    Found 1 items
    drwxr-xr-x - hdfs hdfs 0 2016-03-23 01:04 testdir
    hdfs@ubuntu1404-node02:~$ hadoop/bin/hdfs dfs -put data.csv
    hdfs@ubuntu1404-node02:~$ hadoop/bin/hdfs dfs -put data.csv_2 testdir
    hdfs@ubuntu1404-node02:~$ hadoop/bin/hdfs dfs -ls
    Found 2 items
    -rw-r--r-- 3 hdfs hdfs 1648 2016-03-23 01:07 data.csv
    drwxr-xr-x - hdfs hdfs 0 2016-03-23 01:08 testdir
    hdfs@ubuntu1404-node02:~$ hadoop/bin/hdfs dfs -ls testdir
    Found 1 items
    -rw-r--r-- 3 hdfs hdfs 1648 2016-03-23 01:08 testdir/data.csv_2
    hdfs@ubuntu1404-node02:~$ hadoop/bin/hdfs dfs -cat testdir/data.csv_2
    AAPL,28-01-2011, ,344.17,344.4,333.53,336.1,21144800
    AAPL,31-01-2011, ,335.8,340.04,334.3,339.32,13473000
    AAPL,01-02-2011, ,341.3,345.65,340.98,345.03,15236800

三、Spark安装与测试

3.1 Spark安装配置

  安装很简单,就选择和你Hadoop兼容的Pre-build版本就可以了,设置的话,只需要JAVA_HOME配置对了就好了(在/etc/profile添加export JAVA_HOME=/usr/lib/jvm/java-7-oracle)。

3.2 Spark和HDFS联合测试

  Spark的RDD数据流据说是Spark的精华所在,这里只是简单的做个测试吧!

  • HDFS准备测试数据。这里需要注意的是在最后一行,修改了testdir文件的权限,这是因为之前测试的时候,在计算电脑上保存结果出错,说权限不行,于是这里开放其他用户写权限。

    1
    2
    3
    4
    5
    6
    7
    8
    hdfs@ubuntu1404-node02:~$ wget https://www.kernel.org/doc/Documentation/initrd.txt
    hdfs@ubuntu1404-node02:~$ hadoop/sbin/start-dfs.sh
    hdfs@ubuntu1404-node02:~$ hadoop/bin/hdfs dfs -put initrd.txt
    hdfs@ubuntu1404-node02:~$ hadoop/bin/hdfs dfs -ls
    Found 2items
    -rw-r--r-- 3 hdfs hdfs 14398 2016-03-23 08:15 initrd.txt
    drwxr-xr-x - hdfs hdfs 0 2016-03-23 01:08 testdir
    hdfs@ubuntu1404-node02:~$ hadoop/bin/hdfs dfs -chmod ugo+w /user/hdfs/testdir
  • 在计算电脑上开启pyspark(spark-1.6.1-bin-hadoop2.6/bin/pyspark), 然后进行计算操作

    1
    2
    3
    4
    5
    >>> text_file = sc.textFile("hdfs://ubuntu1404-node02:9000/user/hdfs/initrd.txt")
    >>> counts = text_file.flatMap(lambda line: line.split(" ")) \
    ... .map(lambda word: (word, 1)) \
    ... .reduceByKey(lambda a, b: a + b)
    >>> counts.saveAsTextFile("hdfs://ubuntu1404-node02:9000/user/hdfs/testdir/wc_initrd")

图6:pyspark状态图
过程截图

  • 在HDFS NameNode电脑商查看计算的结果
    1
    2
    3
    4
    5
    hdfs@ubuntu1404-node02:~$ hadoop/bin/hdfs dfs -ls /user/hdfs/testdir/wc_initrd/
    Found 3 items
    -rw-r--r-- 3 root hdfs 0 2016-03-23 09:03 /user/hdfs/testdir/wc_initrd/_SUCCESS
    -rw-r--r-- 3 root hdfs 6650 2016-03-23 09:03 /user/hdfs/testdir/wc_initrd/part-00000
    -rw-r--r-- 3 root hdfs 6609 2016-03-23 09:03 /user/hdfs/testdir/wc_initrd/part-00001

当然,这里的测试是比较简单的,从结果得知,还需要手动将节点计算出来的结果进行整合才行。
这里勘误:上面表述是错误的,这是因为reduceByKey启用了多个task导致的,实际上的结果是合并了的.如果想生成一个文件,可以这样:

1
counts.coalesce(1).saveAsTextFile("hdfs://ubuntu1404-node02:9000/user/hdfs/testdir/wc_initrd")

四、结语

  首先让我对Apache有了一个新的认识,Apache可不仅仅生产Httpd和openOffice,看看Apache镜像的庞大规模,可以跟GNU匹配了,你就知道Apache基金会对开源社区的巨大贡献了。
  大数据的工具也不是那么容易的,这里仅仅是一个皮毛的皮毛,不过好在这些东西都很完善和成熟了,我们需要知道的就是怎么配置出我们需要的环境和条件吧。
  为什么这么多企业级的项目都是用的Java?

参考