【问题标题】:how to use the spark cluster computing function in servlets如何在servlet中使用spark集群计算功能
【发布时间】:2014-07-08 06:42:55
【问题描述】:

我正在开发一个动态网络项目。我想编写一个 servlet 类来响应帧提交请求并使用 apache spark 执行一些集群计算任务(例如,计算 pi)。 servlet(named Hello)的doGet函数如下

public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    String [] args=new String[2];
    args[0]="local";
    args[1]="4";
    double count=0;
    count=performSpark.cpi(args);
    //double count=3.14;
    String text1 =String.valueOf(count);
    response.sendRedirect("wresultjsp.jsp?text1=" + text1);  
}

performSpark 类如下:

public class performSpark {
    static double cpi(String[] input)
    {
        JavaSparkContext jsc = new JavaSparkContext(input[0], "performspark",
        System.getenv("SPARK_HOME"), JavaSparkContext.jarOfClass(performSpark.class));

        int slices = (input.length == 2) ? Integer.parseInt(input[1]) : 2;
        int n = 1000000 * slices;
        List<Integer> l = new ArrayList<Integer>(n);
        for (int i = 0; i < n; i++) 
        {
            l.add(1);
        }

        JavaRDD<Integer> dataSet = jsc.parallelize(l);

        int count = dataSet.map(new Function<Integer, Integer>() {
            @Override
            public Integer call(Integer integer) {
                double x = Math.random() * 2 - 1;             
                double y = Math.random() * 2 - 1;
                return (x * x + y * y < 1) ? 1 : 0;
            }
        }).reduce(new Function2<Integer, Integer, Integer>() {
            @Override
            public Integer call(Integer integer, Integer integer2) {
                return integer + integer2;
            }
        });

        double result=4.0 * count / n;      
        return result;
    }
}

spark-assemply-2.10-0.9.1-hadoop2.2.0.jar 被复制到 WEB-INF/lib。 构建成功,但是当我在tomcat7服务器中运行servlet时,创建JavaSparkContext时报告java.lang.ClassNotFoundException

Servlet.service() 用于 servlet [Hello] 在上下文中的路径 [/sparkdemo] 抛出异常 [Servlet 执行抛出异常] 根本原因是 java.lang.ClassNotFoundException: org.apache.spark.api.java.function.Function 在 org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1720) 在 org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1571) 在 Hello.doGet(Hello.java:54) 在 Hello.doPost(Hello.java:74) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:646) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:727)

有人知道如何解决这个问题吗?

【问题讨论】:

  • 在WEB-INF下更改任何内容后必须重新启动服务。
  • 感谢您的回复。我尝试重新启动服务器,但错误仍然存​​在。由于构建动态Web项目时没有发生错误,我猜spark-assemply jar加载成功。但是在创建 JavaSparkContext 时发生了 ClassNotFoundException。所以我想知道除了 spark-assemply jar 之外,执行 spark 是否还需要其他依赖项。

标签: tomcat servlets apache-spark


【解决方案1】:

最后,我找到了如下解决方案。

tomcat服务器启动时加载spark-assemply-2.10-0.9.1-hadoop2.2.0.jar,报错:validateJarFile (.....) - jar not loaded. See Servlet Spec3.0 ......,表示存在jar依赖重叠。

然后我打开spark-assemply-2.10-0.9.1-hadoop2.2.0.jar 并在javax/servlet 中找到一个重叠的文件夹。删除servlet文件夹后,spark-assemply-2.10-0.9.1-hadoop2.2.0.jar在tomcat中加载成功,ClassNotFoundException消失了。

【讨论】:

    【解决方案2】:

    我们的项目中有一个类似的用例,我们希望提交用户查询以从 Web 项目交互地激发。 我们实现它的方法是首先创建一个 spark session 并将我们的自定义 servlet 附加到:.attachHandler()

    在自定义 servlet 的 attachHandler 方法中,我们将 Servlet 类附加到 spark 的 ServletContextHandler 上:

    ServletContextHandler handler = new ServletContextHandler();
    HttpServlet servlet = new <CustomServlet>(spark);
    ServletHolder sh = new ServletHolder(servlet);
    handler.setContextPath(<root context>);
    handler.addServlet(sh, <path>);
    spark.sparkContext().ui().get().attachHandler(handler);
    

    现在 servlet 已经连接到 Spark UI 上,比如端口 4040,那么你可以直接向它提交请求。我们覆盖了 servlet 的 doGet 方法以接受包含要运行的 SQL 的 JSON,使用提交的 SQL
    ds = this.spark.sql(查询); 遍历返回的数据集,并将其添加到响应对象中。

    另一种方法是利用 Apache Livy。

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2016-03-28
      • 1970-01-01
      • 2014-04-11
      • 1970-01-01
      • 1970-01-01
      • 2018-08-23
      • 2021-03-03
      • 1970-01-01
      • 2017-07-14
      相关资源
      最近更新 更多