Kafka学习笔记-- 1 入门知识和使用场景

目录

 

1 Kafka入门

1.1 主流mq框架对比

1.2 kafka主要特性

1.3 AMQP协议

1.4 Kafka整体架构

1.5 核心概念

broker

topic

partition

record

replication

1.6 kafaka  核心API

概述

producer

consumer

3 consumer的commit offset

4 consumer的数据获取方式

2 kafka使用场景

2.1 消息系统

2.2 存储系统

2.3 日志聚合

2.4 跟踪网站活动(其实就是埋点)

2.5 流处理


1 Kafka入门

1.1 主流mq框架对比

主流mq组件对比
  ActiveMQ   RabbitMQ Kafka 
吞吐量 1w 1w 10w
支持的协议 OpenMessage, AMQP, MQTT, STOMP AMQP 仿AMQP
事务 支持 支持 支持
集群 支持(不良好) 支持(不良好) 支持
负载均衡 支持 支持 支持
动态扩展 不支持 不支持 支持
编写语言 Java Erlang Scala

这三个MQ组件中, ActiveMQ的功能最丰富, 支持的协议最多。 吞吐量上, 一般情况下Kafka > RabbitMQ > ActiveMQ; 可靠性上, 一般情况下RabbitMQ > ActiveMQ > Kafka。

动态扩展, 是指可以向运行中的集群添加新的节点, 而不影响已有节点的使用。 之所以说ActiveMQ对集群的支持不良好, 其中一个原因是 ActiveMQ的节点只能是主从模式, 只有再master节点上才可以发布和消费消息, 这样的话对并发量的提升相对较弱。

1.2 kafka主要特性

消息系统: 可以发布和订阅消息, 类似于消息队列或企业级消息系统。

存储: 提供容错的方式来存储流数据。 存储在kafka中的数据, 都会落到磁盘上, 只要不手动删除, 将一直存在, 不像其他消息中间件, 当消息消费后, 会对消息进行删除。

流处理: 可以在一个流的数据产生时, 就对它进行处理, 即流处理。这个特性是kafka的streams api来支持的,需要在客户端上编码, 实质上是读取现有的流数据, 将处理的结果推到结果的流上。 但主流的还是采用fink, storm sreams, spark等批处理框架来进行流处理。 kafka更多的是充当一个流数据的存储角色。

总的来说, Kafka不仅仅是一个消息系统, 还是一个数据存储。

 

1.3 AMQP协议

AMQP是由金融业的摩根大通公司主导制定的消息协议, 是一个应用层的协议。 

在Kafka中, 生产者push,消费者poll,都是客户端主动发起数据请求。kafka都是以多个broker集群的方式对外提供服务。

1.4 Kafka整体架构

1.5 核心概念

broker

一个Kafka示例, 一般情况下, Kafka都是以集群的方式部署的。

topic

消息的一种分类, 一个主题的消息可以视为一个数据流。主题中的消息不一定按照发布的顺序消费。

partition

一个主题可以分为多个partition,每一个partition都是顺序存储在磁盘的。 每个partition的消息有自己的id,  对于消费者, partion有自己对应的commit offset。partition的意义: 其一, 如果通过将一个主题分隔成多个partition, 部署到多个broker上来提升io的速度, 甚至通过这种方式, 获得和内存相近的吞吐量; 其二, partition可以分布在多个broker上, 可以避免一次性丢失所有数据的情况。

partition中的消息是会按照发布的顺序消费的。 

record

每条记录都有key, value和timestamp三个数据。 其中具有相同key的消息, 可以保证落到同一个partition中。 

replication

每一个partition可以有多个副本, 副本分布在不同的broker上, 通过这种冗余, 可以保证数据的安全性, 只要不是所有的副本都丢失, 那么partition中的数据就是安全的。 副本的数量(replication-factor)不能超过broker的数量, 因为将同样的副本存在同一台机器上, 对于数据安全性,没有作用。 

replication

replication有一下的特性:

  • 同一个partition的多个replication不允许在同一个broker中;(在配置中, replication-factor不能超过broker的数量)
  • 同一个parition的多个replication中, 有一个leader, 0个或多个follower;
  • 消息的读写只能发生在leader节点上, follower只是被动的复制;
  • 当leader节点宕机时, 集群会选举出新的leader节点;

 

注意: 这里的leader和follower是replication级别的, Kafka的broker节点之间没有主次之分, 它们是完全同等的。 

 

1.6 kafaka  核心API

概述

  • producer, 向topic发布消息的应用。
  • consumer, 从broker中接收消息, 进行处理的应用。
  • streams api, 一个流处理的api, 从一个或多个主题接收消息,进行处理后, 将处理结果放到一个或多个主题中。
  • connector, 可重用的producer或consumer。 用于将已有系统, 如数据库等的数据集成到kafka上。 

这四种API, 用来构建四种类型的Kafka客户端, 如下:

Kafka学习笔记-- 1 入门知识和使用场景_第1张图片

 

producer

使用代码示例:

// 设置producer的配置
Properties settings = new Properties();
settings.put("batch.size", 16 * 1024); // 缓冲区大小, 默认16k
settings.put("linger.ms", 1000); // 发送前, 等待的时间, 默认为0
settings.put("acks", "all"); // 多少个broker 确认才认为成功。 0, 
settings.put("retries", 1 ); // 重试的次数

