kafka的定位
(1)消息中间件
(2)消息引擎
(3)分布式实时流处理平台
使用场景:
(1)消息传递 Message
RabbitMQ、RocketMQ能做的事情他都能做,而且吞吐量更大,在大规模消息系统中更有优势;
(2)网站活动跟踪
社交网站的行为跟踪、购物网站的行为跟踪,可以实现更精确的推荐功能;
(3)日志聚合
(4)应用指标监控
(5)数据集成+流计算
数据集成指的是把kafka里的数据导入Hbase\Hadoop等离线数据仓库,实现数据分析;
kafka内置了流处理框架
kafka架构
(1)Broker : kafka的服务
(2)消息:客户端之间传递的数据
生产者对应的封装类是ProducerRecord,消费者对应的封装类是ConsumerRecord
(3)生产者:发送消息的一方,kafka中为了提升消息的发送速率,消息是批量发送的;
(4)消费者:kafka只支持pull(主动拉取)的方式;
原因:在push模式下,如果生产消息的速率远远大于消费消息的速率,那么消费者就会不堪重负,直接挂掉。而且pull的模式,消费者可以自己控制消息的数量。
(5)Topic:逻辑概念,可理解为一组消息的集合;生产者与Topic已经Topic和消费者之间的关系都可以是多对多;
(6)partion: 分区 思想上类似于分库分表,目的是为了进行横向扩展和负载;
partion的副本机制Replica:如果一个partion只有一份数据,在发生网络故障以后,数据就无法恢复了,因此在kafka0.8之后引入了副本机制。
每个partion可以有多个副本,每个副本必须存储在不同的节点上。在这些副本中又有一个leader,消息的读取和发送都是针对leader进行的。
每个partion对应有一个物理存储目录。
(7)segment
kafka的数据是存放在.log后缀的文件里面的,如果一个partion只有一个log文件,消息源源不断的增加,文件会越来越大,检索数据的效率就会随之降低;
因此对partion再进行切分,切分的单位(默认是1G)就是segment。
每个segment都至少有一个数据文件和两个日志文件:
xxx849751.log
xxx849751.index
xxx849751.timeindex
(8)Consumer Group
当需要多个消费者对同一个topic进行消费的时候,通过gruop 来对这一类消费者进行划分。
在同一个group中的不同消费者不能消费相同的partion的消息;
(9)Consumer offset
记录下一条将要发送给consumer的消息的位置(序号)。
kafka应用场景
(1)作为普通的消息队列;
(2)与canal结合,实现数据同步;
canal是阿里开源的增量日志同步工具。它将自己伪装成mysql数据库的一个slave,不断请求master以获取最新binlog,对binlog进行解析,获取数据的变动情况。
Canal是一款java开发的数据同步工具,可以支持binlog增量订阅,可以做数据备份、缓存同步刷新、构建ES索引、增量数据处理等。
kafka高阶
1、消息的幂等性
RabbitMQ的消息幂等性是在消费端实现的,但是所有的消费者都需要相同的实现。
kafka干脆在borker服务端实现消息的幂等性控制,大大方便了消费端的使用。
将enable.idempotence设置成true之后,Producer自动升级成幂等性Producer,kafka会自动去重。
实现机制:
(1)PID(Producer ID):幂等性的生产者每个客户端都有一个一个唯一的编号;
(2)sequence number: 幂等性的生产者发送的每条消息都会带有相应的sequence number,Server根据这个值来判断消息是否重复,
如果发现sequence number比服务端记录的值小,则出现了消息重复。
但是,这个sequence number并不是全局有序的,它的作用范围是有限的:
1、只能保证单分区上的幂等性,即一个幂等性producer能够保证一个topic的一个分区上消息不重复;
2、只能实现单会话上的幂等性,当重启了producer之后,幂等性不保证。
2、生产者事务
由于生产者的消息可能跨分区,因此这里的事务属于分布式事务;
(1)kafka的事务选择比较常用的两阶段提交;如果大家都可以commit,则commit,斗则abort。
(2)2PC提交需要一个协调者,Transcation cordinator
(3)事务管理必须要有事务日志,记录事务状态,以便生产者挂了重启之后能继续原来的事务;
(4)若要事务挂了之后能继续原来的事务,那么需要记录一个事务id,transcation.id,不同机器上的生产者通过这个id来控制同一个事务;
kafka的特性:
kafka主要用于解决数据流的传输问题,因此具有一下特点:
(1)高吞吐、低延迟:kafka最大的特点就是收发消费非常快,每秒可以处理几十万的消息,最低延迟只有几毫秒;
(2)高伸缩性:可以通过增加partion实现扩容;
(3)持久性、可靠性:能够允许数据的持久化存储,消息持久化到磁盘,并支持数据备份防止数据丢失;
(4)容错性:允许集群中的节点失败,某个节点宕机,集群能够正常工作;
(5)高并发:支持数千个客户端同时读写;
kafka与rabbit的比较:
(1)主要区别:
1)产品侧重:kafka用于流式消息处理,消息引擎;rabbitmq:消息代理;
2)性能:kafka有更高的吞吐量;rabbitmq主要push消息,kafka只有pull;
3)消息顺序:分区里面的消息是有序的,同一个consumer group里面的一个consumer只消费一个partion时,能保证消息的顺序;
4)消息的路由和分发:rabbitmq更加灵活:exchange路由关系;
5)rabbitmq支持延迟消息和死信队列;
6)消息的留存:kafka消费完消息之后会留存,rabbitmq消费完就清除;
优先选择rabbitmq的情况“
(1)高级灵活的路由规则;
(2)需要对消息进行时许控制(消息过期或者消息延迟);
(3)高级的容错处理能力(生产者、服务端、queue、消费者消息可靠性保证);
(4)更简单的消费者实现;
优先选择kafka的情况:
(1)严格的消息顺序;
(2)需要延长消息留存时间(过去消息重发);
(3)解决传统方案无法满足的高伸缩能力;
消息的可靠投递:
(1)服务端发送ACK给生产者:
ISR:维护了能正常与leader同步数据的replica集合,当一个replica长时间不与leader同步数据,将被从ISR移除;
(2)ACK应答机制:
客户端可以根据自身需求,选择对应的应答级别:
ack=0: producer不等待broker的应答,延迟最低,可能存在消息丢失;
ack=1(默认):producer等待broker的ack,partion的leader落盘成功后返回ack,如果follower同步之前leader故障,会丢失消息;
ack=-1 :producer等待broker的ack,partion的leader和follower全部落盘成功之后返回ack;