Apache Spark技术实战(一)Standalone部署模式下的临时文件清理&日志级别修改

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 在Standalone部署模式下,Spark运行过程中会创建哪些临时性目录及文件,这些临时目录和文件又是在什么时候被清理,本文将就这些问题做深入细致的解答;并讨论日志级别修改问题。

<一>Standalone部署模式下的临时文件清理

概要

在Standalone部署模式下,Spark运行过程中会创建哪些临时性目录及文件,这些临时目录和文件又是在什么时候被清理,本文将就这些问题做深入细致的解答。

从资源使用的方面来看,一个进程运行期间会利用到这四个方面的资源,分别是CPU,内存,磁盘和网络。进程退出之后,CPU,内存和网络都会由操作系统负责释放掉,但是运行过程中产生临时文件如果进程自己不在退出之前有效清除,就会留下一地鸡毛,浪费有效的存储空间。

部署时的第三方依赖

再提出具体的疑问之前,先回顾一下standalone的部署模式。

在standalone下又分为client模式和cluster模式,其中client模式下,driver和client运行于同一JVM中,不由worker启动,该JVM进程直到spark application计算完成返回结果后才退出。如下图所示。

而在cluster模式下,driver由worker启动,client在确认spark application成功提交给cluster后直接退出,并不等待spark application运行结果返回。如下图所示:

从部署图来进行分析,每个JVM进程在启动时的文件依赖如何得到满足。

1)Master进程最为简单,除了spark jar包之外,不存在第三方库依赖。
2)Driver和Executor在运行的时候都有可能存在第三方包依赖,分开来讲:
  1. Driver比较简单,spark-submit在提交的时候会指定所要依赖的jar文件从哪里读取;
  2. Executor由worker来启动,worker需要下载Executor启动时所需要的jar文件,那么从哪里下载呢。

为了解决Executor启动时依赖的Jar问题,Driver在启动的时候要启动HttpFileServer存储第三方jar包,然后由worker从HttpFileServer来获取。为此HttpFileServer需要创建相应的目录,而Worker也需要创建相应的目录。

HttpFileServer创建目录的过程详见于SparkEnv.scala中create函数。

spark会为每一个提交的application生成一个文件夹,默认位于$SPARK_HOME/work目录下,用以存放从HttpFileServer下载下来的第三方库依赖及Executor运行时生成的日志信息。

实验1

运行spark-shell,查看在/tmp目录下会新产生哪些目录。

#$SPARK_HOME/bin/spark-shell

在/tmp目录下会新增四个与spark-shell相关的文件夹:

spark+随机数目录

  分别用于driver本身,driver创建的tmp目录,httpfileserver创建的目录:

spark-local目录

  用以存放executor执行过程中生成的shuffle output和cache的内容。

运行中的临时文件

Executor在运行的时候,会生成Shuffle Output,如果对RDD进行Cache的话,还有可能会将RDD的内容吐到磁盘中。这些都意味着需要有一个文件夹来容纳这些东西。

上文中提到的形如spark-local-*的目录就是用以存储executor运行时生成的临时文件。

可以通过两个简单的实验来看spark-local-*目录下内容的变化。

实验2:不进行RDD Cache

进入spark-shell之后运行:

spark-shell>sc.textFile(“README.md”).flatMap(l=>l.split(“ “)).map(w=>(w,1)).reduceByKey(_ + _).foreach(println)

上述指令会生成两个不同的Stage, 所以会有Shuffle Output,具体划分原因就不再细述了。

如果使用的是spark 1.2.x,可以看到有在spark-local-*目录下有index文件生成。

实验3: 进行RDD Cache

进入spark-shell之后运行:

spark-shell>val rdd1 = sc.textFile(“README.md”).flatMap(l=>l.split(“ “)).map(w=>(w,1)).reduceByKey(_ + _)
spark-shell> rdd1.persist(MEMORY_AND_DISK_SER)
spark-shell>rdd1.foreach(println)

上述指令执行后,不仅会有index文件还会有形如rdd*的文件生成,这些rdd打头的文件就是cache内容。

配置项

可以通过在$SPARK_HOME/conf/spark-env.sh中指定配置内容来更改默认的存储位置。

SPARK_WORK_DIR 指定work目录,默认是$SPARK_HOME/work子目录。

SPARK_LOCAL_DIRS 指定executor运行生成的临时文件目录,默认是/tmp,由于/tmp目录有可能是采用了tmpfs,建议在实际部署中将其更改到其它目录。

文件的清理

上述过程中生成的临时文件在什么时候会被删除掉呢?

也许第一感觉就是spark application结束运行的时候呗,直觉有时不见得就是对的。

