Kafka是分布式发布-订阅消息系统。它最初由LinkedIn公司开发,以后成为Apache项目的一部分。Kafka是一个分布式的,可划分的,冗余备份的持久性的日志服务。它主要用于处理活跃的流式数据。html
在大数据系统中,经常会碰到一个问题,整个大数据是由各个子系统组成,数据须要在各个子系统中高性能,低延迟的不停流转。传统的企业消息系统并非很是适合大规模的数据处理。为了已在同时搞定在线应用(消息)和离线应用(数据文件,日志)Kafka就出现了。Kafka能够起到两个做用:linux
下降系统组网复杂度。git
下降编程复杂度,各个子系统不在是相互协商接口,各个子系统相似插口插在插座上,Kafka承担高速数据总线的做用。github
同时为发布和订阅提供高吞吐量。据了解,Kafka每秒能够生产约25万消息(50 MB),每秒处理55万消息(110 MB)。算法
可进行持久化操做。将消息持久化到磁盘,所以可用于批量消费,例如ETL,以及实时应用程序。经过将数据持久化到硬盘以及replication防止数据丢失。apache
分布式系统,易于向外扩展。全部的producer、broker和consumer都会有多个,均为分布式的。无需停机便可扩展机器。编程
消息被处理的状态是在consumer端维护,而不是由server端维护。当失败时能自动平衡。vim
支持online和offline的场景。segmentfault
Kafka的总体架构很是简单,是显式分布式架构,producer、broker(kafka)和consumer均可以有多个。Producer,consumer实现Kafka注册的接口,数据从producer发送到broker,broker承担一个中间缓存和分发的做用。broker分发注册到系统中的consumer。broker的做用相似于缓存,即活跃的数据和离线处理系统之间的缓存。客户端和服务器端的通讯,是基于简单,高性能,且与编程语言无关的TCP协议。缓存
Topic:特指Kafka处理的消息源(feeds of messages)的不一样分类。
Partition:Topic物理上的分组,一个topic能够分为多个partition,每一个partition是一个有序的队列。partition中的每条消息都会被分配一个有序的id(offset)。
Message:消息,是通讯的基本单位,每一个producer能够向一个topic(主题)发布一些消息。
Producers:消息和数据生产者,向Kafka的一个topic发布消息的过程叫作producers。
Consumers:消息和数据消费者,订阅topics并处理其发布的消息的过程叫作consumers。
Broker:缓存代理,Kafa集群中的一台或多台服务器统称为broker。
Producer根据指定的partition方法(round-robin、hash等),将消息发布到指定topic的partition里面
kafka集群接收到Producer发过来的消息后,将其持久化到硬盘,并保留消息指定时长(可配置),而不关注消息是否被消费。
Consumer从kafka集群pull数据,并控制获取消息的offset
高吞吐是kafka须要实现的核心目标之一,为此kafka作了如下一些设计:
数据磁盘持久化:消息不在内存中cache,直接写入到磁盘,充分利用磁盘的顺序读写性能
zero-copy:减小IO操做步骤
数据批量发送
数据压缩
Topic划分为多个partition,提升parallelism
producer根据用户指定的算法,将消息发送到指定的partition
存在多个partiiton,每一个partition有本身的replica,每一个replica分布在不一样的Broker节点上
多个partition须要选取出lead partition,lead partition负责读写,并由zookeeper负责fail over
经过zookeeper管理broker与consumer的动态加入与离开
因为kafka broker会持久化数据,broker没有内存压力,所以,consumer很是适合采起pull的方式消费数据,具备如下几点好处:
简化kafka设计
consumer根据消费能力自主控制消息拉取速度
consumer根据自身状况自主选择消费模式,例如批量,重复消费,从尾端开始消费等
当须要增长broker结点时,新增的broker会向zookeeper注册,而producer及consumer会根据注册在zookeeper上的watcher感知这些变化,并及时做出调整。
kafka和JMS实现(activeMQ)不一样的是:即便消息被消费,消息仍然不会被当即删除.日志文件将会根据broker中的配置要求,保留必定的时间以后删除;好比log文件保留2天,那么两天后,文件会被清除,不管其中的消息是否被消费.kafka经过这种简单的手段,来释放磁盘空间.此外,kafka的性能并不会由于日志文件的太多而低下,因此即便保留较多的log文件,也不不会有问题.
kafka中consumer负责维护消息的消费记录,而broker则不关心这些,这种设计不只提升了consumer端的灵活性,也适度的减轻了broker端设计的复杂度;这是和众多JMS prodiver的区别.此外,kafka中消息ACK的设计也和JMS有很大不一样,kafka中的消息时批量(一般以消息的条数或者chunk的尺寸为单位)发送给consumer,当消息消费成功后,向zookeeper提交消息的offset,而不会向broker交付ACK.或许你已经意识到,这种"宽松"的设计,将会有"丢失"消息/"消息重发"的危险.
比起大多数的消息系统来讲,Kafka有更好的吞吐量,内置的分区,冗余及容错性,这让Kafka成为了一个很好的大规模消息处理应用的解决方案。消息系统通常吞吐量相对较低,可是须要更小的端到端延时,并尝尝依赖于Kafka提供的强大的持久性保障。在这个领域,Kafka足以媲美传统消息系统,如ActiveMR或RabbitMQ。
Kafka的另外一个应用场景是跟踪用户浏览页面、搜索及其余行为,以发布-订阅的模式实时记录到对应的topic里。那么这些结果被订阅者拿到后,就能够作进一步的实时处理,或实时监控,或放到hadoop/离线数据仓库里处理。
做为操做记录的监控模块来使用,即聚集记录一些操做信息,能够理解为运维性质的数据监控吧。
日志收集方面,其实开源产品有不少,包括Scribe、Apache Flume。不少人使用Kafka代替日志聚合(log aggregation)。日志聚合通常来讲是从服务器上收集日志文件,而后放到一个集中的位置(文件服务器或HDFS)进行处理。然而Kafka忽略掉文件的细节,将其更清晰地抽象成一个个日志或事件的消息流。这就让Kafka处理过程延迟更低,更容易支持多数据源和分布式数据处理。比起以日志为中心的系统好比Scribe或者Flume来讲,Kafka提供一样高效的性能和由于复制致使的更高的耐用性保证,以及更低的端到端延迟。
这个场景可能比较多,也很好理解。保存收集流数据,以提供以后对接的Storm或其余流式计算框架进行处理。不少用户会将那些从原始topic来的数据进行阶段性处理,汇总,扩充或者以其余的方式转换到新的topic下再继续后面的处理。例如一个文章推荐的处理流程,多是先从RSS数据源中抓取文章的内容,而后将其丢入一个叫作“文章”的topic中;后续操做多是须要对这个内容进行清理,好比回复正常数据或者删除重复数据,最后再将内容匹配的结果返还给用户。这就在一个独立的topic以外,产生了一系列的实时数据处理的流程。Strom和Samza是很是著名的实现这种类型数据转换的框架。
事件源是一种应用程序设计的方式,该方式的状态转移被记录为按时间顺序排序的记录序列。Kafka能够存储大量的日志数据,这使得它成为一个对这种方式的应用来讲绝佳的后台。好比动态汇总(News feed)。
Kafka能够为一种外部的持久性日志的分布式系统提供服务。这种日志能够在节点间备份数据,并为故障节点数据回复提供一种从新同步的机制。Kafka中日志压缩功能为这种用法提供了条件。在这种用法中,Kafka相似于Apache BookKeeper项目。
传统的数据发送须要发送4次上下文切换,采用sendfile系统调用以后,数据直接在内核态交换,系统上下文切换减小为2次。根据测试结果,能够提升60%的数据发送性能。Zero-Copy详细的技术细节能够参考:https://www.ibm.com/developerworks/linux/library/j-zerocopy/
kafka以topic来进行消息管理,每一个topic包含多个part(ition),每一个part对应一个逻辑log,有多个segment组成。每一个segment中存储多条消息(见下图),消息id由其逻辑位置决定,即从消息id可直接定位到消息的存储位置,避免id到位置的额外映射。每一个part在内存中对应一个index,记录每一个segment中的第一条消息偏移。发布者发到某个topic的消息会被均匀的分布到多个part上(随机或根据用户指定的回调函数进行分布),broker收到发布消息往对应part的最后一个segment上添加该消息,当某个segment上的消息条数达到配置值或消息发布时间超过阈值时,segment上的消息会被flush到磁盘,只有flush到磁盘上的消息订阅者才能订阅到,segment达到必定的大小后将不会再往该segment写数据,broker会建立新的segment。
即全部的producer、broker和consumer都会有多个,均为分布式的。Producer和broker之间没有负载均衡机制。broker和consumer之间利用zookeeper进行负载均衡。全部broker和consumer都会在zookeeper中进行注册,且zookeeper会保存他们的一些元数据信息。若是某个broker和consumer发生了变化,全部其余的broker和consumer都会获得通知。
[1] Kafka的一些特色 http://blog.segmentfault.com/mongo/1190000000385620
[2] Apache kafka原理与特性(0.8V) http://shift-alt-ctrl.iteye.com/blog/1930345
[3] Flafka: Apache Flume Meets Apache Kafka for Event Processing
http://blog.cloudera.com/blog/2014/11/flafka-apache-flume-meets-apache-kafka-for-event-processing/
[4] Kafka文件存储机制那些事 http://tech.meituan.com/kafka-fs-design-theory.html
[5] Kafka深度解析 http://www.jasongj.com/2015/01/02/Kafka%E6%B7%B1%E5%BA%A6%E8%A7%A3%E6%9E%90/
Kafka剖析(一):高扩展、高吞吐的分布式消息系统初探
[6] Apache kafka 工做原理介绍
http://www.ibm.com/developerworks/cn/opensource/os-cn-kafka/index.html
[7] Kafka设计解析(四):Kafka Consumer解析
http://www.infoq.com/cn/articles/kafka-analysis-part-4
[8] kafka入门:简介、使用场景、设计原理、主要配置及集群搭建(转)
http://www.cnblogs.com/likehua/p/3999538.html
[9] Apache kafka原理与特性(0.8V)
http://shift-alt-ctrl.iteye.com/blog/1930345
[10] Kafka 高性能吞吐揭秘
[11] Kafka源码分析 ISR
http://zqhxuyuan.github.io/2016/01/14/2016-01-14-Kafka-ISR/#
[12] Kafka设计与原理