Storm-Kafka使用笔记(一):Scheme和Mapper

来源:互联网 发布:上海进项发票认证软件 编辑:程序博客网 时间:2024/06/06 03:42

一、背景

因为是项目驱动的去了解Storm-kafka,所以会由于分工去先了解某一部分,顺序有点杂乱。

二、Storm-Kafka介绍

了解Storm的都知道,Storm拓扑中比较基本的就是Spout和Bolt,Spout作为数据发射源,可以从数据库或者其他地方取得数据然后发射出去,Bolt就是中间一个个运算处理的组件,最后一个Bolt可以担任数据处理结果汇总或者数据落地的角色。

三、Storm-Kafka为我们提供了什么

最先了解的是KafkaSpout和KafkaBolt,显而易见就是把我们上面说的Spout和最后一个Bolt的功用具体化,具体到KafkaSpout就是从Kafka取数据源的Spout,而KafkaBolt就是把数据处理结果转化为一定格式,发送到Kafka的Bolt。

但是,在这之中我们需要有一些规约,就是Spout从Kafka拿到数据后我要怎么处理转换成Storm中的数据格式–Tuple,还有Bolt要怎么把接收到的Tuple转换成Kafka的格式发送到Kafka,这就涉及到另外两个基础的概念,Scheme和Mapper,它们分别说明了我们上面的规约,并把数据进行转换再返回。
Scheme就实现了从byte[]到其他格式的转换(默认提供的是从字节流到字符串的转换)。Mapper就实现了从Tuple到其他格式的转换(默认提供的是从Tuple取Field为key的作为key返回,取Field为message的作为message转换),也让我们可以个性化实现(当然Storm-Kafka也提供了默认的)。

四、Mapper

Mapper接口:

package org.apache.storm.kafka.bolt.mapper;import org.apache.storm.tuple.Tuple;import java.io.Serializable;/** * as the really verbose name suggests this interface mapps a storm tuple to kafka key and message. * @param <K> type of key. * @param <V> type of value. */public interface TupleToKafkaMapper<K,V> extends Serializable {    K getKeyFromTuple(Tuple tuple);    V getMessageFromTuple(Tuple tuple);}

可以看到Mapper接口里面只有两个方法,分别是获取Key和Message,对应的就是发送给Kafka的信息里的Key(可选)和Message。

Storm-Kafka提供默认的FieldNameBasedTupleToKafkaMapper是这样的:

//返回Key和Msg,默认的Field是"key" "message",在new的时候可以自定义,也可以在方法里面做封装和拼接package org.apache.storm.kafka.bolt.mapper;import org.apache.storm.tuple.Tuple;public class FieldNameBasedTupleToKafkaMapper<K,V> implements TupleToKafkaMapper<K, V> {    public static final String BOLT_KEY = "key";    public static final String BOLT_MESSAGE = "message";    public String boltKeyField;    public String boltMessageField;    public FieldNameBasedTupleToKafkaMapper() {        this(BOLT_KEY, BOLT_MESSAGE);    }    public FieldNameBasedTupleToKafkaMapper(String boltKeyField, String boltMessageField) {        this.boltKeyField = boltKeyField;        this.boltMessageField = boltMessageField;    }    @Override    public K getKeyFromTuple(Tuple tuple) {        //for backward compatibility, we return null when key is not present.        return tuple.contains(boltKeyField) ? (K) tuple.getValueByField(boltKeyField) : null;    }    @Override    public V getMessageFromTuple(Tuple tuple) {        return (V) tuple.getValueByField(boltMessageField);    }}

然后,其实不难想到KafkaBolt里面的操作,就是

//取出值然后封装发出,非常简单key = mapper.getKeyFromTuple(input);message = mapper.getMessageFromTuple(input);producer.send(new KeyedMessage(topic, key, message));

五、Scheme

Scheme主要负责定义如何从消息流中解析所需数据。
Scheme接口:

public interface Scheme extends Serializable {      public List<Object> deserialize(byte[] ser);      public Fields getOutputFields();  }  

包括反序列化的方法和输出的字段声明。
Storm-Kafka自带的StringScheme的实现:

public class StringScheme implements Scheme {    private static final Charset UTF8_CHARSET = StandardCharsets.UTF_8;    public static final String STRING_SCHEME_KEY = "str";    public List<Object> deserialize(ByteBuffer bytes) {        return new Values(deserializeString(bytes));    }    public static String deserializeString(ByteBuffer string) {        if (string.hasArray()) {            int base = string.arrayOffset();            return new String(string.array(), base + string.position(), string.remaining());        } else {            return new String(Utils.toByteArray(string), UTF8_CHARSET);        }    }    public Fields getOutputFields() {        return new Fields(STRING_SCHEME_KEY);    }}

其实就是返回了String和声明了字段”str”,只要在方法里自定义对字节流的操作,并声明了字段,就可以自定义自己的Scheme了。

1 0
原创粉丝点击