SPARK_LOCAL_DIRS下的产生的文件夹,确实会在应用程序退出的时候自动清理掉,如果观察仔细的话,还会发现在spark_local_dirs目录有有诸如*_cache和*_lock的文件,它们没有被自动清除。这是一个BUG,可以会在spark 1.3中加以更正。有关该BUG的具体描述,参考spark-4323 https://issues.apache.org/jira/browse/SPARK-4323。

$SPARK_LOCAL_DIRS下的*_cache文件是为了避免同一台机器中多个executor执行同一application时多次下载第三方依赖的问题而引进的patch,详见JIRA case spark-2713. 对就的代码见spark/util/Utils.java中的fetchFile函数。https://issues.apache.org/jira/browse/SPARK-2713。

如果已经在使用了,有什么办法来清除呢?暴力删除,不管三七二十一,过一段时间将已经存在的cache和lock全部删除。这不会有什么副作用,大不了executor再去下载一次罢了。

find $SPARK_LOCAL_DIRS -max-depth 1 -type f -mtime 1 -exec rm -- {} \;

而SPARK_WORK_DIR目录下的形如app-timestamp-seqid的文件夹默认不会自动清除。

那么可以设置哪些选项来自动清除已经停止运行的application的文件夹呢?当然有。

在spark-env.sh中加入如下内容:

SPARK_WORKER_OPTS=”-Dspark.worker.cleanup.enabled=true

注意官方文档中说不管程序是否已经停止,都会删除文件夹,这是不准确的,只有停止掉的程序文件夹才会被删除,我已提交相应的PR。

如果Spark应用程序需要长时间运行,生成的许多shuffle output何时再清理呢?可以通过配置spark.cleaner.ttl来设置清理的时间。

实验4

写一个简单的WordCount,然后以Standalone Cluster模式提交运行,察看$SPARK_LOCAL_DIRS下文件内容的变化。

import org.apache.spark._
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.SparkContext._
import java.util.Date
object HelloApp {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf()
    val sc = new SparkContext()
    val fileName = "$SPARK_HOME/README.md"
    val rdd1 = sc.textFile(fileName).flatMap(l => l.split(" ")).map(w => (w, 1))
    rdd1.reduceByKey(_ + _).foreach(println)
    
    var i: Int = 0
    while ( i < 10 ) {
      Thread.sleep(10000)
      i = i + 1
    }
  }
}

提交运行:

spark-submit –class HelloApp –master spark://127.0.0.1:7077  --deploy-mode cluster HelloApp.jar	

小结

本文通过几个简单易行的实验来观测standalone模式下临时文件的产生和清除,希望有助于理解spark中磁盘资源的申请和释放过程。

Spark部署时相关的配置项比较多,如果先进行分类,然后再去配置会容易许多,分类有CPUMemoryNetworkSecurityDiskAkka相关。

参考资料

  1. https://spark.apache.org/docs/1.2.0/submitting-applications.html
  2. https://spark.apache.org/docs/1.2.0/spark-standalone.html
  3. http://mail-archives.apache.org/mod_mbox/spark-commits/201410.mbox/%3C2c2ce06abc7d48d48f17f8e458a53219@git.apache.org%3E
  4. https://issues.apache.org/jira/browse/SPARK-4323
  5. https://issues.apache.org/jira/browse/SPARK-2713

<二>日志级别修改

摘要

在学习使用Spark的过程中,总是想对内部运行过程作深入的了解,其中DEBUGTRACE级别的日志可以为我们提供详细和有用的信息,那么如何进行合理设置呢,不复杂但也绝不是将一个INFO换为TRACE那么简单。

主要问题

调整Spark日志级别的配置文件是$SPARK_HOME/conf/log4j.properties,默认级别是INFO,如果曾经将其改为DEBUG的朋友可能会有这样的经历,有用的信息还没看完,就被大量的心跳检测日志给淹没了。

解决办法

只将需要的日志级别调整为_TRACE_,而将心跳检测类的设置为_INFO_级别以上,避免干扰。

log4j.properties示范

   # Set everything to be logged to the console
   log4j.rootCategory=INFO, console
   log4j.appender.console=org.apache.log4j.ConsoleAppender
   log4j.appender.console.target=System.err
   log4j.appender.console.layout=org.apache.log4j.PatternLayout
   log4j.appender.console.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %p %c{1}: %m%n

   # Settings to quiet third party logs that are too verbose
   log4j.logger.org.eclipse.jetty=WARN
   log4j.logger.org.eclipse.jetty.util.component.AbstractLifeCycle=ERROR
   log4j.logger.org.apache.spark.repl.SparkIMain$exprTyper=INFO
   log4j.logger.org.apache.spark.repl.SparkILoop$SparkILoopInterpreter=INFO
   log4j.logger.org.apache.spark.sql.SQLContext=TRACE
   log4j.logger.org.apache.spark.sql.catalyst.analysis.Analyzer=TRACE
   log4j.logger.org.apache.spark=TRACE
   log4j.logger.org.apache.spark.storage.BlockManagerMasterActor=WARN
   log4j.logger.org.apache.spark.HeartbeatReceiver=WARN
   log4j.logger.org.apache.spark.scheduler.local.LocalActor=WARN

