Spark上矩阵运算库(一)—— 矩阵相乘

 基于Spark的矩阵相乘

项目中我将先实现基于Spark的矩阵相乘功能。并行化思路将参照MapReduce下的实现方案并做一些优化修改。经过查阅文献,选取比较可行的MapReduce参考方案是HAMA项目。该项目是Apache基金会下的一个顶级开源项目,属于Hadoop生态圈中的一个重要项目。根据HAMA项目主页上的简介,HAMA项目的目的是提供“a general BSP framework on top of Hadoop”。因此HAMA项目的目标现在主要围绕着BSP框架展开。

但是HAMA项目在早期的目标远比此要宏大,其目的有些类似于Spark项目中的MLLib,只是其底层是基于Hadoop生态圈的。下面这张图是截取自2010年发表在IEEE CouldCom会议上的介绍HAMA的文章[1]中的图。在这篇论文中,作者着重介绍了HAMA是如何利用MapReduce框架实现矩阵乘法的。因为MapReduce是第一个在大规模集群上运行的不同于MPI的并行计算框架,对于基于RDD模型的Spark实现具有很强的参考价值,因此我们决定先参考HAMA的实现方式在Spark上试验性的尝试矩阵乘法算法的实现,然后观测一下性能和瓶颈等。

Spark上矩阵运算库(一)—— 矩阵相乘_第1张图片

[1] Seo, S., Yoon, E. J., Kim, J., Jin, S., Kim, J.-S., & Maeng, S. (2010). HAMA: An Efficient Matrix Computation with the MapReduce Framework. In 2010 IEEE Second International Conference on Cloud Computing Technology and Science (CloudCom) (pp.721–726). doi:10.1109/CloudCom.2010.17

HAMA项目在2012年时,真个项目都进行了转型,不再去做图中所示的宏伟目标了,而是专心做BSP框架这一块,我们在如下地址中找到了MapReduce版的矩阵乘法算法:HAMA v0.1 SVN。里面附加的有矩阵乘法示例说明程序:FileMatrixBlockMult.java,目前我们主要基于该程序来完成。

下面简要介绍一下HAMA中矩阵乘法的实现原理。更详细的说明可以参考HAMA的Wiki页面:HAMA Wiki Algorithms

HAMA实现的基于MR的矩阵乘法

矩阵存储

HAMA中的矩阵保存在HBase表中。每个矩阵占用一个表。矩阵是按行存储的,即Row Key是矩阵的行号,而Value部分则是该行的所有元素

基于分块的矩阵乘法框架

HAMA的矩阵乘法需要使用多趟MapReduce Job完成。下面是每趟Job的工作内容:

  1. 从HBase表构造CollectionTable
  2. 从CollectionTable中计算矩阵乘法

构造CollectionTable

CollectionTable是实现矩阵乘法的一个中间数据结构。其记录的是要进行矩阵乘法的两个分块的内容。假设我们想计算分块矩阵C(i,j),那么我们需要进行如下的 C(i,j) = \sigma_{k}{A(i,k)*B(k,j)}。那么CollectionTable是如下组织的:

CollectionTable:
                            matrix A         matrix B
------------------------+-------------------------------             
block(0, 0)-0               block(0, 0)      block(0, 0)
block(0, 0)-1               block(0, 1)      block(1, 0)
block(0, 0)-2               block(0, 2)      block(2, 0)
 ...         N               ...
block(N-1, n-1)-(N^3-1)     block(N-1, N-1)  block(N-1, N-1)

其中block(i,j)-k代表要进行分块矩阵乘的两个block,后面的k代表第K子矩阵乘法。

  • 在Map阶段Map读入矩阵的行向量,发射(blockID, sub-vector)KV对
  • 在Reduce阶段将sub-vector收集成分块矩阵信息,存储HDFS的文件中

进行矩阵乘法

  • 在Map阶段,Map task读入CollectionTable中的一块,并进行MatrixA*MatrixB的操作,发射(blockID,分块矩阵乘结果)
  • 在Reduce结算,收集所有的乘法结果,并进行累加,将最终结果存入HBase表中。

开发环境搭建

所谓工欲善其事必先利其器,基于在Spark的分布式矩阵运算库,需要一个Spark运行环境。在实验室集群节点中用3个节点搭建了一个Saprk 1.0.0的内部测试集群。

每个节点的配置如下:

  • CPU: Intel(R) Quad Core E5620 Xeon(R) , 2.4Ghz/12M Cache (每主板上2片)
    Memory: 24GB (6x4GB) 1333MHz Dual Ranked RDIM for 2 Processors
    Disk: 2TB 3.5-inch 7.2K RPM SATA II Hard Drive(设置为RAID-1)

成功启动后的WEB界面部分截图如下:

Spark上矩阵运算库(一)—— 矩阵相乘_第2张图片

稍微说明一下,这里我修改了Spark的默认web端口,根据Spark的官方推荐,环境底层的HDFS采用了YARN,即在这3个节点上还部署了Hadopp 2.3.0

搭建完Spark系统环境,就是配置sbt等开发环境了,这里稍微吐槽一下这个not so simple的Simple Build Tool,最新的0.13.5版本的sbt下使用run指令启动Spark程序时,会出现Job aborted: ClassNotFound with classloader: sbt.classpath.ClasspathFilter的错误,根据官方JIRA的解决方案https://issues.apache.org/jira/browse/SPARK-1410 ,将sbt版本调低到0.12.4即可,实际测试中,0.13.2版本也可以正常运行不会出现ClassNotFound的Error 。sbt的很多高级特性还不是很熟,基础入门,基本看这篇文章就够了https://github.com/CSUG/real_world_scala/blob/master/02_sbt.markdown

工作小结

作为第一周的内容,搭建完配置完开发环境,按照HAMA 0.1密集矩阵的运算算法Blocking Algorithm Approach ,已经初步完成了CollectionTable的Map部分,预计下面开始会大幅加快进度。

你可能感兴趣的:(Spark上矩阵运算库(一)—— 矩阵相乘)