1. 利用spark-shell提交一个session

  1. curl -X POST --data '{"kind":"spark"}' -H "Content-Type:application/json" localhost:8999/sessions

2. 利用spark-submit提交一个session

  1. 上传jar包到hdfs
  2. hadoop fs -mkdir -p /lixiaolong/spark-jars/
  3. hadoop -fs -put /usr/hdp/3.1.0.0-78/spark2/examples/jars/spark-examples_2.11-2.3.2.3.1.0.0-78.jar /lixiaolong/spark-jars/
  4. curl -X POST --data '{"file": "/lixiaolong/spark-jars/spark-examples_2.11-2.3.2.3.1.0.0-78.jar", "className": "org.apache.spark.examples.SparkPi", "args": ["10"]}' -H "Content-Type: application/json" localhost:8999/batches

这里假设spark使用yarn模式,所以所有文件路径都默认位于HDFS中。如果是本地开发模式的话,直接使用本地文件即可(注意必须配置livy.conf文件,设置livy.file.local-dir-whitelist = directory,以允许文件添加到session)。

3. 提交jar包

首先我们列出当前正在执行的任务

  1. curl localhost:8998/sessions | python -m json.tool

然后提交jar包,假设提交的jar包位于hdfs中,路径为/usr/lib/spark/lib/spark-examples.jar

  1. curl -X POST --data '{"file": "/user/romain/spark-examples.jar", "className": "org.apache.spark.examples.SparkPi"}' -H "Content-Type: application/json" localhost:8998/batches

{“id”:0,”state”:”running”,”log”:[]}
返回结果中包括了提交的ID,这里为0,我们可以通过下面的命令查看任务状态:

  1. curl localhost:8998/batches/0 | python -m json.tool

此外,还可以通过下面的api,获取日志信息:

  1. curl localhost:8998/batches/0/log | python -m json.tool

还可以在命令行中添加参数,例如这里计算一百次:

  1. curl -X POST --data '{"file": "/usr/lib/spark/lib/spark-examples.jar", "className": "org.apache.spark.examples.SparkPi", "args": ["100"]}' -H "Content-Type: application/json" localhost:8998/batches

{“id”:1,”state”:”running”,”log”:[]}
如果想终止任务,可以调用以下API:

  1. curl -X DELETE localhost:8998/batches/1

{“msg”:”deleted”}
当重复调用上述接口时,什么也不会做,因为任务已经删除了:

  1. 提交Python任务

提交Python任务和Jar包类似:

  1. curl -X POST --data '{"file": "/user/romain/pi.py"}' -H "Content-Type: application/json" localhost:8998/batches

{“id”:2,”state”:”starting”,”log”:[]}
检查任务状态:

  1. curl localhost:8998/batches/2 | python -m json.tool

获取日志信息:

  1. curl localhost:8998/batches/2/log | python -m json.tool

4. batches的相关问题

  • 注意这里的spark.master需要设置为yarn-cluster。不然,在运行jar时,会报错,
  • hue上说,livy可以工作在local和yarn两种模式,当工作在local模式,jar的制定位置可以就是linux机器上的文件位置。当工作在yarn模式时,必须将jar上传到hdfs上,相应的,jar的file路径也是hdfs的路径。
  • 在我们执行spark-submit时,如果在打jar包时指定了入口的class,在spark-submit时可以不用再指定,但使用batches时,必须要制定ClassName作为jar的入口,否则会报错:

Error: Cannot load main class from JAR hdfs://datanode32:8020/user/caoaoxiang/spark-examples-1.6.1-hadoop2.6.0.jar with URI hdfs. Please specify a class through —class.

  • spark的yarn部署模式有spark-client和spark-cluster。这两种方式的主要区别就是driver的运行位置。spark-client的driver运行在宿主机上,spark-cluster的deriver运行在整个集群中,可以从集群中申请资源。
  • 个人认为,batches的yarn工作模式必须是spark-cluster,可以使得宿主机的资源不会成为运行的瓶颈。

    5. curl报错400解决方法

    image.jpeg
    1. curl -X POST --data '{"kind": "pyspark"}' -H "Content-Type: application/json" livy_server.domain.com:8999/sessions
    2. <html>
    3. <head>
    4. <meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1"/>
    5. <title>Error 400 </title>
    6. </head>
    7. <body>
    8. <h2>HTTP ERROR: 400</h2>
    9. <p>Problem accessing /sessions. Reason:
    10. <pre > Missing Required Header for CSRF protection.</pre ></p>
    11. <hr /><i><small>Powered by Jetty://</small></i>
    12. </body>
    13. </html>
    解决办法
    我发现在我的配置中将livy.server.csrf_protection.enabled参数设置为true,因此我不得不在标头请求中使用X-Requested-By指定一个额外的参数 parameter:
    1. curl -X POST --data '{"kind": "pyspark"}' -H "Content-Type: application/json" -H "X-Requested-By: Yannick" livy_server.domain.com:8999/sessions
    或者可以将livy.server.csrf_protection.enabled参数设置为false