小结

第一次在博客园中用markdown格式来写文章,感觉挺简单的。

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
2月前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL InnoDB的数据文件与重做日志文件
本文介绍了MySQL InnoDB存储引擎中的数据文件和重做日志文件。数据文件包括`.ibd`和`ibdata`文件,用于存放InnoDB数据和索引。重做日志文件(redo log)确保数据的可靠性和事务的持久性,其大小和路径可由相关参数配置。文章还提供了视频讲解和示例代码。
182 11
【赵渝强老师】MySQL InnoDB的数据文件与重做日志文件
|
2月前
|
SQL Oracle 关系型数据库
【赵渝强老师】Oracle的控制文件与归档日志文件
本文介绍了Oracle数据库中的控制文件和归档日志文件。控制文件记录了数据库的物理结构信息,如数据库名、数据文件和联机日志文件的位置等。为了保护数据库,通常会进行控制文件的多路复用。归档日志文件是联机重做日志文件的副本,用于记录数据库的变更历史。文章还提供了相关SQL语句,帮助查看和设置数据库的日志模式。
【赵渝强老师】Oracle的控制文件与归档日志文件
|
2月前
|
SQL 关系型数据库 MySQL
【赵渝强老师】MySQL的全量日志文件
MySQL全量日志记录所有操作的SQL语句,默认禁用。启用后,可通过`show variables like %general_log%检查状态,使用`set global general_log=ON`临时开启,执行查询并查看日志文件以追踪SQL执行详情。
|
2月前
|
Oracle 关系型数据库 数据库
【赵渝强老师】Oracle的参数文件与告警日志文件
本文介绍了Oracle数据库的参数文件和告警日志文件。参数文件分为初始化参数文件(PFile)和服务器端参数文件(SPFile),在数据库启动时读取并分配资源。告警日志文件记录了数据库的重要活动、错误和警告信息,帮助诊断问题。文中还提供了相关视频讲解和示例代码。
|
2月前
|
存储 分布式计算 Hadoop
数据湖技术:Hadoop与Spark在大数据处理中的协同作用
【10月更文挑战第27天】在大数据时代,数据湖技术凭借其灵活性和成本效益成为企业存储和分析大规模异构数据的首选。Hadoop和Spark作为数据湖技术的核心组件,通过HDFS存储数据和Spark进行高效计算,实现了数据处理的优化。本文探讨了Hadoop与Spark的最佳实践,包括数据存储、处理、安全和可视化等方面,展示了它们在实际应用中的协同效应。
159 2
|
2月前
|
存储 分布式计算 Hadoop
数据湖技术:Hadoop与Spark在大数据处理中的协同作用
【10月更文挑战第26天】本文详细探讨了Hadoop与Spark在大数据处理中的协同作用,通过具体案例展示了两者的最佳实践。Hadoop的HDFS和MapReduce负责数据存储和预处理,确保高可靠性和容错性;Spark则凭借其高性能和丰富的API,进行深度分析和机器学习,实现高效的批处理和实时处理。
144 1
|
3月前
|
SQL 数据库
为什么 SQL 日志文件很大,我应该如何处理?
为什么 SQL 日志文件很大,我应该如何处理?
|
3月前
|
SQL 数据库
为什么SQL日志文件很大,该如何处理?
为什么SQL日志文件很大,该如何处理?
|
2月前
|
分布式计算 大数据 Apache
ClickHouse与大数据生态集成:Spark & Flink 实战
【10月更文挑战第26天】在当今这个数据爆炸的时代,能够高效地处理和分析海量数据成为了企业和组织提升竞争力的关键。作为一款高性能的列式数据库系统,ClickHouse 在大数据分析领域展现出了卓越的能力。然而,为了充分利用ClickHouse的优势,将其与现有的大数据处理框架(如Apache Spark和Apache Flink)进行集成变得尤为重要。本文将从我个人的角度出发,探讨如何通过这些技术的结合,实现对大规模数据的实时处理和分析。
214 2
ClickHouse与大数据生态集成:Spark & Flink 实战

热门文章

最新文章

推荐镜像

更多