有什么方式能让java后台程序直接调用spark,并且直接收到spark计算后的返回值?
目前我这边能做的只是用java传给kafka,kafka再给spark,spark计算完后再回传给kafka,java程序再接收
我这样做比较绕
有没有什么方法能直接调用并得到返回值的?

解决方案 »

  1.   

    其实你目前这种方案是比较好的。如果你是web同步与spark交互,会阻塞servlet线程,吞吐量有限。除非你的集群非常碉堡,能在很短时间完成响应。另外结果建议是写到Redis上,前台查询后台,会得到一个请求id,这个请求id就是redis的key。然后拿着这个id轮询结果获取接口。
    我们这边做Spark即席查询,都是SparkContext和Web Service分离,通过Zookeeper实现HA和负载均衡。Web Service接收SQL查询请求,对SQL进行优化后,查询ZK获取较空闲的Driver,然后将SQL发送给Driver执行,结果是写在HDFS上,然后把请求id作为key,HDFS路径作为value,写到Redis上。
      

  2.   

    就看你怎么看待spark ,如果把spark当作服务,那可以使用spark的 rest的客户端,提交job。如果你要把spark当作依赖,代码中集成。不管是rest 还是集成,你都可以编写你的drvier,返回你需要的值。
      

  3.   


    大侠能不能详细讲讲,谢谢。有案例可供参考吗?
    大概是:
    1、编写一个Spark Driver,我们称之为SparkJobServer,部署模式是Yarn client,打开DynamicAllocation特性,即会根据实际需要动态申请Executor。然后启动的时候,在ZK的某个路径下,创建一个PERSISTENT_SEQUENTIAL类型节点(参见:http://blog.csdn.net/heyutao007/article/details/38741207),得到自己的一个ID,然后在新建的这个节点下,设置自身的ip,Socket端口,以及负载值(当前有多少个SQL在跑)等信息。启动一个Socket Server,监听上面说的端口,接收SQL请求,优化SQL,然后通过SQLContext.sql执行,负载值+1,执行完成后-1,结果放在请求报文定义的hdfs目录上,并在redis设置对应的key value。另外有个细节就是利用ShutdownHook,在Driver意外退出的时候,删除ZK上自身信息节点,实现自动下线。这个SparkJobServer会在不同机器启动多个,以实现HA和负载均衡。
    2、Web后端接收前端传来的SQL,通过UUID生成一个请求Key,在ZK指定路径下,找到目前可用且负载值最小的SparkJobServer,向它发送指定格式的TCP/IP报文。然后把key返回给前端。
    3、前端拿着这个key去轮询另一个rest接口,这个rest接口直接去查询redis,如果拿到值,就是SparkJobServer跑出来放在HDFS上的结果文件路径,直接读取这个文件,返回给前端。如果拿不到值,前端定时轮询直到取到值。
    4、另外会有一个后台服务去监控SparkJobServer的状况。可以手工启动或下线SparkJobServer。
    我们这个方案是经过数据日增量10T,日即席查询数1w+考验的架构。可以根据自身需求修改。
      

  4.   

    大神,
    1、那个SparkJobServer不是一个离线的程序吗,如何保持多个SparkJobServer是启动状态?
    2、如何在zk中保持每个SparkJobServer对应的元数据值(自身的ip,Socket端口,以及负载值)?
      

  5.   

    1、Driver不死,SparkJobServer就一直存在。SparkContext是线程安全的。每个Driver都会开启若干个线程去处理前端传过来的SQL查询请求。
    2、用zk 的API啊!ZK就是为服务注册发现而生的
      

  6.   

    你好,用java传给kafka,kafka再给spark,spark计算完后再回传给kafka,java程序再接收,这种类型的例子能不能分享给我,让我学习下啊。谢谢啊。
      

  7.   

    楼主你好,用java传给kafka,kafka再给spark,spark计算完后再回传给kafka,java程序再接收,这种类型的例子能不能分享给我,让我学习下啊。谢谢啊。
      

  8.   

    Spark Thrift Server,可以通过JDBC连接