我可以获取使用avro kafka消息的示例代码吗?

时间:2016-04-15 17:53:30

标签: apache-kafka avro apache-apex

我刚刚设置了Datatorrent RTS(Apache Apex)平台并运行了pi演示。 我想消费" avro"来自kafka的消息然后聚合并将数据存储到hdfs中。 我可以获得这个或kafka的示例代码吗?

3 个答案:

答案 0 :(得分:2)

以下是完整工作应用程序的代码,它使用新的Kafka输入操作符和Apex Malhar的文件输出操作符。它将字节数组转换为字符串,并使用有限大小的滚动文件(在本例中为1K)将它们写入HDFS;在文件大小达到界限之前,它将具有.tmp扩展名的临时名称。您可以按照https://stackoverflow.com/a/36666388)中的DevT建议在这两者之间插入其他运算符:

package com.example.myapexapp;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

import org.apache.apex.malhar.kafka.AbstractKafkaInputOperator;
import org.apache.apex.malhar.kafka.KafkaSinglePortInputOperator;
import org.apache.hadoop.conf.Configuration;

import com.datatorrent.api.annotation.ApplicationAnnotation;
import com.datatorrent.api.StreamingApplication;
import com.datatorrent.api.DAG;

import com.datatorrent.lib.io.ConsoleOutputOperator;
import com.datatorrent.lib.io.fs.AbstractFileInputOperator.FileLineInputOperator;
import com.datatorrent.lib.io.fs.AbstractFileOutputOperator;

@ApplicationAnnotation(name="MyFirstApplication")
public class KafkaApp implements StreamingApplication
{

  @Override
  public void populateDAG(DAG dag, Configuration conf)
  {
    KafkaSinglePortInputOperator in = dag.addOperator("in", new KafkaSinglePortInputOperator());
    in.setInitialPartitionCount(1);
    in.setTopics("test");
    in.setInitialOffset(AbstractKafkaInputOperator.InitialOffset.EARLIEST.name());
    //in.setClusters("localhost:2181");
    in.setClusters("localhost:9092");   // NOTE: need broker address, not zookeeper

    LineOutputOperator out = dag.addOperator("out", new LineOutputOperator());
    out.setFilePath("/tmp/FromKafka");
    out.setFileName("test");
    out.setMaxLength(1024);        // max size of rolling output file

    // create stream connecting input adapter to output adapter
    dag.addStream("data", in.outputPort, out.input);
  }
}

/**
 * Converts each tuple to a string and writes it as a new line to the output file
 */
class LineOutputOperator extends AbstractFileOutputOperator<byte[]>
{
  private static final String NL = System.lineSeparator();
  private static final Charset CS = StandardCharsets.UTF_8;
  private String fileName;

  @Override
  public byte[] getBytesForTuple(byte[] t) { return (new String(t, CS) + NL).getBytes(CS); }

  @Override
  protected String getFileName(byte[] tuple) { return fileName; }

  public String getFileName() { return fileName; }
  public void setFileName(final String v) { fileName = v; }
}

答案 1 :(得分:1)

在较高级别,您的应用程序代码类似于

KafkaSinglePortStringInputOperator - &gt; AvroToPojo - &gt;尺寸聚合器 - &gt; AbstractFileOutputOperator的实现

KafkaSinglePortStringInputOperator - 如果您正在使用其他数据类型,则可以使用KafkaSinglePortByteArrayInputOperator或编写自定义实现。

AvroToPojo - https://github.com/apache/incubator-apex-malhar/blob/5075ce0ef75afccdff2edf4c044465340176a148/contrib/src/main/java/com/datatorrent/contrib/avro/AvroToPojo.java

此运算符将GenericRecord转换为给定POJO的用户。用户需要提供应该发出的POJO类,否则使用反射。目前,这用于从容器文件中读取GenericRecords,仅支持基本类型。从Kafka你可以沿着类似的行对你的运算符进行建模,并添加一个Schema对象来解析传入的记录。在processTuple方法中,下面的东西应该可以工作, Schema schema = new Schema.Parser()。parse()); GenericDatumReader reader = new GenericDatumReader(schema);

Dimensions聚合器 - 您可以选择此处给出的聚合器之一 - https://github.com/apache/incubator-apex-malhar/tree/5075ce0ef75afccdff2edf4c044465340176a148/library/src/main/java/org/apache/apex/malhar/lib/dimensions或沿相同的行编写自定义聚合器。

FileWriter - 来自上面帖子中的示例。

答案 2 :(得分:0)

从Kafka读取并写入JDBC的示例代码。

github.com/tweise/apex-samples/tree/master/exactly-once

博客解释上述代码。

www.datatorrent.com/blog/end-to-end-exactly-once-with-apache-apex /

可以找到Avro运营商 https://github.com/apache/incubator-apex-malhar/search?utf8=%E2%9C%93&q=avro

测试用例包含示例用例。