一、WEBUI-Historyserver
Every SparkContext launches a web UI, by default on port 4040, that displays useful information about the application. This includes:
- A list of scheduler stages and tasks
- A summary of RDD sizes and memory usage
- Environmental information.
- Information about the running executors
当运行结束后无法打开查看。
Note that this information is only available for the duration of the application by default. To view the web UI after the fact, set spark.eventLog.enabled
to true before starting the application. This configures Spark to log Spark events that encode the information displayed in the UI to persisted storage.
从文档说明,在程序启动前设置spark.eventLog.enabled
,spark相关配置都在conf下面。
$SPARK_HOME/conf/spark-default.conf
spark.eventLog.enabled true
spark.eventLog.dir hdfs://hadoop001:8020/directory
$SPARK_HOME/conf/spark.env.sh
SPARK_DAEMON_JAVA_OPTS="-Dspark.history.fs.logDirectory=hdfs://hadoop001:8020/directory"
启动hdfs
启动sparkhistoryservey
$SPARK_HOME/Sbin/
./start-history-server.sh 启动后再次提交作业,作业完成后可以通过webui18080查看运行情况。
默认访问端口为:http://hadoop001:18080/
二、序列化
spark官当文档有一章优化:http://spark.apache.org/docs/latest/tuning.html
序列化在任何分布式应用程序的性能中都扮演着重要的角色。将对象序列化成或消耗大量字节的速度慢的格式将极大地降低计算速度。通常,这是优化Spark应用程序的第一件事。Spark的目标是在便利性(允许您在操作中使用任何Java类型)和性能之间取得平衡。它提供了两个序列化库,
Java serialization:默认情况下,Spark使用Java的ObjectOutputStream框架序列化对象,并且可以与您创建的任何实现Java .io. serializable的类一起工作。您还可以通过扩展java.io.Externalizable来更紧密地控制序列化的性能。Java序列化是灵活的,但通常非常慢,并且导致了许多类的大型序列化格式。
Kryo serialization::Spark还可以使用Kryo库(版本4)来更快地序列化对象。Kryo比Java序列化快得多,也更紧凑(通常多达10倍),但是它不支持所有的序列化类型,并且要求您提前注册将在程序中使用的类,以获得最佳性能。
三、广播 变量
使用SparkContext中可用的广播功能可以极大地减少每个序列化任务的大小,以及通过集群启动作业的成本。如果您的任务使用来自驱动程序内部的任何大型对象(例如,静态查找表),请考虑将其转换为广播变量。Spark将每个任务的序列化大小打印在主服务器上,因此您可以查看它来决定任务是否太大;一般来说,大于20kb的任务可能值得优化。
参见文档 Tuning guide:http://spark.apache.org/docs/latest/tuning.html#broadcasting-large-variables
四、内存管理
调优内存使用有三个考虑因素:对象使用的内存数量(您可能希望将整个数据集放入内存中)、访问这些对象的成本以及垃圾收集的开销(如果对象的周转率很高)。
默认情况下,Java对象访问起来很快,但是很容易比字段中的“原始”数据多消耗2-5倍的空间。这是由于几个原因:
1.每个不同的Java对象都有一个“object header”,大约16个字节,包含指向其类的指针等信息。对于数据很少的对象(比如一个Int字段),它可能比数据大。
2.Java字符串在原始字符串数据上大约有40个字节的开销(因为它们存储在字符数组中并保留额外的数据,如长度),由于字符串内部使用UTF-16编码,所以每个字符存储为两个字节。因此,一个10个字符的字符串可以轻松地消耗60个字节。
3.公共集合类,如HashMap和LinkedList,使用链接数据结构,其中每个条目都有一个“包装器”对象(例如Map.Entry)。这个对象不仅有一个头,而且还有指向列表中下一个对象的指针(通常每个指针有8个字节)。
4.基本类型集合通常将它们存储为“盒装”对象,如java.lang.Integer。
内存管理:
Spark中的内存使用主要分为两类:执行和存储。执行内存是指在改组、连接、排序和聚合中用于计算的内存,而存储内存是指在集群中用于缓存和传播内部数据的内存。在Spark中,执行和存储共享一个统一的区域(M),当没有执行内存时,存储可以获得所有可用的内存,反之亦然。如果需要,执行可能会驱逐存储,但只会在总存储内存使用量低于某个阈值(R)时才会这样做。换句话说,R描述了M中的一个子区域,其中缓存的块永远不会被驱逐。存储可能不会因为实现的复杂性而驱逐执行。
具体默认内存占比:http://spark.apache.org/docs/latest/configuration.html#memory-management
五、数据本地性
数据位置对Spark作业的性能有很大的影响。如果数据和对其进行操作的代码在一起,那么计算往往会很快。但是,如果代码和数据是分开的,其中一个必须移动到另一个。通常,从一个地方到另一个地方传送序列化代码要比传送一块数据快得多,因为代码的大小比数据小得多。Spark根据数据局部性的一般原则构建其调度。
数据局部性是指数据与处理数据的代码之间的距离。基于数据的当前位置,有几个级别的局部性。按从最近到最远的顺序:
- PROCESS_LOCAL数据与运行代码位于同一个JVM中。这是最好的地点
- NODE_LOCAL数据在同一个节点上。示例可能在同一节点上的HDFS中,也可能在同一节点上的另一个执行器中。这比PROCESS_LOCAL稍微慢一些,因为数据必须在进程之间传递
- NO_PREF数据在任何地方都可以同样快速地访问,并且没有区域性首选项
- RACK_LOCAL数据位于相同的服务器机架上。数据位于同一机架上的不同服务器上,因此需要通过网络发送,通常是通过单个交换机
- 任何数据都在网络的其他地方,不在同一个机架上
Spark倾向于将所有任务安排在最佳位置级别,但这并不总是可能的。在任何空闲执行器上都没有未处理的数据的情况下,Spark切换到较低的位置级别。有两种选择:a)等待繁忙的CPU释放,然后在同一台服务器上的数据上启动一个任务,或者b)立即在较远的地方启动一个需要移动数据的新任务。
Spark通常做的是等待一会儿,希望繁忙的CPU释放出来。一旦超时过期,它就开始将数据从很远的地方移动到空闲的CPU。每个级别之间回退的等待超时可以单独配置,也可以全部配置在一个参数中;看到火花。有关详细信息,请参阅配置页上的位置参数。如果您的任务很长,并且局部性很差,那么您应该增加这些设置,但是默认设置通常工作得很好。
相关推荐:
hadoop,pySpark环境安装与运行实战《一》
Spark RDD操作,常用算子《二》
PySpark之算子综合实战案例《三》
Spark运行模式以及部署《四》
Spark Core解析《五》
PySpark之Spark Core调优《六》
PySpark之Spark SQL的使用《七》
持续更新中...