Kafka学习笔记

一、Kafka简介

1.1、Kafka概念

Kafka是一个分布式消息系统,由linkedin使用scala编写,用作LinkedIn的活动流和运营数据处理管道的基础。具有高水平扩展和高吞吐量。

1.2、使用场景

1)作为常规的消息系统,Kafka是个不错的选择,可以使Kafka具有良好的扩展性和性能优势,到目前为止,Kafka并没有提供JMS中的"事务性"消息传输担保(消息确认机制),“消息分组"等企业级特性;Kafka只能使用作为"常规"的消息系统,在一定程度上,尚未确保消息的发送与接收绝对可靠(比如,消息重发,消息发送丢失等),如果需要支持消息的事务性,可以考虑RocketMQ或者RabbitMQ等。
2)Kafka的特性决定它非常适合作为"日志收集中心”;程序可以将操作日志"批量"、"异步"的发送到Kafka集群中,而不是保存在本地或者DB中;Kafka可以批量提交消息/压缩消息等,这对Producer端而言,几乎感觉不到性能的开支.此时Consumer端可以使Hadoop等其他系统化的存储和分析系统。
3)Kafka可以作为"网站活性跟踪"的最佳工具;可以将网页/用户操作等信息发送到Kafka中.并实时监控,或者离线统计分析等。

1.3、Kafka入门

Kafka是一种高吞吐量的分布式消息系统,它提供了类似于JMS的特性,但是在实现上完全不同,它并不是JMS规范的实现。Kafka对消息保存时根据Topic进行归类,发送消息者成为Producer,消息接受者成为Consumer,Kafka集群有多个Kafka实例组成,每个实例成为Broker。无论是Kafka集群,还是Producer和Consumer都依赖于Zookeeper来保证系统可用性。

1.3.1、producer:生产者,即消息的产生端。

1.3.2、Consumer:消费者,即消息的消费端。

imagepng

1.3.3、Topic:一个Topic可以认为是一类消息,一个Topic类似新闻中的体育、娱乐、教育等分类概念,在实际工程中通常一个业务一个主题,消费者可以只关注自己需要的Topic中的消息。

1.3.4、Partition:一个Topic中的消息数据按照多个分区组织,分区是Kafka消息队列组织的最小单位,一个分区可以看作是一个FIFO(先入先出)的队列。Kafka分区是提高Kafka性能的关键所在,当你发现你的集群性能不高时,常用手段就是增加Topic的分区,分区里面的消息是按照从新到老的顺序进行组织,消费者从队列头订阅消息,生产者从队列尾添加消息。

imagepng

1.3.5、Broker:以集群的方式运行,可以由一个或多个服务组成,每个服务叫做一个Broker;消费者可以订阅一个或多个主题(Topic),并从Broker拉数据,从而消费这些已发布的消息。

1.3.6、Replication:为了保证分布式可靠性,Kafka对每个分区的数据进行备份(不同的Broker上),防止其中一个Broker宕机造成分区上的数据不可用。

imagepng

1.3.7、Kafka与其他消息队列的比较

imagepng

二、Kafka集群搭建

下面介绍Kafka集群部署的步骤,Kafka的安装需要java环境,Kafka集群是把状态保存在Zookeeper中的,所以首先安装JDK和搭建Zookeeper集群。

环境

  |     服务器    |
  | 10.211.55.10 |
  | 10.211.55.11 |
  | 10.211.55.12 |

软件版本

JDK 1.8
Kafka_2.1.0
Zookeeper-3.4.13

2.1、JDK的安装

在三台机器都安装配置好java环境。
JDK的下载地址:https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
解压JDK压缩包到:/usr/local/,重命名为jdk1.8,jdk的完整路径就是:/usr/local/jdk1.8
配置JDK环境变量:

vi /etc/profile 

export JAVA_HOME=/usr/local/jdk1.8 
export PATH=${JAVA_HOME}/bin:$PATH  

source /etc/profile

2.2、Zookeeper集群搭建

Zookeeper的安装需要在三台机器都进行安装。

目录规划
Zookeeper程序目录:/usr/local/zookeeper/zookeeper-3.4.13/
Zookeeper的DataDir目录:/usr/local/zookeeper/data/
Zookeeper的dataLogDir目录:/usr/local/zookeeper/log/

Zookeeper下载地址:http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.13/zookeeper-3.4.13.tar.gz

配置zoo.cfg
在zookeeper-3.4.13/conf目录里,重命名zoo_sample.cfg为zoo.cfg

vi zoo.cfg

#服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个tickTime时间就会发送一个心跳。tickTime以毫秒为单位。
tickTime=2000
#集群中的follower服务器(F)与leader服务器(L)之间初始连接时能容忍的最多心跳数(tickTime的数量)。
initLimit=10
#集群中的follower服务器与leader服务器之间请求和应答之间能容忍的最多心跳数(tickTime的数量)。
syncLimit=5
#数据文件目录
dataDir=/usr/local/zookeeper/data
#快照日志的存储路径
dataLogDir=/usr/local/zookeeper/log
#客户端连接 Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。
clientPort=12181

#服务器名称与地址:集群信息(服务器编号,服务器地址,LF通信端口,选举端口)
server.1=10.211.55.10:12888:13888
server.2=10.211.55.11:12888:13888
server.3=10.211.55.12:12888:13888

创建myid文件
myid文件就是在dataDir目录下创建一个文件名为myid的文件,myid文件和server.myid在快照目录下存放的标识本台服务器的文件,他是整个zk集群用来发现彼此的一个重要标识。里面的内容就是写上上面对应的server.N,这个N就是对应的1、2、3的数字,对应的是哪台服务器的意思,比如服务器10.211.55.10,可以在myid文件写上1,10.211.55.11的myid文件写上2,10.211.55.12的myid文件写上3。

