Kafka的简单介绍与使用,生产者和消费者的JavaApi

一、简介
2、实时流数据管道,可以在
3、构建流式引用
4、是一个分布式流式处理平台, 统称消息队列或消息中间件,有生产者和消费者之分
消费者去kafka中拉数据(而不是kafka给数据)
其实kafka就是一个临时存储的插件,但是这个插件性能很强大
kafka 是用scala编译的
0.8版本的偏移量 可以自己管理,0.8版本用的很多
高可用、高吞吐、多副本、容错、读写能力强

三、kafka的组件
1、生产者:Producer
是消息生产的源头,生产者不需要连接zookeeper
2、消费者:Consumer
是消费的使用方,负责消费kafka服务器上的消息
3、主题:Topic: 由用户定义配置,用于建立生产者和消费者之间的订阅关系,生产者发送消息到指定的Topic下,消费者从这个Topic消费消息
4、消息分区:Partition,一个Topic下面会分为多个分区,这个分区也是用户指定的,在kafka上没有主从结构,但是Partition上是有主从结构的
,每个分区都有一个活跃的(leader),leader分区负责读写,follower分区负责同步数据,producer会向leader的分区写数据,读数据时可以从leader读,也可以从follower中读,实现读写的压力均摊到多态机器上,提高了读写能力,尽量让分区的leader分散到不同的机器上,
生产环境中,副本保存3分(最佳),配置分区的数量broker的数量*每一台机器上所用的核数(充分发挥机器的多核多线程的功能)
follower分区的功能是:负责同步数据,也可以设置从分区读取数据
kafka的吞吐量大, 同步数据
5、Broker:kafka 的服务器ID,一台机器就叫一个Broker
6、消费者组:Group,用于归类同一消费者,在kafka中,多个消费者可以共同消费一个Topic下的消息,每个消费者消费一部分消息,这些消费者就组成了一个分区,拥有同一个分组名称
消费者组,可以消费一个或多个分区的数据,相反,一个数据同一时刻,只能被一个消费者消费
7、Offset:偏移量,消费者在拉取数据过程中,需要知道消息在文件中的偏移量,然后才能通过偏移量拉去数据

四、使用场景
1、日志收集
2、消息系统(kafka其一个缓冲的作用)
3、运营指标
4、流式处理(spark streaming)
index文件存的是索引(元数据,偏移量),先找索引文件,在拉去真正的数据
logs,存放真正的数据

五、kafka的常用命令
1、新建一个主题
默认有一个partition(配置文件中)分区数只能增加不能减少
创建一个topic,设置分区数,设置副本数和zookeeper,因为partition有主从结构,所以zookeeper中存放一些元数据,在读取时也需要指定zk,找到topic对应的元数据
创建topic(topic的信息保存在zk中,zk中保存了topic叫什么,有几个副本,几个分区)在创建时,如果指定副本数大于集群中的数量brokers会报错kafka.admin.AdminOperationException: replication factor: 4 larger than available brokers: 3
分区数可以随意指定

bin/kafka-topics.sh --create --zookeeper 192.168.163.128:2181,192.168.136.129:2181,192.168.136.130:2181 --partition 3 --replication-factor 3 --topic test-01

查看topic
kafka-topics.sh --list --zookeeper 192.168.163.128:2181,192.168.136.129:2181,192.168.136.130:2181

查看描述详细信息
kafka-topics.sh --describe --zookeeper 192.168.163.128:2181,192.168.136.129:2181,192.168.136.130:2181 --topic test-01

分区数 每个分区的leader 副本 存活副本数
数字代表broker.id
Topic:test-01 PartitionCount:3 ReplicationFactor:3 Configs:
Topic: test-01 Partition: 0 Leader: 1 Replicas: 1,0,2 Isr: 1,0,2
Topic: test-01 Partition: 1 Leader: 2 Replicas: 2,1,0 Isr: 2,1,0
Topic: test-01 Partition: 2 Leader: 0 Replicas: 0,2,1 Isr: 0,2,1

