分享

spark个人学习总结

xuanxufeng 2015-8-2 16:29:04 发表于 总结型 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 3 24986

导读
spark是比较火的一门大数据技术,下面是某个同学的个人经验总结,借鉴过来,供大家参考





通过修改Spark的属性,环境变量,或者是日志属性来配置Spark
使用Web端界面,以及各种不同的外部工具来监控Spark和应用程序


在Spark集群中有三种主要的组成部分。驱动程序,是放置主程序中SparkContext的地方,要运行一个集群,你需要一个集群管理器
它可以是单机版的集群管理器,也可以是 Mesos 或者 Yarn
而worker节点,就是放置执行器的地方



执行器,是运行计算和储存应用程序数据的地方。SparkContext以JAR或者Python文件
的形式向每个执行器发送应用程序。最终,它向每个执行器发送任务并运行

因为驱动程序在集群上调配任务,它应该在相同的本地网络中
  
的woker节点运行。如果要向集群发送远端请求


最好使用一个RPC,并且从附近的节点提交操作

我们前面提到三个支持的集群管理器

对于Spark的配置,主要有三个主要的地方


Spark属性,你可以用SparkConf对象或者通过Java系统属性来设置应用程序的参数
环境变量,你可以用它们来设置每一个机器的设定,比如IP地址这是通过配置每一个节点上的conf/spark-env.sh脚本实现的
对于日志属性,它可以通过log4j.propertieis来进行设置
你可以选择修改目前位于SPARK_HOME/conf目录下的默认配置目录设定SPARK_CONF_DIR环境变量并且在这个目录下提供你的配置文件




这里有两种方法来设定Spark属性:
第一种方法是通过SparkConf对象来传递应用程序属性
第二种方法是动态地设置Spark的属性。Spark允许你在创建一个SparkContext的时候传递一个空的SparkConf
然后,在运行时用 “—master” 或者 “—conf” 参数命令行选项来提供设置值


你可以运行spark-submit脚本的时候,通过“—-help”来查看各种选项
另一种设定Spark属性的方法是在spark-defaults.conf文件里设置
spark-submit脚本会从你的文件中读取这些配置
你可以在应用程序的默认端口为4040的Web客户端上查看Spark属性


最后我想提到的一件注意事项,直接SparkConf上设置的属性具有最高的优先级
spark-submit或者spark-shell是第二优先级,最后是spark-default.conf文件里的设置。


监控Spark应用程序有三种方法:第一种方法是使用基于Web的客户端,它的默认端口是4040
在应用程序运行期间,你可以在这个客户端上获得Spark实时监控信息
如果你希望在程序运行完以后查看这些信息,你需要在应用程序开始之前把spark.eventlog.enabled属性设定为true,这样所有运行的信息就会被储存起来




Metrics是另一种检测Spark应用程序的方法。这个metric系统是基于Coda Hale Metrics库的
你可以自定义输出的格式,例如CSV格式的运行报告
可以在conf目录下的metrics.properties文件中配置metrics系统


最后,也可以通过外部工具来监控Spark。例如,Gangalia是用来查看整体集群的利用情况和资源瓶颈的工具。
各种不同的OS profiling工具和JVM工具也可以用来监测Spark


默认设置下,Web客户端可以在端口4040下查看,它显示当前
正在运行的应用程序的信息。Web客户端,可以看到任务协调器的状态,提交的任务状态,RDD的大小,内存使用量的报告,环境设置信息以及
正在运行的执行器的信息




要在应用程序运行完以后查看应用程序的历史,你需要启动历史记录服务器配置历史记录服务器可以规定给它分配多少内存
各种JVM的选项,服务器的公共地址以及一系列的属性




集群中的任何一种资源都有可能成为Spark的瓶颈
Spark的内存计算属性,数据序列化以及内存优化成为能够提升Spark效能的
两个主要的因素。


数据的序列化是一种提升网络效能并减少内存使用的关键这是当你要优化Spark应用程序需要优先考虑的
Spark提供两个数据序列化的库。Java序列化提供更多的选择,但是它们通常很慢
而且生成过大的序列化对象。但这个是Spark用来序列化对象的默认库
Kyro序列化比Java要快很多,但是不支持所有的序列化类型
你需要提前注册这些类库,来获得最好的性能效果,可以通过设置SparkConf对象来使用Kyro序列化




在内存优化中,你需要考虑三件事:
1)对象使用的内存有多少(无论你是否想将全部对象导入到内存中);
2)获取这些对象的成本;
3)垃圾回收的管理费用


你创建一个RDD,先将它缓存,然后查看你驱动程序中的
SparkContext日志。查看日志可以帮助你了解数据集需要多少内存
这里有减少每个对象内存使用量的一些建议。尽量避免增加管理费用的某些Java特征
比如基于指针的数据结构和wrapper对象。如果可以的话,使用数组或者原始数据类型并且避免使用迭代结构




序列化储存也可以帮助减少内存使用。缺点是它会导致要花更多的时间来获取数据
因为在你使用这些数据之前,你必须要对它们进行反序列化


你可以在垃圾回收器中查看它发生的频率,以及它使用时间的、一系列指标。你可以通过将此行增加到SPARK_JAVA_OPTS环境变量中来实现它


为了要充分利用集群,并行的级别也是需要考虑的因素之一
它自动地被设置为任务文件的大小,但是你可以通过例如在SparkContext.textFile里的
选项参数来配置它。你也可以对spark.default.parallelism的config属性设置默认的并行级别。通常来说,我们建议在集群中
为每一个CPU核设置2到3个任务
当你的内存不能容纳你的RDD的时候,你会得到一个OutOfMemoryError错误
在这种情况下,通过提升并行级别可以解决这个问题
通过提升并行级别,每一个输入的任务集都会变得更小,这样内存就可以容纳了




通过Spark的广播变量的功能,可以极大地减小序列化对象的大小
有一个比较好的例子,比如你有某种静态的公共查询表
考虑一下把它变成一个广播变量,这样它就不需要被发送到
每一个worker节点上,省去了很多序列化对象的工作
Spark将每一个任务序列化之后的大小打印到主节点上。通过查看这些信息,
也可以帮助检查否有任务过大。如果你发现某些任务超过20KB,你就有必要考虑
是否需要对它进行优化,比如创建广播变量

已有(3)人评论

跳转到指定楼层
Mac_Jsy 发表于 2015-8-5 12:09:12
不错不错!刚接触spark
回复

使用道具 举报

sprite101 发表于 2015-8-10 15:00:10
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条