1. 介绍

在之前我写的Ignite In-Memory Hadoop Accelerator安装使用这篇文章中我已经介绍了如何安装Ignite In-Memory Hadoop Accelerator。

为了达到添加一个内存缓存层来加速MR JOB的目的,我们使用的是Ignite In-Memory Hadoop Accelerator(下文我就简称IHA了)。这里注意区别下ignite的data fabric组件。

2. 注意事项

2.1 集成yarn的问题

使用IHA也就意味着由ignite来管理MR任务的调度执行了。因为ignite自己实现了native的ignite MR框架。所以如果你的hadoop配置了yarn来执行MR job记得要关闭相关选项。

在yarn-site.xml中的mapreduce.framework.name属性也要设置成ignite。当然这么做,也就是不使用yarn来管理MR JOB了。

    <property>
        <name>mapreduce.framework.name</name>
        <value>ignite</value>
    </property>

不使用ignite的情况下是YARN来管理一个MR application。现在使用ignite的情况下,如果还要使用YARN的话,就是用YARN来管理ignite application。所以这里注意下互相之间的关系:

如果要集成YARN可以自己看下官方文档YARN Deployment或者等我后续中文教程。

2.2 参数配置

由于我后续实验采用的数据块较大,而且单个文件本身也比较大。所以为了能正常跑起来,记得需要修改下ignite的配置。

修改ignite.sh这个脚本:

if [ -z "$JVM_OPTS" ] ; then
    if [[ `"$JAVA" -version 2>&1 | egrep "1\.[7]\."` ]]; then
        JVM_OPTS="-Xms1g -Xmx1g -server -XX:+AggressiveOpts -XX:MaxPermSize=256m"
    else
        # 此处修改下,我用的是JDK 1.8的,所以修改这里。如果是1.7的修改上面的。这里看到我分配了比较大的JVM heap size和MetaSpace
        JVM_OPTS="-Xms10g -Xmx30g -server -XX:+AggressiveOpts -XX:MaxMetaspaceSize=20g"
    fi
fi

由于后续实验都是对比实验。就是一组实验采用IHA,另外一组实验不采用IHA。然后查看实验结果来对比。两者的hadoop配置是一样的。也就是说我们的实验是不关心其他不变量的。所以这里就不贴自己的hadoop配置了。但是建议大家块大一点、分片数少一点,这样对比效果会明显点。

3. 实验一:10G文件读取(IO密集型JOB)

在HDFS上准备好10G的单个大文件。我们这个实验采用20个split、每个512MB大小。

记得不使用ignite的时候,做下系统缓存清空操作,避免系统缓存影响:

sudo sh -c 'free && sync && echo 3 > /proc/sys/vm/drop_caches && free'

3.1 running without IHA

实验结果:

观察下实验结果我们可以获取以下信息:

  1. 2.4MB的中间数据写入了OS文件系统
  2. HDFS上面读取了10G的数据
  3. 耗时45.79秒

3.2 running with IHA

实验开始前,同样做下系统缓存清空操作,避免系统缓存影响:

sudo sh -c 'free && sync && echo 3 > /proc/sys/vm/drop_caches && free'

当然我们会发现,即使做了系统缓存,由于使用了基于内存的IGFS,大量数据应该是pin在内存了。

执行结果:

这里可以发现采用IGFS之后,打印信息都变化很大。没有了一些统计信息。

3.3 实验结果处理

首先我们要了解下time来统计时间的real、user和sys的含义:

  1. Real 是时钟时间-程序从开始至结束的总时间。他包括期间其他进程所占用的时间片和进程被阻塞的时间(如IO等待的时间)
  2. User 被测试程序在用户模式下所花的CPU时间。他是进程执行的正真的CPU时间。其他进程调度的时间片以及阻塞(如IO)的时间不包含在内。
  3. Sys 是进程在内核中所花费的CPU时间。他表示进程在内核调用中所花的CPU时间,而程序的库调用仍然运行在用户空间下。
  4. User+Sys表示程序所执行的CPU时间(不包括IO以及其他进程的CPU时间).

我们定义一个概念
“耗时比”=(不使用ignite所花的时间 )/( 使用ignite所花的时间)*100%

计算以上实验的耗时比我们可以得到如下表格:
第一次实验的截图就在上面,大家可以自己算下。

时间分类 耗时比
Real(总时间) 254%
User+Sys(CPU时间) 87.06%
Real-(User+Sys) 583%

3.4 重复实验

3.4.1 第二次实验

  1. without ignite

  2. with ignite

时间分类 耗时比
Real(总时间) 257%
User+Sys(CPU时间) 125%
Real-(User+Sys) 383%

3.4.2 第三次实验

  1. without ignite

  2. with ignite

时间分类 耗时比
Real(总时间) 290%
User+Sys(CPU时间) 137%
Real-(User+Sys) 437%

3.5 系统缓存影响

前面是实验,在每次开始前都清空了系统缓存。接下来我们再重复两遍上面的实验,但是不清空系统缓存。

先执行一遍程序,使得数据存到系统缓存中。

3.5.1 第一次实验

  1. without ignite

  1. with ignite

时间分类 耗时比
Real(总时间) 282%
User+Sys(CPU时间) 141%
Real-(User+Sys) 434%

3.5.2 第二次实验

  1. without ignite

  1. with ignite

时间分类 耗时比
Real(总时间) 272.5%
User+Sys(CPU时间) 131%
Real-(User+Sys) 417%

3.6 实验总结

  1. 清空系统缓存确实会对IO造成影响。从实验结果可以看到从HDFS读取的时候,在使用系统缓存的情况下IO时间大概减少了5秒的样子。但是对从IGFS读取的影响不大。说明本来就从内存读取了。
  2. 采用的是IO密集型的JOB,Real-(User+Sys)的耗时可以反映在IO上的耗时。按照耗时比来看提升的性能,基本在5倍左右。
  3. 根据Real-(User+Sys)的耗时作为IO耗时来看。使用IGFS的时候,读取10G文件,平均耗时7秒左右,读取速率1.42GB/s;如果使用HDFS,在没有系统缓存的情况下,读取速度为270MB/s。这样的差距比较符合内存和磁盘的性能差距。

4. 关于首次读取IGFS慢的问题

这里需要补充一点。当启动IGFS之后,首次从IGFS读取的时候,耗时会比较久。比如实验一的读取10G文件操作,第一次的耗时:

可见大量时间花在IO,而且比正常从HDFS读取还慢很多。这个需要引起注意。不过你内存大一点,缓存较多的数据,肯定是利大于弊的。一旦数据缓存到IGFS,清空系统缓存是无法清除IGFS里面的数据的。

5. 实验二: