从HIVE中的REST API访问数据

时间:2016-09-27 22:39:46

标签: hadoop hive hiveql

有没有办法创建一个hive表,其中该hive表的位置将是一个http JSON REST API?我不想每次都在HDFS中导入数据。

1 个答案:

答案 0 :(得分:1)

几年前我在一个项目中遇到过类似的情况。这是从Restful到HDFS的数据摄取的低调方式,然后您使用Hive分析来实现业务逻辑。我希望您熟悉核心Java,Map Reduce(如果不是,您可能会考虑Hortonworks数据流, HDF是Hortonworks的产品。)

步骤1:您的数据提取工作流程不应与包含业务逻辑的Hive工作流绑定。这应该根据您的要求(数据流的数量和速度)及时独立执行并定期监控。我在文本编辑器上编写此代码。警告:它没有编译或测试!!

下面的代码使用的是Mapper,它会接收网址或调整它以接受来自FS的网址列表。有效负载或请求的数据作为文本文件存储在指定的作业输出目录中(这次忘记了数据结构)。

Mapper类:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;

import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;


public class HadoopHttpClientMap extends Mapper<LongWritable, Text, Text, Text> {
    private int file = 0;
    private String jobOutDir;
    private String taskId;

    @Override
    protected void setup(Context context) throws IOException,InterruptedException {
        super.setup(context);

        jobOutDir = context.getOutputValueClass().getName();
        taskId = context.getJobID().toString();

    }

    public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException{

        Path httpDest = new Path(jobOutDir, taskId + "_http_" + (file++));

        InputStream is = null;
        OutputStream os = null;
        URLConnection connection;
        try {
            connection = new URL(value.toString()).openConnection();
            //implement connection timeout logics
            //authenticate.. etc
            is = connection.getInputStream();

            os = FileSystem.getLocal(context.getConfiguration()).create(httpDest,true);

            IOUtils.copyBytes(is, os, context.getConfiguration(), true);

        } catch(Throwable t){
            t.printStackTrace();
        }finally {
            IOUtils.closeStream(is);
            IOUtils.closeStream(os);
        }

        context.write(value, null);
        //context.write(new Text (httpDest.getName()), new Text (os.toString()));
    }

}  

仅限映射器作业:

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;


public class HadoopHttpClientJob {
    private static final String data_input_directory  =  “YOUR_INPUT_DIR”;
    private static final String data_output_directory  =  “YOUR_OUTPUT_DIR”;

    public HadoopHttpClientJob() {
    }

    public static void main(String... args) {
        try {
            Configuration conf = new Configuration();

            Path test_data_in = new Path(data_input_directory, "urls.txt");
            Path test_data_out = new Path(data_output_directory);

            @SuppressWarnings("deprecation")
            Job job = new Job(conf, "HadoopHttpClientMap" + System.currentTimeMillis());
            job.setJarByClass(HadoopHttpClientJob.class);

            FileSystem fs = FileSystem.get(conf);

            fs.delete(test_data_out, true);
            job.setMapperClass(HadoopHttpClientMap.class);
            job.setMapOutputKeyClass(Text.class);
            job.setMapOutputValueClass(Text.class);
            job.setInputFormatClass(TextInputFormat.class);
            job.setOutputFormatClass(TextOutputFormat.class);
            job.setNumReduceTasks(0);

            FileInputFormat.addInputPath(job, test_data_in);
            FileOutputFormat.setOutputPath(job, test_data_out);

            job.waitForCompletion(true);

        }catch (Throwable t){
            t.printStackTrace();
        }
    }
}

步骤2:根据HDFS目录在Hive中创建外部表。记得使用Hive SerDe作为JSON数据(在您的情况下),然后您可以将外部表中的数据复制到托管主表中。这是实现增量逻辑压缩的步骤..

步骤3:将您的配置单元查询(您可能已创建)指向主表,以实现您的业务需求。

注意:如果您涉及实时分析或流式API,则可能需要更改应用程序的体系结构。既然您已经提出了架构问题,我会使用我最好的猜测来支持您。请仔细阅读一次。如果您认为可以在应用程序中实现此功能,那么您可以询问具体问题,我会尽力解决这些问题。