项目从开始准备工作到如今已经接近一个月的时间,这次的中期检查报告回顾一下这一个月内的工作进展,并对未来的进一步工作做一个规划
Spark用scala语言进行开发,而Spark本身目前推荐使用YARN作为底层环境,所以我们从最开始三个节点的Spark 1.0.0 on Hadoop1 迁移到现在18个节点的Spark 1.0.1 on YARN,程序的开发IDE一直都是Intellij IDEA Community 13.1,运行环境见下
一次开发工作流程如下:在IDE中修改编写程序,保存之后,进入shell,执行sbt assembly命令,对于assembly的大体积jar包,用官方所提倡的spark-submit命令提交,提交运行命令如下:
在Spark官方提供的MLlib中,实现了Distributed matrix的理念,包括IndexedRow,IndexedRowMatrix这些,我们参照其实现了IndexRow和IndexMatrix,由于原先MLlib中的类中有些函数是private的,而且由于RDD初始化的问题(见第四周报告),为了使用这些函数,我们复制了IndexedRow、IndexedMatrix等类的部分源码。
由于Breeze会调用netlib-java,并借助netlib-java调用底层C和Fortran的库,以极大地提高运算速度,所以我们实现时也借助了Breeze。
目前我们已经全部完成了如下的矩阵操作API:
这里重点讲一下两个矩阵相乘的API,我们的参考实现HAMA 0.1的矩阵乘法算法(见第一周报告),该原型的数据读取都是通过HBase,目前我们这里则是通过spark自带的textFile函数读取,日后也准备考虑与HBase的衔接问题。
主要的测试对象就是矩阵乘法部分,我自己写了一个scala程序直接调用Breeze对两个矩阵进行相乘,两个输入矩阵文本文件均是860MB,每个矩阵的单个元素是0到5的float型,维度是1万-1万,从文本载入到内存的单机版本程序很慢,完全载入内存后,最初我们无法成功调用底层的BLAS,Breeze用预备的Java版本实现了两个矩阵的相乘,需要大约26min,而经过我们不懈努力(此处过程比较坎坷,可以单独写一篇博客出来),终于成功调用到了底层BLAS,对比之下需要4min左右时间,性能差距还是很明显的。
虽然解决了Breze对底层库的调用问题,但是我们按照相同的办法(简单来说就是用本地编译的netlib-java的jar包替代从maven下载的jar包),去尝试解决Spark程序调用底层库的问题,却并没有得到解决,这个问题已经困扰我们相当长的时间,已经向导师求助了。下面是我们Spark程序执行的stage监控图
其中用时最多的就是stage6,也就是被切分后的矩阵相乘的时间,需要大约9min,如果能打通调用底层库,其时间能大量减少,极大地提升性能。由于我们读取和存储时候是并行的,所以比单机读取存储快很多,上面提到的Breeze程序需要接近3个小时的本地存储时间,而我们只需要1分钟左右。