这个应该算是之前比较火热的词了,一直没时间抽出来看看。一个新东西出来,肯定是为了解决某些问题,不然不会有它的市场。先简单看下。
官方介绍:分布式、分区、支持复制的日志提交系统
适用场景:顾名思义,特别适合用于系统日志的异步记录,对于数据稳定性、一致性、可靠性要求不高的场景,追求的是高吞吐量。非传统的MQ产品!
核心模型抽象:
topics:某种消息的高层抽象
producers:消息的生产者
consumers:消息的消费者
broker:集群中的每一个节点服务器,多个broker组成一个集群
整体结构图:
topic:
1.kafka集群会将每个topic进行分区,每个分区都是一个排序且不可改变的队列,新的消息会进入队尾并分配一个唯一ID,官方称之为偏移量(offset)
2.无论消息是否被消费,集群都会保留消息,有一个配置的时间,超过这个时间后,消息会被清除
3.消费端唯一记录的元信息就是自己在topic中的位置(offset),
4.分布式的原因:第一集群可以容纳大量的数据 第二:可以并行的处理
分布式
1.每一份数据都会复制到不同的服务器上,以便与容错处理
2.每一个topic的分区都会有一个leader,并有零个或是多个follower,所有的读写请求都会经过leader来进行分发,若是leader发生错误的话,那么就会有一个follower上位成为leader
生产者
Producers会将数据发送消息到topic,发送的目的地可以根据轮训策略或是到指定的分区策略
消费者
消息一般有两种模式,其一是队列,另一种是发布订阅。
队列:有很多消费者,每一个消费者从队列中获取其中一个数据,一个数据只被消费一次。
发布订阅模式:将一个消费广播到所有的消费者,一个数据会被消费N次。
kafka对于消费者提供了一种简单的抽象 — 消费组。每一个消费者都会有一个消费组的名称,一个消费会发布到一个topic上,同时递送到订阅了这个消息的消费组下的所有消费者。具体如下图所示:
若是所有的消费者都是相同的消费组,那么就是一个队列模式。若是消费者有不同的组,那么就是发布订阅模式,那么消费就会递送到所有的消费者。
通过对于消费组的名称不同来区分了队列和发布订阅模式。
每一个topic都会有一定数量的消费组,每个消费组(逻辑订阅者)包含了多个消费者,这样就可以保证可伸缩性金额容错。这样订阅者就是一个集群而不是单个实例。保证单点故障问题。
在强一致性上kafka同传统的MQ也在靠近。
传统的队列是将消息按照存储时候的顺序进行发送,但是有多个消费者的时候,有可能发生到底每个消费者的顺序不一定,一是导致无法并行,二是导致消费的顺序不一致。为了解决这个问题,通常的手段是只有一个消费者来保证顺序。
针对上面两个问题,kafka有自己的解决方案。解决并行是将多个分区分别指定对应的消费者,这样就保证了并行,同时保证了消息消费的顺序,限制是消费者的数量不能多于分区数目(通过配置指定).
但是这样就只能保证一个分区中的消息是保证顺序,无法保证不同分区的消息的顺序一致性。在大多数应用场景下,这样是能满足要求的,若是你要求非常强烈的一致性话,就只能单消费者了。
一致性
1.topic接受到消息并保存到队列中,若是收到M1,M2两个消息,那么在队列中M1的偏移量会小于M2
2.消费者看到消息的顺序就是在保存到日志上的顺序
3.一个topic的复制因子是N,那么消息会被复制到N-1服务器上,保证消息的不丢失
一些常见的使用场景
1.作为消息处理系统
作用:解耦消息的生产和处理、缓存消息以缓解对于后端处理承受的压力
可以比较的类似产品是ActiveMQ or RabbitMQ.
2.网页行为记录
一个用户的行为记录的消费者一般是多个,可能是实时处理系统,也可能是离线处理系统,同时吞吐量非常的大,kafka就非常的适合
3.监控 对于一些监控数据的处理
4.日志聚合方案
这个是kafka最常用的地方,用于分散到多个地方的日志做一个聚合,以便于后续的分析处理
5.流式处理
官方的说法是也可以把kafka当做类似Strom或Samza的流式处理框架来用,至于效果如何就未知
6.事件驱动架构
这种架构风格中的候选者之一
消息框架的出现解决了很多问题,例如解耦消息的生产和处理、缓存消息以缓解对于后端处理承受的压力(提升性能.不同框架的设计决定了它的适用场景,kafka的topic分区并行设计决定了它的高吞吐量,但是不保证顺序一致性,对于feed类就不友好
其他:
1.支持批量发布
2.基于TCP协议,传输层协议,不需要任何的语义
3.有不同客户端实现
参考资料:
- http://kafka.apache.org/documentation.html#introduction
- http://www.zhihu.com/question/22480085