数据从kafka到hive(2)

本文详细介绍了数据从Kafka到Hive的迁移工具camus的实现原理,包括camus如何重写InputFormat和OutputFormat,以及在ETL过程中对kafka partition的处理方式。camus通过map-reduce执行,不设置reduce任务,直接将数据写入目标目录。在InputFormat中,camus获取每个partition的earliest和latest offset,创建请求列表并分配到mapper。RecordReader从InputSplit读取message,并传递给mapper。OutputFormat则负责将mapper的输出写入临时文件,任务完成后,将文件拷贝到最终目的地。
摘要由CSDN通过智能技术生成

前面一篇讲到了将数据从kafka读到hdfs使用了开源工具camus,既然用到了开源的代码,免不了研究一下实现过程。所以这里分享一下阅读camus代码了解到的一些细节。

前置知识

在讲camus之前,需要提一下hadoop的一些知识。

关于inputFormat

inputFormat类的原型如下:

public interface InputFormat<K, V> {
        InputSplit[] getSplits(JobConf job, int numSplits) throws IOException;
        RecordReader<K, V> getRecordReader(InputSplit split,JobConf job,Reporter reporter) throws IOException;
}

hadoop job调用setInputFormat来设置InputFormat类,通过getSplits函数,hadoop可以将输入分割为InputSplit,每个map分配到InputSplit后,再通过getRecordReader获取reader,逐条读取输入文件中Key-Value。hadoop本身提供了一些InputFormat类的实现,如TextInputFormat,KeyValueTextInputFormat,SequenceFileInputFormat等;
除了使用hadoop本身提供的这些类以外,hadoop允许自定义InputFormat类,只需要实现相应的getSplits函数和RecoderReader类即可。

关于OutputFormat 和 OutputCommitter

OutputFormat类用于写入记录,原型如下:

public abstract class OutputFormat<K, V> {
    //创建一个写入器
  public abstract RecordWriter<K, V> getRecordWriter(TaskAttemptContext context) throws IOException, InterruptedException;
   // 检查结果输出的存储空间是否有效
  public abstract void checkOutputSpecs(JobContext context) throws IOException, InterruptedException;
   //创建一个任务提交器
  public abstract OutputCommitter getOutputCommitter(TaskAttemptContext context) throws IOException, InterruptedException;
}

getRecordWriter和checkOutputSpecs都很好理解,前置就是将Mapper或Reducer传来的key-value写入到文件里面,写入的姿势由它来决定。而checkOutputSpecs一般就是用来检查输出规范,判断输出文件是否存在,如果已经存在,则抛出异常。
OutputCommitter稍稍难理解一点,里面定义了这几个方法:

//Job开始被执行之前,框架会调用setupJob()为Job创建一个输出路径
void  setupJob(JobContext jobContext);
//如果Job成功完成,框架会调用commitJob()提交Job的输出
void  commitJob(JobContext jobContext);
//如果Job失败,框架会调用OutputCommitter.abortJob()撤销Job的输出
void  abortJob(JobContext jobContext, JobStatus.State state);
//Task执行前的准备工作,类似setupJob
void  setupTask(TaskAttemptContext taskContext);
//Task可能没有输出,也就不需要提交,通过needsTaskCommit()来判断
boolean  needsTaskCommit(TaskAttemptContext taskContext);
//Task成功执行,提交输出
void  commitTask(TaskAttemptContext taskContext);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值