087:Kafka-高可用集群环境kafka环境搭建
1 MQ服务器集群基本的概念
课程内容:
- kafka与其他MQ到底有不同?
- 如何理解kafka Partition与Topic
- 构建kafka集群环境
- SpringBoot整合kafka集群环境
Kafka消息中间件简介
Apache Kafka是一个分布式发布-订阅消息传递系统。
注意:Kafka并没有遵循JMS规范,它只提供了发布和订阅通讯方式。
kafka中文官网:http://kafka.apachecn.org/quickstart.html
2 kafka服务器常用相关名词
Kafka核心相关名称
Broker:节点,表示一个MQ服务器端,多个Broker就是表示多个不同的MQ服务器端形成一个群体;
Topic:主题,相当于目录,一个MQ服务端可以存放多个不同的主题,每个主题实际就是消息的分类;
massage:消息,异步通讯传递的参数;
Partition:分区,对大的群体实现分区。topic物理上的分组,一个topic可以分为多个partition,每个partition是一个有序的队列;
Kafka里面实现分区:一个Broker就是表示一个区域。
数据库中1000万条数据,分成10表,每张表存放100w条数据,类似redis中卡槽。
Segment:分片,partition物理上由多个segment组成,每个Segment存着message信息;
Producer:生产者,向MQ投递消息;
Consumer:消费者,订阅topic并消费message, consumer作为一个线程来消费;
Consumer Group:消费者组,对消费者实现分组,一个Consumer Group包含多个consumer;
Offset:偏移量,消息的索引位置,理解为消息partition中的索引即可;
主题和队列区别?
队列是一个数据结构,遵循先进先出原则;主题没有这个规范。
3 kafka集群节点如何实现相互感知
kafka集群节点动态相互感知
每个broker连接同一个zk地址,节点信息注册到同一个zk上,新broker从zk上感知老broker信息;
老broker监听zk,一旦有新的节点加入注册形成集群,发布事件通知到老broker上。
Kafka为什么会依赖于zk?
- kafka会将MQ的信息存放到zk上;
- 为了整个集群能够方便扩展,采用zk的事件通知相互感知;
4 kafka集群环境搭建方式实现
Kafka集群环境搭建
1.每台服务器上安装jdk1.8环境
2.安装Zookeeper集群环境
3.安装kafka集群环境
4.运行环境测试
安装jdk环境1.8
1.安装jdk
cd /usr/local
上传jdk1.8安装包并解压tar -zxvf jdkxxxx
mv jdkxxxx jdk1.8
2.修改jdk1.8环境变量vi /etc/profile,文件末尾添加以下内容
export JAVA_HOME=/usr/local/jdk1.8
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
刷新profile文件 source /etc/profile
查看java是否安装成功 java -version
Zookeeper集群环境
cd /usr/local
1. 解压安装包
tar -zxvf zookeeper-3.4.10.tar.gz
2. 重新命名
mv zookeeper-3.4.10 zookeeper
cd /usr/local/zookeeper/conf
mv zoo_sample.cfg zoo.cfg
3. 修改conf: vi zoo.cfg 修改两处
(1) dataDir=/usr/local/zookeeper/data(注意同时在zookeeper创建data目录)
(2)最后面添加
server.0=192.168.0.58:2888:3888
server.1=192.168.0.59:2888:3888
server.2=192.168.0.60:2888:3888
4. 每台zk服务器节点,创建服务器标识
cd /usr/local/zookeeper
mkdir data
cd /usr/local/zookeeper/data
创建文件myid并填写内容为0: vi myid (内容为服务器标识 : 0)
集群环境克隆服务器并修改myid
5. 关闭每台服务器节点防火墙,systemctl stop firewalld.service
启动Zookeeper
路径: cd /usr/local/zookeeper/bin
执行: ./zkServer.sh start
(注意这里3台机器都要进行启动)
状态: ./zkServer.sh status(在三个节点上检验zk的mode,一个leader和俩个follower)
Kafka集群搭建
cd /usr/local
tar -zxvf kafka_2.11-1.0.0.tgz
mv kafka_2.12-0.11.0.0 kafka
cd /usr/local/kafka/config
vi server.properties
broker.id=0
listeners=PLAINTEXT://192.168.0.58:9092
zookeeper.connect=192.168.0.58:2181,192.168.0.59:2181,192.168.0.60:2181
6 搭建Kafka集群方式实现通讯
Kafka集群环境测试
1、开启3台虚拟机的zookeeper程序
/usr/local/zookeeper/bin/zkServer.sh start
开启成功后查看zookeeper集群的状态
/usr/local/zookeeper/bin/zkServer.sh status
出现Mode:follower或是Mode:leader则代表成功
2、在后台开启3台虚拟机的kafka程序(cd /usr/local/kafka)
./bin/kafka-server-start.sh -daemon config/server.properties
3、在其中一台虚拟机(192.168.0.58)创建topic
/usr/local/kafka/bin/kafka-topics.sh --create –zookeeper 192.168.0.58:2181 –replication-factor 3 –partitions 1 –topic my-replicated-topic
// 查看创建的topic信息
/usr/local/kafka/bin/kafka-topics.sh –describe –zookeeper 192.168.0.58:2181 –topic my-replicated-topic
详细参照官网即可
http://kafka.apachecn.org/quickstart.html
Kafka集群效果
7 kafka集群实现分区存放不同节点
cd /usr/local/kafka
bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 3 --topic mayikt
数据均摊分配到3个节点中。
8 SpringBoot如何整合kafka集群
引入依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
</parent>
<dependencies>
<!-- springBoot集成kafka -->
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
<!-- SpringBoot整合Web组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
application.yml
# kafka
spring:
kafka:
# kafka服务器地址(可以多个)
bootstrap-servers: 192.168.0.58:9092,192.168.0.59:9092,192.168.0.60:9092
consumer:
# 指定一个默认的组名
group-id: kafka2
# earliest:当各分区下有已提交的offset时,从提交的offset开始消费;无提交的offset时,从头开始消费
# latest:当各分区下有已提交的offset时,从提交的offset开始消费;无提交的offset时,消费新产生的该分区下的数据
# none:topic各分区都存在已提交的offset时,从offset后开始消费;只要有一个分区不存在已提交的offset,则抛出异常
auto-offset-reset: earliest
# key/value的反序列化
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
producer:
# key/value的序列化
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.apache.kafka.common.serialization.StringSerializer
# 批量抓取
batch-size: 65536
# 缓存容量
buffer-memory: 524288
# 服务器地址
bootstrap-servers: 192.168.0.58:9092,192.168.0.59:9092,192.168.0.60:9092
KafkaController
@RestController
@SpringBootApplication
public class KafkaController {
/**
* 注入kafkaTemplate
*/
@Autowired
private KafkaTemplate<String, String> kafkaTemplate;
/**
* 发送消息的方法
*
* @param key
* 推送数据的key
* @param data
* 推送数据的data
*/
private void send(String key, String data) {
// topic 名称 key data 消息数据
kafkaTemplate.send("mayikt", key, data);
}
// test 主题 1 my_test 3
@RequestMapping("/kafka")
public String testKafka() {
int iMax = 6;
for (int i = 1; i < iMax; i++) {
send("key" + i, "data" + i);
}
return "success";
}
public static void main(String[] args) {
SpringApplication.run(KafkaController.class, args);
}
/**
* 消费者使用日志打印消息
*/
@KafkaListener(topics = "mayikt")
public void receive(ConsumerRecord<?, ?> consumer) {
System.out.println("topic名称:" + consumer.topic() + ",key:" +
consumer.key() + "," +
"分区位置:" + consumer.partition()
+ ", 下标" + consumer.offset());
}
}
运行结果: