Spark Thrift Server 解放数据开发,开发计算资源的里利器

0x001 Spark Thrift Server 是什么

   Spark Thrift Server 是一个jdbc和odbc服务,底层依赖的是hive Server2。

0X002 Spark Thrift Sever 带来的价值

现在部分公司情况, 大数据部门更像是一个报表开发部门,日常工作就是开发报表,一个完了接着下一个。整个模式的架构如下: 关系数据库=》 大数据平台 =》关系数据库 =》报表后台 。

Spark Thrift Server 解放数据开发,开发计算资源的里利器_第1张图片

0x003 总结

上面这种架构有一下几个问题。
1: 数据平台需要完成80%的计算指标,剩余部分由mysql完成,业务稍有变动数据平台也需要跟着调整。
2:业务的变更需要数据平台、报表后台开发的支持,导致不能够及时响应需求的变更。
3:也是最重要的一点,只开放了数据平台的人力,没有开放出计算平台的计算力(和人力成本比起来,硬件资源的成本很低)

0X004 解决

上面的架构暴露出了问题,怎么去解决他那,这个时候Spark Thrift Server就排上用场了(如下图),通过它能够直接把集群的计算资源开放出去,后台开发通过调用jdbc服务来调用我们集群的计算资源。在底层我们只需开发出与业务相关最细粒度的事实表即可,不在需要去开发每一个具体的指标,数据的粒度没变,不论业务怎么变化,我们都不需要做调整。话不多说开始具体的实践吧
Spark Thrift Server 解放数据开发,开发计算资源的里利器_第2张图片

0x005 相关配置

相关环境:CDH6.0.1, hive2.2.1 , Spark2.4.0(开源的)
1: 打通 Hive到Spark
把hive的hive-site.xml拷贝的${SPARK_HOME}/conf 里。

2:配置Spark Thrift Server2。
备注: 默认的Hive Server2服务端口是10000,注意重复

${SPARK_HOME}/conf/hive-site.xml


   
       hive.server2.thrift.min.worker.threads
       5
   
   
       hive.server2.thrift.max.worker.threads
       500
   
   
      hive.server2.thrift.port
       10001
   
   
       hive.server2.thrift.bind.host
       
       cdh102 
   


0x005 启动服务

./sbin/start-thriftserver.sh --master yarn --num-executors 2 \

–executor-cores 2
–conf “spark.executor.overhead.memory=1g”
–conf “spark.executor.memory=2g”
–jars ./mysql-connector-java-6.0.6.jar

0x006 验证服务

服务的验证由好几个地方:

0x006.1 linux beeline 方式验证

1:启动
     $SPARK_HOME/bin/beeline
2:链接服务
	!connect jdbc:hive2://cdh102:10001
	输入对应的用户与密码:user:root, password:空。
3:查看链接后的状态

Spark Thrift Server 解放数据开发,开发计算资源的里利器_第3张图片

0x006.2 Spark Ui窗口方式验证

通过 http://hostname:4040验证,这里面还能查到每个sql具体的执行信息。

0x007 开发编程

只需要开发jdbc程序就能够链接Spark SQL,代码如下

pom 依赖:

        
            org.spark-project.hive
            hive-jdbc
            1.2.1.spark
        
    
        
        
            org.apache.hadoop
            hadoop-client
            ${hadoop.version}
        
public class SparkThriftDemo {

    public static void main(String[] args) {
        //add driver
        String driver="org.apache.hive.jdbc.HiveDriver";
        try {
            Class.forName(driver);
            //get connection
            //这里的url就是启动beeline的时候用的url sid是hive中的库名
            String jdbc="jdbc:hive2://cdh102:10001";
            try {
                Connection  connection= DriverManager.getConnection(jdbc);

                long startTime=System.currentTimeMillis(); //获取开始时间

                //get statement
                connection.prepareStatement("use game_dwd").execute();
                String sql="select substr(a.ctime,0, 10) as day,substr(a.ctime,12, 2) as hour,  a.barcode, a.activity_id , a.activity_name, count(distinct a.main_uid) as num  from game_dwd.dwd_market_lottery a \n" +
                        "where substr(a.ctime,0, 10) < '2019-05-22' and   substr(a.ctime,0, 10) > '2019-05-01'\n" +
                        "group by  substr(a.ctime,0, 10), substr(a.ctime,12, 2), a.barcode,  a.activity_id , a.activity_name   ";

                sql="select  a.barcode , a.activity_id , a.activity_name, b.register_platform,  substr(a.ctime,0, 10) as day, substr(a.ctime,12, 2) as hour, count(a.main_uid) as total_makets,sum(consume_circle) as num  from game_dwd.dwd_market_lottery a \n" +
                        "join game_dwd.dwd_user_main b on a.main_uid = b.id\n" +
                        "GROUP BY a.barcode, b.register_platform , a.activity_id , a.activity_name,substr(a.ctime,0, 10) , substr(a.ctime,12, 2)";
                Statement statement=connection.prepareStatement(sql);

                //get result
                ResultSet rs= statement.executeQuery(sql);
                while(rs.next()){
                    System.out.println("day:"+ rs.getString("day")  + " 抽奖人数:" + rs.getString("num"));

                }
                long endTime=System.currentTimeMillis(); //获取结束时间
                System.out.println("程序运行时间: "+(endTime-startTime
                )+"ms");
                rs.close();
                statement.close();
                connection.close();

            } catch (SQLException e) {
                e.printStackTrace();
            }

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

0x008 效率情况

到了我们关心的效率问题了,一般我们关系的有两个问题,单次的查询耗时和并发耗时
1: 单次的情况如下, 这段sql是比较复杂,耗时约3秒 。 在这之上我们可以做优化,如存储格式
Spark Thrift Server 解放数据开发,开发计算资源的里利器_第4张图片
2:并发 由于一般这类报表都是面向运营和管理层的,用户量不大。如果到极端情况,我们可以增加Spark Thrift Server的个数,然后做负载均衡。

遇到的问题

1:在写jdbc客服端的时候遇到了棘手的问题
原因是由于我的hive-jdbc版本不对,报了无连接的错,左后我拉去${SPARK_HOME}/jars 下对应的hive-jdbc 包就解决这个问题了。

你可能感兴趣的:(Spark,数据仓库,SparkSQL)