概述
Kafka是一个开源的分布式事件流平台(Event Streaming Platform),被数千家公司用于高性能数据管道、流分析、数据集成和关键任务应用。
- Producer :消息生产者,就是向 kafka broker 发消息的客户端。
- Consumer :消息消费者,向 kafka broker 取消息的客户端。
- Consumer Group (CG):消费者组,由多个 consumer 组成。消费者组内每个消费者负责消费不同分区的数据,一个分区只能由一个组内消费者消费;消费者组之间互不影响。所有的消费者都属于某个消费者组,即消费者组是逻辑上的一个订阅者。
- Broker :一台 kafka 服务器就是一个 broker。一个集群由多个 broker 组成。一个 broker 可以容纳多个topic。
- Topic :可以理解为一个队列,生产者和消费者面向的都是一个 topic。
- Partition:为了实现扩展性,一个非常大的 topic 可以分布到多个broker(即服务器)上,一个 topic 可以分为多个 partition,每个 partition 是一个有序的队列。
- Replica:副本,为保证集群中的某个节点发生故障时,该节点上的 partition 数据不丢失, 且kafka 仍然能够继续工作,kafka 提供了副本机制,一个 topic 的每个分区都有若干个副本,一个 leader 和若干个 follower。
- leader:每个分区多个副本的“主”,生产者发送数据的对象,以及消费者消费数据的对 象都是 leader。
- follower:每个分区多个副本中的“从”,实时从 leader 中同步数据,保持和 leader 数据的同步。leader 发生故障时,某个 follower 会成为新的 follower。
集群部署
安装kafka之前一定要先安装好zookeeper:大数据实训笔记6:zookeeper
将下载好的kafka安装包上传到hadoop101 /opt/software/ 并解压。
//解压
[hadoop@hadoop101 software]$ tar -zxvf kafka_2.12-3.0.1.tgz -C /opt/module/
//进入kafka_2.12-3.0.1文件夹
[hadoop@hadoop101 software]$ cd /opt/module/kafka_2.12-3.0.1/
//配置kafka环境变量
[hadoop@hadoop101 kafka_2.12-3.0.1]$ sudo vim /etc/profile.d/my_env.sh
##KAFKA_HOME
export KAFKA_HOME=/opt/module/kafka_2.12-3.0.1
export PATH=$PATH:$KAFKA_HOME/bin
//刷新
[hadoop@hadoop101 kafka_2.12-3.0.1]$ source /etc/profile
//测试环境变量是否配置成功
[hadoop@hadoop101 kafka_2.12-3.0.1]$ echo $KAFKA_HOME
//分发环境变量
[hadoop@hadoop101 module]$ sudo /home/hadoop/bin/xsync /etc/profile.d/my_env.sh
//创建logs日志文件夹
[hadoop@hadoop101 kafka_2.12-3.0.1]$ mkdir logs
//修改配置文件server.properties
[hadoop@hadoop101 kafka_2.12-3.0.1]$ cd config/
[hadoop@hadoop101 config]$ vim server.properties
找到相应的地方并根据自己的情况修改,注意不要有空格!
broker.id=0
log.dirs=/opt/module/kafka_2.12-3.0.1/logs
zookeeper.connect=hadoop101:2181,hadoop102:2181,hadoop103:2181/kafka
//分发
[hadoop@hadoop101 kafka_2.12-3.0.1]$ cd /opt/module/
[hadoop@hadoop101 module]$ xsync kafka_2.12-3.0.1/
分发成功后,分别修改hadoop102, hadoop103的broker.id为1和2。
集群的启动和停止
在启动kafka之前,一定要先启动zookeeper。
在三台客户机下分别执行下列命令:
//启动
[hadoop@hadoop101 kafka_2.12-3.0.1]$ bin/kafka-server-start.sh -daemon config/server.properties
//停止
[hadoop@hadoop101 kafka_2.12-3.0.1]$ bin/kafka-server-stop.sh
同样的,我们可以编写脚本kk.sh,方便集群的启动和停止。
[hadoop@hadoop101 kafka_2.12-3.0.1]$ cd ~
[hadoop@hadoop101 ~]$ cd bin/
[hadoop@hadoop101 bin]$ sudo vim kk.sh
#!/bin/bash
case $1 in
"start"){
for i in hadoop101 hadoop102 hadoop103
do
echo "*************$i***************"
ssh $i "source /etc/profile && $KAFKA_HOME/bin/kafka-server-start.sh -daemon $KAFKA_HOME/config/server.properties"
echo $?
done
};;
"stop"){
for i in hadoop101 hadoop102 hadoop103
do
echo "*************$i***************"
ssh $i "source /etc/profile && $KAFKA_HOME/bin/kafka-server-stop.sh $KAFKA_HOME/config/server.properties"
echo $?
done
};;
esac
//修改权限
[hadoop@hadoop101 bin]$ sudo chmod 777 kk.sh
//分发
[hadoop@hadoop101 ~]$ xsync bin/
//启动
[hadoop@hadoop101 bin]$ kk.sh start
//停止
[hadoop@hadoop101 bin]$ kk.sh stop
命令操作
//查看当前服务器中所有topic
[hadoop@hadoop101 kafka_2.12-3.0.1]$ bin/kafka-topics.sh --bootstrap-server hadoop101:9092 --list
//创建first topic
[hadoop@hadoop101 kafka_2.12-3.0.1]$ bin/kafka-topics.sh --bootstrap-server hadoop101:9092 --topic first --create --partitions 2 --replication-factor 2
//查看first topic的详情
[hadoop@hadoop101 kafka_2.12-3.0.1]$ bin/kafka-topics.sh --bootstrap-server hadoop101:9092 --topic first --describe
//修改first topic分区数为3
[hadoop@hadoop101 kafka_2.12-3.0.1]$ bin/kafka-topics.sh --bootstrap-server hadoop101:9092 --topic first --alter --partitions 3
//删除first topic
[hadoop@hadoop101 kafka_2.12-3.0.1]$ bin/kafka-topics.sh --bootstrap-server hadoop101:9092 --topic first --delete
接下来我们在三台客户机上操作生产者和消费者。
//hadoop102作为生产者
[hadoop@hadoop102 kafka_2.12-3.0.1]$ bin/kafka-console-producer.sh --bootstrap-server hadoop102:9092 --topic first
//hadoop101作为消费者
[hadoop@hadoop101 kafka_2.12-3.0.1]$ bin/kafka-console-consumer.sh --bootstrap-server hadoop101:9092 --topic first
//hadoop103作为消费者,并且接收从一开始的历史消息
[hadoop@hadoop103 kafka_2.12-3.0.1]$ bin/kafka-console-consumer.sh --bootstrap-server hadoop103:9092 --topic first --from-beginning
API应用
生产者生产消息,消费者接收消息,这个功能我们还可以通过变成实现。
环境准备
创建maven工程kafka_demo,并导入依赖。
<!-- 自定义属性设置版本号 -->
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>3.0.1</version>
</dependency>
</dependencies>
代码实现
//生产者
public class Producer {
public static void main(String[] args) {
//指定配置Properties
Properties properties = new Properties();
properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "hadoop101:9092,hadoop102:9092,hadoop103:9092");
properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
//创建生产者对象
KafkaProducer<String, String> producer = new KafkaProducer<String, String>(properties);
//发送消息
for(int i=0; i<10; i++) {
producer.send(new ProducerRecord<>("mytopic", i+":", "Hello world!"));
}
//释放资源
producer.close();
}
}
//消费者
public class Consumer {
public static void main(String[] args) {
//指定配置properties
Properties properties = new Properties();
properties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "hadoop101:9092,hadoop102:9092,hadoop103:9092");
properties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");
properties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");
properties.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, true); //自动提交
properties.put(ConsumerConfig.GROUP_ID_CONFIG, "bigdata"); //消费者组
//创建消费者对象
KafkaConsumer<String, String> consumer = new KafkaConsumer<String, String>(properties);
//订阅主题
ArrayList<String> topics = new ArrayList<>();
topics.add("mytopic");
consumer.subscribe(topics);
//获取数据
while(true) {
//拉取
ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));
//打印
for(ConsumerRecord<String, String> record: records) {
System.out.println(record.key() + "----" + record.value());
}
consumer.commitAsync((map, e)->{
if(e!=null) {
System.out.println(map + "自动提交失败");
}
});
}
}
}
执行效果
执行之前一定要确保代码中的topic已经在kafka上创建好了。
先执行Consumer,再执行Producer,在Consumer命令行中能接收到Producer发出的消息。
在kafka上执行下列命令,也能接收到历史消息。
[hadoop@hadoop101 kafka_2.12-3.0.1]$ bin/kafka-console-consumer.sh --bootstrap-server hadoop101:9092 --topic mytopic --from-beginning