Kafka Streaming【用kafkaStreaming进行数据过滤,然后再放入kafka中】

确保kafka的有相应的topic

案例所需要的表格

这里topic数据是从flume中获取的。
下面是将数据从本地文件夹中传入Kafka中指定的topic消息队列中。

#定义source、channel、sink
user_friends.sources = userFriendSource
user_friends.channels = userFriendChannel
user_friends.sinks = userFriendSink

# 指定source的类型
user_friends.sources.userFriendSource.type = spooldir
# 指定source监控的目录
user_friends.sources.userFriendSource.spoolDir = /opt/kb07file/flumeFile/data/tablecsv
#指定一个把文件中的数据行解析成Event的解析器。默认是把每一行当做一个Event进行解析,所有解析器必须实现EventDeserializer.Builder接口
user_friends.sources.userFriendSource.deserializer = LINE
# 设定一行最大长度为60000
user_friends.sources.userFriendSource.deserializer.maxLineLength = 60000
#用正则表达式指定所需要接收的文件的文件名,文件名符合的才会被接收
user_friends.sources.userFriendSource.includePattern = userFriends_[0-9]{4}-[0-9]{2}-[0-9]{2}.csv

# 指定channe的类型
user_friends.channels.userFriendChannel.type = file
# 指定检查点所在目录
user_friends.channels.userFriendChannel.checkpointDir = /opt/kb07file/flumeFile/checkpoint/userFriends
#逗号分隔的目录列表,用于存储日志文件。 在不同物理磁盘上使用多个目录可以提高文件channel的性能
user_friends.channels.userFriendChannel.dataDirs = /opt/kb07file/flumeFile/data/userFriends

#指定sink类型
user_friends.sinks.userFriendSink.type = org.apache.flume.sink.kafka.KafkaSink
#每次批量发送的 Event 数
user_friends.sinks.userFriendSink.batchSize = 640
#所需要传输的机器的ip
user_friends.sinks.userFriendSink.brokerList = 192.168.222.115:9092
#所需要存放的kafka  topic 需要指定
user_friends.sinks.userFriendSink.topic = user_friends_raw
#source连接channel
#sorce连接sink
user_friends.sources.userFriendSource.channels = userFriendChannel
user_friends.sinks.userFriendSink.channel = userFriendChannel

再Kafka中创建一个flume中指定的topic用来接收传来的消息

  • 注释: 如果没有配置环境变量,所有涉及到kafka的命令,请在kafka的bin目录下执行一下代码

启动Kafka

kafka-server-start.sh -daemon ./config/server.properties

创建符合flume指定的kafka的topic

  • 注释:这里因为使用的是单机版的kafka,所以建议分区设为1就好了
kafka-topics.sh --create --zookeeper 192.168.222.115:2181 --topic user_friends_raw --partitions 1 --replication-factor 1

启动flume相关配置,然后查看kafka中topic的变化

kafka topic执行前查看数据行数

kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list 192.168.222.115:9092 --topic user_friends_raw -time -1 --offsets 1

#结果为
user_friends_raw:0:0

启动flume相关配置

flume-ng agent --conf ./ --conf-file userfriends-flume-kafka.conf --name user_friends -Dflume.root.logger = INFO,console

再次查看topic中的数据行数

kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list 192.168.222.115:9092 --topic user_friends_raw -time -1 --offsets 1

#结果为
user_friends_raw:0:29500
#说明数据已经进入kafka对应的topic中

使用KafkaStreaming API 拿到topic数据,处理完放回Kafka新的topic中

  • 注释:代码写好先不要执行
  • 业务代码解说
    这段代码实现的是将原本userid 后面跟的数据拆分编程一个userid对应拆分后的一条数据,然后再放回kafka中。
    这样操作虽然消息数量变多了,但是方便了后期的提取和管理。
import org.apache.kafka.common.serialization.Serdes;
import org.apache.kafka.streams.*;
import org.apache.kafka.streams.kstream.KStream;

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.CountDownLatch;

public class MyUserFriends {
    public static void main(String[] args) {
        Properties prop = new Properties();
        prop.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG,"192.168.222.115:9092");
        prop.put(StreamsConfig.APPLICATION_ID_CONFIG,"kb07");
        prop.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass());
        prop.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG,Serdes.String().getClass());

        // TODO: 2020/8/27 将定义的Streams应用程序的计算逻辑 
        // TODO: 2020/8/27 在kafka的流中,这种计算逻辑被定义为连接处理器节点的拓扑。 
        // TODO: 2020/8/27 我们可以使用拓扑构建器来构造这样的拓扑。
        StreamsBuilder builder = new StreamsBuilder();

        // TODO: 2020/8/27 然后设置一个输入流的主题
        final KStream<Object, Object> user_friends_raw = builder.stream("user_friends_raw")
                .filter((k, v) -> (!v.toString().startsWith("user,")
                        && v.toString().split(",").length == 2));

        // TODO: 2020/8/27 可以根据业务逻辑需要,从输入流主题中源源不断的获取数据,处理完成后发。
        user_friends_raw.flatMap((k,v)->{
            System.out.println(k+"  "+v);
            List<KeyValue<String,String>> keyValues = new ArrayList<>();
            String[] split = v.toString().split(",");
            String userId = split[0];
            String[] friends = split[1].split(" ");
            for(String friend: friends){
                KeyValue<String,String> keyValue=new KeyValue<>(null,userId+" "+friend);
                keyValues.add(keyValue);
            }
            return keyValues;
            // 下面字符串是新建的kafka topic
        }).to("user_friends");

        // TODO: 2020/8/27 我们可以通过一下步骤来检查构建器所创建的拓扑结构 
        Topology topo = builder.build();

        // TODO: 2020/8/27 有了拓扑结构和属性配置后,就可以构造一个KafkaStream对象
        KafkaStreams streams = new KafkaStreams(topo, prop);

        // TODO: 2020/8/24 java1.5以后 提供的一个线程构造器
        CountDownLatch countDownLatch = new CountDownLatch(1);

        // TODO: 2020/8/24 加一个关闭的钩子
        Runtime.getRuntime().addShutdownHook(new Thread("kb07"){
            @Override
            public void run() {
                streams.close();
                countDownLatch.countDown();
            }

        });

        streams.start();
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //todo 线程脱钩
        System.exit(0);
    }
}

再kafka中创建新的topic,用来接收KafkaStreaming清理后的数据

kafka-topics.sh --create --zookeeper 192.168.222.115:2181 --topic user_friends --partitions 1 --replication-factor 1

查看创建的topic中的数据行数

kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list 192.168.222.115:9092 --topic user_friends -time -1 --offsets 1

#结果为:
 user_friends:0:0

在idea执行Kafka Streaming

在这里插入图片描述

再次查看新的topic中的数据行数

kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list 192.168.222.115:9092 --topic user_friends -time -1 --offsets 1

#结果为:
user_friends:0:30386403
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值