....

Producer producer = new KafkaProducer(settings);
// 发送消息
ProducerRecord record = new ProducerRecord<>("my-topic", "key", "value");
producer.send(record);

producer.close();

producer发送消息时, 并不是直接发送到broker中的, 而是先放在本地内存中的一个缓冲区,当缓冲区大小达到最大大小或缓冲区中的消息达到停留时间时, 才进行发送。 如下:

Kafka学习笔记-- 1 入门知识和使用场景_第2张图片

producer有三个重要的配置:

  • batch.size:  缓冲区大小, 默认16k
  • linger.ms: 发送前, 等待的时间, 默认为0
  • acks: 多少个broker 确认才认为消息发布成功, 可选值为0, 1, all。 0, 是发送之后就认为是成功了, 不去考虑这个消息是否交付到kafka中; 1, 当leader节点确认成功, 就认为已经成功的交付到kafka中了, 这种情况下, 如果leader节点宕机, 而又没有来得即将消息同步到follower上, 那么就会出现消息丢失; all, 只有当所有的broker都ack之后, 才认为一个消息发送成功。 

一旦达到batch.size或linger.ms其中一个条件, 缓冲区的消息就会被立刻发送。 

 

consumer

1 simple consumer API

每次消费消息时, 都需要提供topic, partition, offset, feichSize等四个参数, 不提供负载均衡和容错的特性。 

非常基础, 但是基于可以定义实现所有的功能。 

2 high level consumer API

消费时只需要指定topic, 客户端透明地切换consumer的partition, 实现consumer group级别的负载均衡。 如下图:

Kafka学习笔记-- 1 入门知识和使用场景_第3张图片

 

consumer group有如下的特性:

  • 一个topic可以有多个consumer group,  每一个consumer group都可以接收到所有的topic中的数据。 
  • consumer group中可以有一个或多个consumer, 每个consumer处理主题中的一个或多个partition。 
  • 一个group中的一个partition只能被一个consumer处理。

 

可以通过consumer group来实现队列和广播:

  • 队列: 当所有的消费者都在一个group中时, 那么每个消息都只会被消费一次。
  • 广播(主题): 当所有的消费者都分属不同的消费者, 那么每个消费者都会接收到topic中的所有消息。

 

consumer 什么时候会退出group?

  • consumer在很长的一段时间内没有心跳时;
  • 当consumer很久没有poll数据时;


3 consumer的commit offset

consumer可以通过commit, 来告诉服务器, 当前已经消费了的消息, 当consumer因为某种原因重启时, 会从最新提交的offset的下一个消息开始消费。 默认的情况下, Consumer是自动提交的, 每当poll数据时, 就会提交上一条数据。 

除了这个存在kafka的commit offset, 还有一个consumer自己持有的offset, 来指向下一个消息。

 

4 consumer的数据获取方式

kafka中,消费者是只能通过主动poll的方式来获取数据的。 

push和poll两种方式的难点:

  • push, 难点是请求的压力可能落到consumer上: 消息队列可能无法起到缓冲区的作用, 无法进行削峰(这是在消息中间件服务端完全不做控制的情况);
  • poll, 难点是poll时间间隔的取舍, 隔一段时间去获取一次数据, 这个时间的间隔如果太短, 服务器的压力就会比较大, 如果过小, 那么数据就不够实时;

poll时间间隔的解决方案--- long polling:

consumer poll数据时, 如果当前数据不够, 那么这个poll请求会阻塞, 等待有足够多的数据或者到达等待时间时才返回。 

2 kafka使用场景

2.1 消息系统

原因: 高可用; 根据经验, 通常对消息传递对吞吐量的要求比较低, 但是要求较低的端到端延迟, 并且要有可靠的durable机制(kafka是一个持久化的消息队列);高吞吐量;

 

对于消息顺序的保证, 从某种角度来说, kafka会比较好。因为即使是RabbitMQ和ActiveMQ, 当有多个消费者进行消费时, 其实我们没有办法保证哪个消费者先消费完, 其实顺序也会丢失。 

kafka实现顺序消费的方法:

  • 使用相同的key, 让消息只发送到一个partition中, 而一个partition只会被消费者组内的一个消费者所使用;
  • topic内只有一个消费者;

 

2.2 存储系统

高性能, 低延迟, 高可用的日志提交存储。 

 

2.3 日志聚合

日志处理的流程: 收集, 清洗(一般是使用正则来清洗), 聚合,存储, 展示

可能不能作为一个完全的日志解决方案, ELK的日志解决方案更加有优势。 (ELK的缺点: 聚合节点Logstash可能会成为系统瓶颈)

 

为什么要进行日志的聚合?

如果是分布式系统, 那么一个程序的多个实例的日志需要进行聚合。 一个请求在上下游的日志也需要聚合。 

 

2.4 跟踪网站活动(其实就是埋点)

kafka在LinkedIn中就因此而生。

 

2.5 流处理

Kafka StreamAPIs 可以进行流处理, 但是如果要使用复杂的流处理功能, 还是使用flink, spark streaming等框架。 

为什么需要流处理?

和流处理相对的是批处理, 批处理有很大的延迟, 比如说前一天去跑一些统计数据。 而流处理, 是一有新的数据就马上计算更新结果的处理方式。 

 

 

 

 

 

 

 

 

你可能感兴趣的:(消息中间件学习笔记)