Java操作kafka

来源:互联网 发布:伊藤润二渊小姐知乎 编辑:程序博客网 时间:2024/06/06 01:24

1、基本概念--消息发布与订阅

消息的发布(publish)称做producer。

消息的订阅(subscribe)称做consumer。

中间的存储阵列称做broker。

多个broker协同合作,producer、consumer和broker三者之间通过zookeeper来协调请求和转发。

producer产生和推送(push)数据到broker,consumer从broker拉取(pull)数据并进行处理。

kafka服务:

Topic:主题,Kafka处理的消息的不同分类。
Broker:消息的代理,Kafka集群中的一个kafka服务节点称为一个broker,主要存储消息数据。存在硬盘中。每个topic都是有分区的。
Partition:Topic物理上的分组,一个topic在broker中被分为1个或者多个partition,分区在创建topic的时候指定。
Message:消息,是通信的基本单位,每个消息都属于一个partition。

kafka服务相关:
Producer:消息和数据的生产者,向Kafka的一个topic发布消息。
Consumer:消息和数据的消费者,订阅topic并处理其发布的消息。
zookeeper:协调kafka的正常运行。
作用:
消息队列的应用在传统的业务中使用高吞吐、分布式、使得处理大量业务内容轻松自如。
互联网行业的日志行为实时分析,比如:实时统计用户浏览页面、搜索及其他行为,结合实时处理框架使用实现实时监控,或放到 hadoop/离线数据仓库里处理。
一种为外部的持久性日志的分布式系统提供服务。主要利用节点间备份数据,文件存储、日志压缩等功能


2、基本操作

启动服务

首先启动zookeeper服务
bin/zookeeper-server-start.sh config/zookeeper.properties

或者zkServer.sh

启动Kafka
bin/kafka-server-start.sh config/server.properties >/dev/null 2>&1 &

或者
./kafka-server-start.sh /usr/local/kafka/kafka_2.11-0.10.1.1/config/server.properties 
ps aux|grep kafka jps


创建topic
创建一个"test"的topic,一个分区一个副本
bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test
查看主题
bin/kafka-topics.sh --list --zookeeper localhost:2181
查看主题详情
bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic test
删除主题
bin/kafka-topics.sh --zookeeper localhost:2181 --delete --topic test


创建生产者 producer
bin/kafka-console-producer.sh --broker-list localhost:9092 --topic test 
/usr/hdp/2.4.*/kafka/bin/kafka-console-producer.sh --broker-list node1:6667,node2:6667,node3:6667 --topic threadtest
创建消费者 consumer
bin/kafka-console-consumer.sh --zookeeper localhost:2181 --topic test --from-beginning
/usr/hdp/2.4.3.0-227/kafka/bin/kafka-console-consumer.sh --zookeeper node1:2181,node2:2181,node3:2181 --topic threadtest


生产者参数查看:bin/kafka-console-producer.sh

消费者参数查看:bin/kafka-console-consumer.sh

3、编写JAVA程序

消费者

import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Properties;import kafka.consumer.ConsumerConfig;import kafka.consumer.ConsumerIterator;import kafka.consumer.KafkaStream;import kafka.javaapi.consumer.ConsumerConnector;public class my_Consumertest extends Thread{    private final ConsumerConnector consumer;    private final String topic;    public static void main(String[] args) {      my_Consumertest consumerThread = new my_Consumertest("threadtest");      System.out.println("consumerThread :"+consumerThread); //Thread[Thread-0,5,main]      consumerThread.start();    }    public my_Consumertest(String topic) {        consumer =kafka.consumer.Consumer.createJavaConsumerConnector(createConsumerConfig());        this.topic =topic;    }private static ConsumerConfig createConsumerConfig() {    Properties props = new Properties();    // 设置zookeeper的链接地址    props.put("zookeeper.connect", "192.168.3.50:2181,192.168.3.51:2181,192.168.3.52:2181");    // 设置group id    props.put("group.id", "1");    // kafka的group 消费记录是保存在zookeeper上的, 但这个信息在zookeeper上不是实时更新的, 需要有个间隔时间更新    props.put("auto.commit.interval.ms", "1000");    props.put("zookeeper.session.timeout.ms","400");    return new ConsumerConfig(props);}@Overridepublic void run(){     //设置Topic=>Thread Num映射关系, 构建具体的流    Map<String,Integer> topickMap = new HashMap<String, Integer>();    topickMap.put(topic, 1);    System.out.println("topickMap  "+topickMap);    //{threadtest=1}    Map<String, List<KafkaStream<byte[],byte[]>>>  streamMap=consumer.createMessageStreams(topickMap);    KafkaStream<byte[],byte[]> stream = streamMap.get(topic).get(0);    ConsumerIterator<byte[],byte[]> it =stream.iterator();    System.out.println("*********Results********");    while(it.hasNext()){        System.err.println("get data:" +new String(it.next().message()));        try {            Thread.sleep(1000);        } catch (InterruptedException e) {            e.printStackTrace();        }    }}}

生产者

import java.util.Date;import java.util.Properties;import java.text.SimpleDateFormat;import kafka.javaapi.producer.Producer;import kafka.producer.KeyedMessage;import kafka.producer.ProducerConfig;public class my_producer {     public static void main(String[] args) {         Properties props = new Properties();         props.put("zookeeper.connect", "192.168.3.50:2181,192.168.3.51:2181,192.168.3.52:2181");      // serializer.class为消息的序列化类         props.put("serializer.class", "kafka.serializer.StringEncoder");         props.put("metadata.broker.list", "192.168.3.50:6667,192.168.3.51:6667,192.168.3.52:6667");         props.put("num.partitions", "6");         ProducerConfig config = new ProducerConfig(props);         Producer<String, String> producer = new Producer<String, String>(config);         for (int i = 0; i < 10; i++)         {           SimpleDateFormat formatter = new SimpleDateFormat   ("yyyy年MM月dd日 HH:mm:ss SSS");           Date curDate = new Date(System.currentTimeMillis());//获取当前时间           String str = formatter.format(curDate);           String msg = "produce " + i+"="+str;           String key = i+"";           //如果没有key默认随机随机分区           producer.send(new KeyedMessage<String, String>("threadtest", key, msg));         }       }}
可以在通过java代码实现kafka之间的通信,也可以实现java代码与控制台之间的通信

例如:接收

/usr/hdp/2.4.3.0-227/kafka/bin/kafka-console-consumer.sh --zookeeper node1:2181,node2:2181,node3:2181 --topic bds_data

发送

/usr/hdp/2.4.*/kafka/bin/kafka-console-producer.sh --broker-list node1:6667,node2:6667,node3:6667 --topic threadtest

附:Demo下载地址

http://download.csdn.net/download/qq_31780525/9931062