RDDstrack lineage information that can be used to efficiently recomputelost data
One waySpark avoids using it is through locality-aware scheduling for RAMand disk Pre-partition the links RDD so that links for URLs withthe same hash code are on the same node
定位至Spark主目录,如/spark-0.9.0-incubating-bin-hadoop1, 使用GitBash打开
设置Hadoop版本:set SPARK_HADOOP_VERSION=1.2.1
SBT 构建
$ SPARK_HADOOP_VERSION=1.2.1 sbt/sbt clean assembly
$ SPARK_HADOOP_VERSION=2.2.0 SPARK_YARN=true sbt/sbt assembly(集成YARN)
Maven 构建
$
export MAVEN_OPTS="-Xmx2g -XX:MaxPermSize=512M -XX:ReservedCodeCacheSize=512m"
$ mvn -Dhadoop.version=1.2.1 -DskipTests -Pspark-ganglia-lgpl clean package (集成ganglia)
$ mvn -Pyarn -Dhadoop.version=2.2.0 -Dyarn.version=2.2.0 -DskipTests clean package(集成YARN)
new SparkContext(master, appName, [sparkHome], [jars])
- master:必填项,用于指定Spark或者Mesos集群地址,或者local本地模式。地址格式如下:
-
- local: 本地运行一个worker进程
- local[N]:本地运行N歌worker进程
- spark://host:port
连接 Sparkstandalone cluster 集群,默认端口为7077 - mesos://host:port 连接
Mesos 集群 - 连接YARN集群参考:
runningon YARN
- appName:必填项,应用程序全局名称
- sparkHome:可选项,部署Spark应用程序时使用,用于指定集群所有结点中Spark的安装路径,必须一致
- jars:可选项,部署Spark应用程序时使用,指定需要部署至集群的本地代码和相关依赖包,以逗号分隔,如:ADD_JARS=a.jar,b.jar./bin/spark-shell
resilient distributeddataset
2)Resilient DistributedDatasets (RDDs)
2.1)ParallelizedCollections
scala> val data = Array(1, 2, 3, 4, 5)
scala> val distData = sc.parallelize(data)
scala> val distData = sc.parallelize(data,10)
2.2)HadoopDatasets
scala>
val textFile = sc.textFile("README.md")
textFile.count()
textFile同样提供了一个参数控制slice个数,默认情况下Spark为每个file block(64MB by default inHDFS)分配一个slice,当然也可以手动调整,但注意保证slices 〉= blocks
bin/run-example org.apache.spark.examples.SparkPi local
bin/run-example org.apache.spark.examples.SparkTC local[2]
2.3)RDDOperations
2.3.1)Transformations
Transformation | Meaning |
---|---|
map(func) | 返回一个新的分布式数据集,由每个原元素经过func函数转换后组成 |
filter(func) | 返回一个新的数据集,由经过func函数后返回值为true的原元素组成 |
flatMap(func) | 类似于map,但是每一个输入元素,会被映射为0到多个输出元素(因此,func函数的返回值是一个Seq,而不是单一元素) |
mapPartitions(func) | 类似于map,但独立地在RDD的每一个分块上运行,因此在类型为T的RDD上运行时,func的函数类型必须是Iterator[T]=> Iterator[U] |
mapPartitionsWithIndex(func) | 类似于mapPartitions,但func带有一个整数参数表示分块的索引值。因此在类型为T的RDD上运行时,func的函数类型必须是(Int,Iterator[T]) => Iterator[U] |
sample(withReplacement,fraction, | 根据给定的随机种子seed,随机抽样出数量为fraction的数据 |
union(otherDataset) | 返回一个新的数据集,由原数据集和参数联合而成 |
distinct([numTasks])) | 返回一个包含源数据集中所有不重复元素的新数据集 |
groupByKey([numTasks]) | 在一个由(K,V)对组成的数据集上调用,返回一个(K,Seq[V])对的数据集。注意:默认情况下,使用8个并行任务进行分组,你可以传入numTask可选参数,根据数据量设置不同数目的Task |
reduceByKey(func, [numTasks]) | 在一个(K,V)对的数据集上使用,返回一个(K,V)对的数据集,key相同的值,都被使用指定的reduce函数聚合到一起。和groupbykey类似,任务的个数是可以通过第二个可选参数来配置的。 |
sortByKey([ascending], [numTasks]) | 在类型为( K, V)的数据集上调用,返回以K为键进行排序的(K,V)对数据集。升序或者降序由boolean型的ascendingOrder参数决定 |
join(otherDataset, [numTasks]) | 在类型为(K,V)和(K,W)类型的数据集上调用,返回一个(K,(V,W))对,每个key中的所有元素都在一起的数据集 |
cogroup(otherDataset, [numTasks]) | 在类型为(K,V)和(K,W)类型的数据集上调用,返回一个数据集,组成元素为(K, Seq[V], Seq[W])Tuples。这个操作在其它框架,称为 groupWith. |
cartesian(otherDataset) | 笛卡尔积。但在数据集T和U上调用时,返回一个(T,U)对的数据集,所有元素交互进行笛卡尔积。 |
2.3.2)Actions
Action | Meaning |
---|---|
reduce(func) | 通过函数func聚集数据集中的所有元素。Func函数接受2个参数,返回一个值。这个函数必须是关联性的,确保可以被正确的并发执行 |
collect() | 在Driver的程序中,以数组的形式,返回数据集的所有元素。这通常会在使用filter或者其它操作后,返回一个足够小的数据子集再使用,直接将整个RDD集Collect返回,很可能会让Driver程序OOM |
count() | 返回数据集的元素个数 |
first() | 返回数据集的第一个元素(类似于take(1)) |
take(n) | 返回一个数组,由数据集的前n个元素组成。注意,这个操作目前并非在多个节点上,并行执行,而是Driver程序所在机器,单机计算所有的元素 |
takeSample(withReplacement,num, | 返回一个数组,在数据集中随机采样num个元素组成,可以选择是否用随机数替换不足的部分,Seed用于指定的随机数生成器种子 |
saveAsTextFile(path) | 将数据集的元素,以textfile的形式,保存到本地文件系统,hdfs或者任何其它hadoop支持的文件系统。Spark将会调用每个元素的toString方法,并将它转换为文件中的一行文本 |
saveAsSequenceFile(path) | 将数据集的元素,以sequencefile的格式,保存到指定的目录下,本地系统,hdfs或者任何其它hadoop支持的文件系统。RDD的元素必须由key-value对组成,并都实现了Hadoop的Writable接口,或隐式可以转换为Writable(Spark包括了基本类型的转换,例如Int,Double,String等等) |
countByKey() | 对(K,V)类型的RDD有效,返回一个(K,Int)对的Map,表示每一个key对应的元素个数 |
foreach(func) | 在数据集的每一个元素上,运行函数func。这通常用于更新一个累加器变量,或者和外部存储系统做交互 |
2.4)RDDPersistence
Storage Level | Meaning |
---|---|
MEMORY_ONLY | 将RDD作为反序列化的的对象存储JVM中。如果RDD不能被内存装下,一些分区将不会被缓存,并且在需要的时候被重新计算。这是是默认的级别 |
MEMORY_AND_DISK | 将RDD作为反序列化的的对象存储在JVM中。如果RDD不能被与内存装下,超出的分区将被保存在硬盘上,并且在需要时被读取 |
MEMORY_ONLY_SER | 将RDD作为序列化的的对象进行存储(每一分区占用一个字节数组)。通常来说,这比将对象反序列化的空间利用率更高,尤其当使用fastserializer,但在读取时会比较占用CPU |
MEMORY_AND_DISK_SER | 与MEMORY_ONLY_SER相似,但是把超出内存的分区将存储在硬盘上而不是在每次需要的时候重新计算 |
DISK_ONLY | 只将RDD分区存储在硬盘上 |
MEMORY_ONLY_2, MEMORY_AND_DISK_2, etc. | 与上述的存储级别一样,但是将每一个分区都复制到两个集群结点上 |
- 如果对象可以合适存储在内存中,尽量保持默认的MEMORY_ONLY,这可以使得CPU利用率最大化,RDD的Operation(transformation/action)可以最快
- 如果内存大小不适合存储原始对象,那么使用MEMORY_ONLY_SER,并且选择一个合适的序列化工具,使得空间利用率最大化,以及可以快速访问
- 尽量不要使用硬盘存储,除非在内存计算dataset会产生高昂的代价,或者要过滤一个巨大的数据集,否则在分区中重新计算dataset的效率都优于从硬盘加载
- 尽可能使用副本存储机制以保证快速容错,所有的容错机制都可以保证重新计算丢失的数据,但是副本可以让你继续运行而不用等待重新计算丢失的分区数据
3)SharedVariables
3.1)广播变量Broadcast Variables
BroadcastVariables可以在集群所有节点中cache缓存一个只读的变量,而不用来回传递。BroadcastVariables一旦创建,那么任何集群中的任何函数都可以使用它,并且由于它是只读的,可以保证所有节点都有相同的值。BroadcastVariables使用broadcast创建,使用value读取,如:
scala> val broadcastVar = sc.broadcast(Array(1, 2, 3))
scala> broadcastVar.value
3.2)累加器Accumulators
scala> val accum = sc.accumulator(0)
accum: spark.Accumulator[Int] = 0
scala> sc.parallelize(Array(1, 2, 3, 4)).foreach(x => accum += x)
...
10/09/29 18:41:08 INFO SparkContext: Tasks finished in 0.317106 s
scala> accum.value
res2: Int = 10
Term | Meaning |
---|---|
Application | User program built on Spark. Consists ofa |
Driver program | The process running the main() function of the application andcreating the SparkContext. Driverprogram |
Cluster manager | An external service for acquiring resources on the cluster (e.g.standalone manager, Mesos, YARN) |
Worker node | Any node that can run application code in the cluster |
Executor | A process launched for an application on a worker node, that runstasks and keeps data in memory or disk storage across them. Eachapplication has its own executors. |
Task | A unit of work that will be sent to one executor |
Job | A parallel computation consisting of multiple tasks that getsspawned in response to a Spark action(e.g. save , collect );you'll see this term used in the driver's logs. |
Stage | Each job gets divided into smaller sets of taskscalled |
- Amazon EC2: our EC2 scripts let you launch a cluster in about 5minutes
- Standalone Deploy Mode: simplest way to deploy Spark on aprivate cluster
- Apache Mesos
- Hadoop YARN
sbin/start-master.sh
- Starts a masterinstance on the machine the script is executed on. sbin/start-slaves.sh
- Starts a slaveinstance on each machine specified inthe conf/slaves
file. sbin/start-all.sh
- Starts both a masterand a number of slaves as described above. sbin/stop-master.sh
- Stops the master thatwas started via the bin/start-master.sh
script. sbin/stop-slaves.sh
- Stops the slaveinstances that were started via bin/start-slaves.sh
.sbin/stop-all.sh
- Stops both the masterand the slaves as described above.
2)HadoopYARN
![Spark <wbr>编程起步 Spark <wbr>编程起步]()
- 构建SPARK
SPARK_HADOOP_VERSION=2.2.0 SPARK_YARN=true sbt/sbtassembly
cd/usr/local/ims/spark/spark-0.9.0-incubating-bin-hadoop2
- yarn-client
mode(用例测试场景)
SPARK_YARN_APP_JAR=examples/target/scala-2.10/spark-examples-assembly-0.9.0-incubating.jar\
./bin/run-example org.apache.spark.examples.SparkPiyarn-client
SPARK_JAR=./assembly/target/scala-2.10/spark-assembly-0.9.0-incubating-hadoop2.2.0.jar\
SPARK_YARN_APP_JAR=examples/target/scala-2.10/spark-examples-assembly-0.9.0-incubating.jar\
MASTER=yarn-client ./bin/spark-shell
- yarn-standalone
mode(生产环境推荐)
运行SparkPi样例
SPARK_JAR=./assembly/target/scala-2.10/spark-assembly-0.9.0-incubating-hadoop2.2.0.jar\
./bin/spark-classorg.apache.spark.deploy.yarn.Client \
--jarexamples/target/scala-2.10/spark-examples-assembly-0.9.0-incubating.jar\
--classorg.apache.spark.examples.SparkPi \
--args yarn-standalone\
--num-workers 3\
--master-memory 4g\
--worker-memory 2g\
--worker-cores1
运行SparkTC样例(观察跟踪ApplicationMasterTracking UI)
SPARK_JAR=./assembly/target/scala-2.10/spark-assembly-0.9.0-incubating-hadoop2.2.0.jar\
./bin/spark-classorg.apache.spark.deploy.yarn.Client \
--jarexamples/target/scala-2.10/spark-examples-assembly-0.9.0-incubating.jar\
--classorg.apache.spark.examples.SparkTC \
--args yarn-standalone\
--num-workers 3\
--master-memory 4g\
--worker-memory 2g\
--worker-cores1
- 序列化:Kyro
- 内存优化:
- 数据结构:
-
使用原始对象类型,不用使用包装的wrapper对象 -
使用对象数据,而不是集合类,万不得已可以考虑fastutil -
尽量避免大量的内嵌对象和指针引用 -
使用枚举对象替代string -
设置JVM -XX:+UseCompressedStrings
对ASCIIstring使用8bit -
调整存储级别,优先内存,其次考虑硬盘
-
GC调优
-
通过设置JVM的GCverbose参数,观察JVM状态,以及测量GC发生频率和耗时 -
在worker端一个task的执行期间多次发生fullgc,那么显然内存不足以使任务高效运行 -
调整RDD缓存容量,默认使用worker内存的66%进行old full gc,可根据old大小进行调整占比,从而增大RDD缓存利用率,避免任务执行变慢 -
如果时常发生小规模GC,很少Full GC,那么调整young的Eden大小 -
当有时发生OutOfMemory错误,表示task所要处理的数据集对当前节点太大了,可以尝试增加增加parallel -
当某些静态数据存在时,尽可能使用广播变量,以避免串行任务执行
-
MapReduce
- 当两个RDD做Map时,可考虑将数据集小的RDD收集collect至本地后再进行map,以防止整个集群shuffle,更进一步的方法是使用广播变量传递
- 根据hash算法,把相同hash值数据(PageRank中的links/URLs)分配到相同节点内存进行计算,从而避免全局盲目的shuffle
- 设置合理的partition对数据进行切片,调整合适的并发执行度
- 基于YARN资源调度,超越集群节点一致性hash对数据在极端情况下的不均匀,而是通过ResourceManager调度