删除topic:真正删除没有删除,要真正删除时,要删除zookeeper的client端的元数据
kafka-topics.sh --delete --zookeeper 192.168.163.128:2181,192.168.136.129:2181,192.168.136.130:2181 --topic test-01
显示 ,再 list查询时 显示 test-01 - marked for deletion
要真正删除时,要删除zookeeper的client端的元数据:
rmr /brokers/topics/test-01 ,删除client中的brokers中topic对应的
rmr /config/topics/test-01 ,删配置
rmr /admin/delete_topics,删除admin中的标记为删除的topics
最后删除真正的数据 rm -rf test-01-2 rm -rf test-01-*

修改分区数,不能修改分区数
bin/kafka-topics.sh --alter --zookeeper 192.168.163.128:2181,192.168.136.129:2181,192.168.136.130:2181 --partition 5 --topic test-03

六、API操作
启动生产者
bin/kafka-console-producer.sh --broker-list 192.168.136.128:9092,192.168.136.129:9092,192.168.136.130:9092 --topic test-03
启动消费者
kafka-console-consumer.sh --zookeeper 192.168.136.128:2181,192.168.136.129:2181,192.168.136.130:2181 --topic test-03 --from-beginning(代表从头消费,如果先启动生产者,在启动消费者之前就有生产,如果在启动消费者时使用 --form–beginning会 从头开始消费,如果不使用,则是在消费 消费者 启动之后 生产者生产的数据,如果有多个消费者且不再同一个组里面,那么会有多个消费者都实时监控生产者生产的数据)

Java API

import kafka.javaapi.producer.Producer;
import kafka.producer.KeyedMessage;
import kafka.producer.ProducerConfig;

import java.util.Properties;

public class Producer1day03 {
    public static void main(String[] args) {
        final Properties prop = new Properties();
                  //"metadata.broker.list"
        prop.put("metadata.broker.list","192.168.136.128:9092," +
                "192.168.136.129:9092," +
                "192.168.136.130:9092");
        prop.put("serializer.class","kafka.serializer.StringEncoder");
        ProducerConfig conf = new ProducerConfig(prop);
        Producer<String, String> producer = new Producer<>(conf);
        int i = 0;
        while (true){
            KeyedMessage<String, String> msg = new KeyedMessage<String, String>("test02","msg"+i);
            producer.send(new KeyedMessage<String,String>("test-03",
                    "msg"+i));
            i++;
        }

    }
}

消费者

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

public class Consumersday03 {
    private static final String topic ="test-03";
    private static final int threads = 2;
    public static void main(String[] args) {
        //配置属性
        final Properties prop = new Properties();
        prop.put("zookeeper.connect","192.168.136.128:2181," +
                "192.168.136.129:2181,192.168.136.130:2181"
                );
        //配置消费者组
        prop.put("group.id","kkk");
        //配置从头消费数据
        //prop.put("auto.offset.reset","smallset");
        //创建消费者
        final ConsumerConfig conf = new ConsumerConfig(prop);
        final ConsumerConnector connector = Consumer.createJavaConsumerConnector(conf);
        //创建Map,主要用来存储多个topic信息
        final HashMap<String, Integer> map = new HashMap<>();
        map.put(topic,threads);
        //创建获取信息流
        final Map<String, List<KafkaStream<byte[], byte[]>>> messageStreams =
                connector.createMessageStreams(map);

        //读取某一个
        final List<KafkaStream<byte[], byte[]>> kafkaStreams = messageStreams.get(topic);

        //循环接收Map内的topic数据
        for(KafkaStream<byte[], byte[]>  stream: kafkaStreams){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for(MessageAndMetadata<byte[], byte[]> m :stream){
                        String msg = new String(m.message());
                        System.out.println(msg);
                    }
                }
            }).start();
        }


    }
}

猜你喜欢

转载自blog.csdn.net/Lu_Xiao_Yue/article/details/83957929
今日推荐