1.Apache Zookeeper:
Apache Zookeeper 是一个分布式,无主服务器的协调服务。假设在分布式环境中有一个无主服务,那就表明没有协调中心,而如果没有协调中心,则集群中每一个zookeeper节点都可以被启动。
假设Zookeeper 服务可用,Spark master 就能依赖它确保在给定的任意时刻,只有一个master控制集群。因此当前master可以在任意给定节点上失效,由其他的master接管为新的leader,这是通过zookeeper的选举过程实现的,由于给定的master 状态保存在zookeeper中,必须将它传给新的master,然后这个继任者才能把工作接上。
应该在提交此应用程序用于运行在 spark-env 文件里的SPARK_DAEMON_JAVA_OPTS 指定以下属性
-Dspark.deploy.recoverMode = ZOOKEEPER
-Dspark.deploy.zookeeper.url = master:port 监听实例的主机:端口
-Dspark.depoly.zookeeper.dir = /spark/master Zookeeper目录
2.Spark driver 应用场景
有一个需要连接(join)两个大数据集的应用,它要求两个文件的所有数据以及对给定的join条件数据集的所有行都驻留在内存中。假设每个数据集有512G,Spark集群的每个数据节点只有256G的内存,在16个数据节点上,哪一个节点都放不下这两个文件。在这个实例中,构建一个2Tb的内存的客户端比较理想,在客户端本地启动driver应用并执行join。
多个应用共享一个spark集群,它们通过客户端节点访问集群,该节点仅有60G的内存,这个集群管理着50个数据节点,每个节点有256G的内存,因为这是一个共享的集群,客户端机器上的资源使用是有限制的,由多个用户共享。在这个实例中,在spark集群的节点上启动driver比较合理。
可以像下面这样手动指定客户端模式启动应用
spark-submit --depoly-mode client <application-jar>
以集群模式启动应用,基本上等价于使用如下命令
spark-submit --deploy-mode cluster <application-jar>
3.Spark 调度器
Spark的内部调度主要分为两种类型。第一种是FIFO(first in,first out),第二种是Fair(公平)调度器。
声明:在这里的上下文中,spark job仅仅是作用于RDD上的一个action,该方法被调用时,它被分解成几个stage(阶段),例如map和reduce。每个stage需要一组资源来完成各自的并行任务。
用FIFO调度器,可以通过一个SparkContext提交多个job,spark将按接受它们的顺序依次完成。这意味着,如果队列头部的job没有利用整个集群的资源,后面的stage也能执行。然而,如果第一个stage很大,消耗了所有可用的资源,对于给定优先级的FIFO队列而言,其他job将无法运行。
FIFO总结:按接受job的顺序依次分配资源,先接受的先分配,分配完后后面的job就无法执行。
Fair调度器就能解决以上的问题,每个job的任务按轮循方式处理。轮循是指为第一个任务分配资源,接着为下一个任务分配资源,依次类推 ,直至所有的任务都分配到资源,然后再从第一个任务开始分配剩余资源,直至所有的资源都被消耗完。它能防止长时间运行的job消耗完所有的资源,那些短时运行的job能迅速响应。
配置Fair调度器
conf.set("spark.scheduler.mode","FAIR")
4.Hive on Spark
Hive 是用于管理分布式存储(例如HDFS)中的大型数据集的数据仓库软件,Hive一开始被开发来作为生成Hadoop Mapreduce数据处理任务的简单接口。(将hive sql 翻译成 MapReduce 的接口),之后,一个更灵活,可靠的框架Tez被引入进来,Apache Tez 是一个比MapReduce更复杂的通用执行引擎。从Hive 1.1开始,Hive也支持spark作为查询执行引擎。这意味着Hive目前支持三个执行引擎:Hadoop MapReduce ,Apache Tez ,spark
5.垃圾回收
基于对象生命周期的长短,它们被存储在Java堆空间的新生代及老年代中,短时对象保存在新生代,而长时对象保存在老年代。当新生代中的对象存活时间足够久或者新生代已满时,对象会被移至老年区。
当老年区快被填满时,会触发一次Full GC,这时也是性能受到影响最大的时候:应用的线程终止,同时整理老年代区的对象。
前面介绍数据缓存的时候说过使用堆外存储可以减少垃圾回收的消耗。