最近做大数据的项目,碰到了一个坑, Running on yarn 的时候有两个模式,一个是 client 一个是 cluster ,
但是我的 Big jar 里面需要读 取配置文件
,配置文件在本地,所用用 cluster 模式会出现 FilenotfondException , excutor 不知道这个文件的位置,现在想让excutor 知道这个文件的位置和内容
找到了几个参数 就是 spark-submit 加上--files 但是似乎没有起到作用,求个正确的姿势。 有两个配置文件,一个是 project.propeties , 一个是 parser.properties 用 Scala 搞得,但是 io 只能读取本地文件,这个比较坑,因为 hadoop 上面的文件系统似乎和本地的不一样。
还有一个方法似乎是用 --properties-file 但是这个只能载入配置。来个正确的姿势急等。*
spark-submit --class "app.Runml" --master yarn-cluster --files "/home/expertise/BigData2016/conf/project.properties","/home/expertise/BigData2016/conf/2016.properties" --jar ~/BigData2016/ml-assembly-1.0.jar 出现了 FileNotFond ,但是 client 模式就 ok 。 郁闷死了,不想重新改 parser 的代码,这里是读取文件的代码,返回一个 properties ,可以之间 properties.get(你想要的参数)
object Tools {
def conf(file: String): Properties = {
val properties = new Properties()
properties.load(new FileInputStream(file))
properties
}
}
1
mringg 2016-06-24 17:29:20 +08:00 1
初始化的时候 用广播变量存储配置信息
|
3
liprais 2016-06-24 18:20:50 +08:00
cluster 模式需要你在每个节点的这个路径下面都有这个文件,为啥不能用 client 模式?
|
4
winiex 2016-06-24 18:25:49 +08:00
你用 big jar 的话,应该把配置也打包进去,然后运行的时候把配置的路径加入到 classpath 中去。
Hadoop 里面 Configuration 是通过 classLoader 来寻找配置文件的,所以重点是在 cluster 上的每个机器内相同的 classpath 里存在相同的配置文件。 Spark 处理手段可能是类似的,不过它用的 Scala 实现的,我也不是太确定。 还有一个手段就是把你的自定义配置当作参数传进去了,这个比较麻烦。 |
5
winiex 2016-06-24 18:28:07 +08:00 1
除了打包以外, hadoop 里面还有 distribute cache 可以用来存储公有文件,然后再 loadResource 加入到运行的程序中去,这个特性 spark 应该也能够用吧。
|
7
qfdk OP @liprais 主要也要看一下 有什么不同的地方 性能 使用情景 第一次接触 打包也碰到不少坑 比如 sbt run 和 sbt assembly 不能同时共存 而且规定只能用 Scala ide
|
8
qfdk OP @winiex 谢谢 现在把所有的配置文件写成一个 conf 用--conf 传进去 这样 cluster 解决了 但是还是在想动态参数问题
|
9
winiex 2016-06-24 18:40:23 +08:00
@qfdk 那就把要改的配置项通过参数的方式传进去呗, hadoop 这边的处理逻辑是参数方式的配置会覆盖掉非 final 的配置文件中的配置,优先级更高。等到上线的版本打包也不迟。
话说回来,你把程序提交到集群运行还是免不了要打包的啊。 动态参数可以在程序代码里面实现的, MapReduce 程序里面用 Configuration 来实现,你可以看看 spark 里面有没有类似的 API 。 |
10
qfdk OP @winiex 想的是这样的,程序打包好了,可以读取外部的配置文件,然后外部的配置文件里面写着程序里面的参数,就是 key-value 形式的,看了一下优先级,在 spark-submit 参数的优先级比较高,比 default 的更高一些。刚才说错了,那个参数是--property-file 但是只能传一个大的配置文件,总之还是感谢。
|
11
yaoyuan7571 2016-06-25 09:13:14 +08:00 1
对于 yarn-cluster,可以试下--files /home/expertise/BigData2016/conf/project.properties#project.properties,读取的时候改为
def conf(file: String): Properties = { val properties = new Properties() try { properties.load(new FileInputStream(file)) } catch { case e : FileNotFoundException => properties.load(new FileInputStream((new File(file)).getName()) case e : Throwable => throw e } properties } 因为没有环境不太方便验证,如果不行可以在试一试添加 --conf spark.driver.extraClassPath=./ --conf spark.executor.extraClassPath |
12
qfdk OP @yaoyuan7571 我周一试一下 谢谢
|
13
qfdk OP @yaoyuan7571 似乎可以了,但是运行结束之后出现了奇怪的 exception
Exception in thread "main" org.apache.spark.SparkException: Application application_1465834608781_0129 finished with f |
14
yaoyuan7571 2016-06-27 19:56:10 +08:00
@qfdk 贴出来的信息量太少,看不出哪里问题,你可以再仔细看下异常堆栈,应该是其他方面的问题
|
15
qfdk OP @yaoyuan7571 谢谢先,顺便问另一个问题 sbt run 和 sbt assembly 没法一起共存,
libraryDependencies ++= Seq( "org.apache.spark" %% "spark-core" % "1.6.1"% "provided", "org.apache.spark" %% "spark-sql" % "1.6.1"% "provided", "com.databricks" %% "spark-xml" % "0.2.0" ) 加了 provided 关键字,似乎只能 assembly 后来用的 lazy val makeJar = project.in(file(".")).settings( libraryDependencies ++= spd.map(_ % "provided"), libraryDependencies +="com.databricks" % "spark-xml_2.10" % "0.2.0" ) 发现用 sbt makeJar : assembly 可以但是 sbt run 还是不可以,因为缺少 spark-core ,要不然就是打包重复。 |
16
yaoyuan7571 2016-06-27 22:08:50 +08:00
@qfdk sbt run 命令调用的是 project 中的 main class, 而 spark 任务需要使用 spark-submit 脚本提交任务,应该用不到 sbt run 这个命令吧,打包的话可以使用 sbt+assembly 插件(也可以使用 maven 管理项目)生成一个包含所有依赖的全包(去除 spark-core 这种框架已提供的), 外部使用单独的 shell 脚本执行生成的 jar 包
|