启动Zookeeper服务
在zookeeper-3.4.13/bin目录下执行启动服务命令:

./zkServer.sh start

在其他节点都执行同样的启动命令,然后输入命令查看服务状态:

./zkServer.sh status

会看到:

ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/zookeeper-3.4.13/bin/../conf/zoo.cfg
Mode: follower

看到这个服务是运行中,说明是从节点,如果是Leader,说明是主节点。

2.3、Kafka集群搭建

Kafka的安装也同样需要在三台机器操作。

目录规划
kafka log的目录:/usr/local/kafka/data
kafka程序的目录:/usr/local/kafka/kafka-2.1.0
下载kafka地址:https://www.apache.org/dyn/closer.cgi?path=/kafka/2.1.0/kafka_2.12-2.1.0.tgz

修改配置文件
kafka-2.1.0/config/server.properties

vi kafka-2.1.0/config/server.properties


# 当前机器在集群中的唯一标识,和myid一样的性质,不同的节点修改不同的id
broker.id=1
#监听的IP和端口,端口默认是9092
listeners = PLAINTEXT://10.211.55.10:9092

num.network.threads=3

num.io.threads=8

socket.send.buffer.bytes=102400

socket.receive.buffer.bytes=102400

socket.request.max.bytes=104857600

#log目录
log.dirs=/usr/local/kafka/data

num.partitions=1

num.recovery.threads.per.data.dir=1

offsets.topic.replication.factor=1
transaction.state.log.replication.factor=1
transaction.state.log.min.isr=1
log.retention.hours=168
log.segment.bytes=1073741824
log.retention.check.interval.ms=300000
#Zookeeper集群的地址
zookeeper.connect=10.211.55.10:12181,10.211.55.11:12181,10.211.55.12:12181
zookeeper.connection.timeout.ms=6000
group.initial.rebalance.delay.ms=0

其他主机将该机器的Kafka目录拷贝即可,然后需要修改broker.id、listeners地址。

启动Kafka
在三台机分别都执行以下命令:

setsid kafka-2.1.0/bin/kafka-server-start.sh ../config/server.properties

验证Kafka服务
在随便一台机器执行Topic的创建命令:

kafka-2.1.0/bin/kafka-topics.sh --create --zookeeper 10.211.55.10:12181,10.211.55.11:12181,10.211.55.12:12181 --replication-factor 1 --partitions 1 --topic calonTest

这样,一个名为calonTest的Topic就创建好了,在另外一台机器查询一下这个Topic是否存在:

kafka-2.1.0/bin/kafka-topics.sh --list --zookeeper 10.211.55.10:12181,10.211.55.11:12181,10.211.55.12:12181

这个时候发现calonTest的Tpoic可以被查询出来,说明整个集群是OK的。

三、Springboot整合Kafka

上面都是服务的搭建过程,下面使用Springboot集成Kafka进行一些简单的测试。

创建一个Springboot项目,添加依赖:

<dependencies>
  <dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
	<groupId>org.springframework.kafka</groupId>
	<artifactId>spring-kafka</artifactId>
  </dependency>
  <dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-test</artifactId>
	<scope>test</scope>
  </dependency>
  <dependency>
	<groupId>org.springframework.kafka</groupId>
	<artifactId>spring-kafka-test</artifactId>
	<scope>test</scope>
  </dependency>
</dependencies>

配置Kafka的链接信息application.properties:

spring.kafka.bootstrap-servers=10.211.55.10:9092,10.211.55.11:9092,10.211.55.12:9092

spring.kafka.producer.retries=0
spring.kafka.producer.batch-size=4096
spring.kafka.producer.buffer-memory=40960

spring.kafka.consumer.group-id=Calon
spring.kafka.consumer.enable-auto-commit=true
spring.kafka.consumer.auto-commit-interval=100
spring.kafka.consumer.key-serializer=org.apache.kafka.common.serialization.StringDeserializer
spring.kafka.consumer.value-serializer=org.apache.kafka.common.serialization.StringDeserializer
spring.kafka.consumer.auto-offset-reset=earliest

建一个消息生产者类CalonConsumer.java:

import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Service;

@Service
public class CalonConsumer {
    @KafkaListener(topics = "CalonTopic")
    public void listen(ConsumerRecord, ?> record) throws Exception {
        System.out.println("接收到消息:"+record);
  System.out.printf("topic = %s, offset = %s, value = %s \n", record.topic(), record.key(), record.value());
  }
}

建一个消息消费者类CalonProducer.java:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class CalonProducer {

    @Autowired
  private KafkaTemplate kafkaTemplate;

  @RequestMapping(value = "/send", method = RequestMethod.GET)
    public String sendKafka(@RequestParam("message") String message) {
        try {
            System.out.println("kafka的消息=" + message);
  kafkaTemplate.send("CalonTopic","CalonKey",message);
  System.out.println("发送kafka成功.");
 return "successs";
  } catch (Exception e) {
            e.printStackTrace();
 return "failure";
  }
    }

}

启动项目,访问:http://localhost:8080/send?message=HelloCalon
后台会受到消息的打印:

发送kafka成功.
接收到消息:ConsumerRecord(topic = CalonTopic, partition = 0, offset = 1, CreateTime = 1545558001477, serialized key size = 8, serialized value size = 11, headers = RecordHeaders(headers = [], isReadOnly = false), key = CalonKey, value = HelloCalon)
topic = CalonTopic, offset = CalonKey, value = HelloCalon 

好了,到此结束。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值