无论您是使用 Mahout- shell、运行命令行作业,还是将其用作构建应用程序的库,您都需要设置多个环境变量。在 Mac 或许多 Linux 发行版中编辑您的环境。添加以下内容~/.bash_profile
~/.bashrc
export MAHOUT_HOME=/path/to/mahout
export MAHOUT_LOCAL=true # for running standalone on your dev machine,
# unset MAHOUT_LOCAL for running on a cluster
您将需要 ,如果您在 Spark 上运行,您还需要 。$JAVA_HOME
$SPARK_HOME
[hidecontent type="logged" desc="隐藏内容:登录后可查看"]
运行任何使用 Mahout 的应用程序都需要安装二进制或源版本并设置环境。从源代码编译:
mvn -DskipTests clean install
mvn test
mvn eclipse:eclipse
mvn idea:idea
要使用 Maven,请按照以下模板将适当的设置添加到您的 pom .xml或 build.sbt。
要使用 Samsara 环境,您需要同时包含引擎中立的 math-scala 依赖项:
<dependency>
<groupId>org.apache.mahout</groupId>
<artifactId>mahout-math-scala</artifactId>
<version>${mahout.version}</version>
</dependency>
以及后端引擎转换的依赖关系,例如:
<dependency>
<groupId>org.apache.mahout</groupId>
<artifactId>mahout-spark</artifactId>
<version>${mahout.version}</version>
</dependency>
Linux 环境(最好是 Ubuntu 16.04.x) 注意:目前,只有仅限 JVM 的版本才能在 Mac 上运行。 GCC > 4.x NVIDIA 卡(与 OpenCL 驱动程序一起安装以及常用的 GPU 驱动程序)
将 java 1.7+ 安装在易于访问的目录(在本例中为 ~/java/)http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
创建一个目录 ~/apache/。
下载 apache Maven 3.3.9 和 un-tar/gunzip 到 ~/apache/apache-maven-3.3.9/ 。https://maven.apache.org/download.cgi
下载并解压缩 Hadoop 2.4.1 到 ~/apache/hadoop-2.4.1/ 。https://archive.apache.org/dist/hadoop/common/hadoop-2.4.1/
下载并解压缩 spark-1.6.3-bin-hadoop2.4 到 ~/apache/ 。http://spark.apache.org/downloads.html选择版本: Spark-1.6.3 (Nov 07 2016) 选择软件包类型: 预构建于 Hadoop 2.4
安装 ViennaCL 1.7.0+ 如果运行 Ubuntu 16.04+
sudo apt-get install libviennacl-dev
否则,如果您的发行版的软件包管理器没有 viennniacl-dev 软件包 >1.7.0,请将其直接克隆到由 Mahout 编译时将包含的目录中:
mkdir ~/tmp
cd ~/tmp && git clone https://github.com/viennacl/viennacl-dev.git
cp -r viennacl/ /usr/local/
cp -r CL/ /usr/local/
确保 OpenCL 1.2+ 驱动程序全部安装(与大多数消费级 NVIDIA 驱动程序一起打包)。不确定高端卡。
将Library存储库克隆到 .~/apache
git clone https://github.com/apache/mahout.git
在为 Spark 后端构建 mahout 时,我们需要设置四个系统环境变量:
export MAHOUT_HOME=/home/<user>/apache/mahout
export HADOOP_HOME=/home/<user>/apache/hadoop-2.4.1
export SPARK_HOME=/home/<user>/apache/spark-1.6.3-bin-hadoop2.4
export JAVA_HOME=/home/<user>/java/jdk-1.8.121
Spark上的Mahout经常使用另一个env变量,即Spark集群主节点(通常是托管会话用户的节点)的IP。
使用四个本地内核(Spark master不需要运行)
export MASTER=local[4]
使用所有可用的本地内核(同样,Spark master不需要运行)
export MASTER=local[*]
要指向正在运行 Spark 的群集,请执行以下操作:
export MASTER=spark://master.ip.address:7077
然后,我们将这些添加到路径中:
PATH=$PATH$:MAHOUT_HOME/bin:$HADOOP_HOME/bin:$SPARK_HOME/bin:$JAVA_HOME/bin
这些被附加到用户的 ~/.bashrc 文件中。
目前,Mahout有三个版本。从 $MAHOUT_HOME 目录中,我们可以发出命令以使用 mvn 配置文件构建每个命令。
仅限 JVM:
mvn clean install -DskipTests
具有本机 OpenMP 级别 2 和级别 3 矩阵/矢量乘法的 JVM
mvn clean install -Pviennacl-omp -Phadoop2 -DskipTests
具有本机OpenMP和OpenCL的JVM,用于2级和3级矩阵/矢量乘法。(GPU 错误回退到 OpenMP,目前仅支持单个 GPU/节点)。
mvn clean install -Pviennacl -Phadoop2 -DskipTests
Mahout 提供了 spark-shell 的扩展,有利于了解语言、测试分区负载、原型算法等。
要使用两个线程在本地模式下启动 shell,只需执行以下操作:
$ MASTER=local[2] mahout spark-shell
在非常冗长的启动之后,将出现一个Mahout欢迎屏幕:
Loading /home/andy/sandbox/apache-mahout-distribution-0.13.0/bin/load-shell.scala...
import org.apache.mahout.math._
import org.apache.mahout.math.scalabindings._
import org.apache.mahout.math.drm._
import org.apache.mahout.math.scalabindings.RLikeOps._
import org.apache.mahout.math.drm.RLikeDrmOps._
import org.apache.mahout.sparkbindings._
sdc: org.apache.mahout.sparkbindings.SparkDistributedContext = org.apache.mahout.sparkbindings.SparkDistributedContext@3ca1f0a4
_ _
_ __ ___ __ _| |__ ___ _ _| |_
'_ ` _ \ / _` | '_ \ / _ \| | | | __|
| | | | (_| | | | | (_) | |_| | |_
_| |_| |_|\__,_|_| |_|\___/ \__,_|\__| version 0.13.0
That file does not exist
scala>
在 scala> 提示符下,输入:
scala> :load /home/<andy>/apache/mahout/examples
/bin/SparseSparseDrmTimer.mscala
这将加载矩阵乘法计时器函数定义。运行矩阵计时器:
scala> timeSparseDRMMMul(1000,1000,1000,1,.02,1234L)
{...} res3: Long = 16321
请注意,14.1 版本缺少一个必需的类,这将在 14.2 中修复。我们可以看到仅JVM的版本很慢,因此我们支持GPU和本机多线程的动机。
为了理解在计时器引擎盖下执行的过程,我们可以检查.mscala(mahout scala)代码,它既是功能齐全的scala,也是张量代数的Mahout R-Like DSL:
def timeSparseDRMMMul(m: Int, n: Int, s: Int, para: Int, pctDense: Double = .20, seed: Long = 1234L): Long = {
val drmA = drmParallelizeEmpty(m , s, para).mapBlock(){
case (keys,block:Matrix) =>
val R = scala.util.Random
R.setSeed(seed)
val blockB = new SparseRowMatrix(block.nrow, block.ncol)
blockB := {x => if (R.nextDouble < pctDense) R.nextDouble else x }
(keys -> blockB)
}
val drmB = drmParallelizeEmpty(s , n, para).mapBlock(){
case (keys,block:Matrix) =>
val R = scala.util.Random
R.setSeed(seed + 1)
val blockB = new SparseRowMatrix(block.nrow, block.ncol)
blockB := {x => if (R.nextDouble < pctDense) R.nextDouble else x }
(keys -> blockB)
}
var time = System.currentTimeMillis()
val drmC = drmA %*% drmB
// trigger computation
drmC.numRows()
time = System.currentTimeMillis() - time
time
}
[/hidecontent]