这几天我尝试了hadoop+spark+hive+mysql集成方案:
1. Hadoop: 提供HDFS服务
2. Spark: 实现map-reduce分析算法
3. Hive提供Spark计算的来源数据
4. Mysql存放Hive的元数据,以及计算的最终结果
首先,我把需要处理的原始数据文件临时存放在hdfs上,文件名是随机产生,以实现文件名的唯一性。
然后,我通过hive提供的接口,将数据导入到hive中。(注:其实hive是将数据保存在HDFS上自己特定目录下)
最后,我用spark处理hive上数据,再将最终结果存放到mysql里面。
这套方案已经可以工作。不过还有一些遗留问题:
Hive的效率:为了提高hive的处理效率,需要将数据分区。hive分区的实现原理,与我们之前的想法是一致的。Hive也是在hdfs上创建了不同的目录,来存放分区数据。
但是hive的分区对用户不是透明的。也就是说,在我们查询数据时,必须知道是要查询哪几个分区,在查询条件中也必须显式地指出分区的具体值。
这个与我之前理解的分区接口不太一样。比如mysql的分区,用户是不需要在查询SQL中写出分区条件的。另外, hive支持的SQL标准也有限。论坛说hive在处理大规模数据时,性能比较差。
Hive的性能比较差,主要是基于hadoop map-reduce方案的原因。Hadoop map-reduce在处理过程中,会把中间结果写入hdfs,也就是磁盘上。IO效率会成为系统瓶颈。
星环科技采用Spark来实现处理过程,大量中间结果保存在内存中,这个应该是影响效率最大的部分。
我看了星环科技的方案,他没有用SparkSQL、Hive这样的技术,而是自己实现SQL这一层。
参考了网上的一些资料,我们也可以按这个思路试一下:在上层封装一层SQLParser,在下面可以基于Spark来实现具体动作。
我找了一个开源SQLParser: JSqlParser http://jsqlparser.sourceforge.net/
通过这个工具,可以对用户提交的SQL进行解析,然后用map-reduce对源数据进行处理,得到用户想要的结果。
我试用了一下这个工具,可以分析SQL文法。这个文法采用JavaCC描述,可以根据需要进行调整。