本系列主要讲解kafka基本设计和原理分析,分以下内容:html
kafka在1.0版本之前,官方主要定义为分布式多分区多副本的消息队列,而1.0后定义为分布式流处理平台,就是说处理传递消息外,kafka还能进行流式计算,相似Strom和SparkStreaming。
主要有三大核心能力:算法
能够看到其主要分为两类应用,即系统或应用程序之间的数据共享,以及构建实时流应用程序并进行相应的处理。
数据库
相关功能主要经过以下四个核心API实现:编程
kafka的主题(topic)是支持多用户订阅的,一个主题能够有零个,一个或多个消费者订阅写入的数据。
对于每个主题,Kafka集群保持一个分区日志文件,看下图:
服务器
每一个分区是一个有序的,不可变的消息序列,新的消息不断追加,同时分区会给每一个消息记录分配一个顺序ID号 – 偏移量, 用于惟一标识该分区中的每一个记录。并发
Kafka集群保留全部发布的记录,无论这个记录有没有被消费过,Kafka提供可配置的保留策略去删除旧数据(还有一种策略根据分区大小删除数据)。例如,若是将保留策略设置为两天,在记录公布后两天,它可用于消费,以后它将被丢弃以腾出空间。Kafka的性能跟存储的数据量的大小无关, 因此将数据存储很长一段时间是没有问题的。
分布式
事实上,保留在每一个消费者元数据中的最基础的数据就是消费者正在处理的当前记录的偏移量(offset)或位置(position)。这种偏移是由消费者控制:一般偏移会随着消费者读取记录线性前进,但事实上,由于其位置是由消费者进行控制,消费者能够在任何它喜欢的位置读取记录。例如,消费者能够恢复到旧的偏移量对过去的数据再加工或者直接跳到最新的记录,并消费从“如今”开始的新的记录。
数据日志的分区,有多个目的。首先,每一个单独的分区的大小受到承载它的服务器的限制,但一个主题可能有不少分区,容许数据可以扩展到多个服务器,以便它可以支持海量的的数据。其次,更重要的意义是分区是进行并行处理的基础单元。
日志的分区会跨服务器的分布在Kafka集群中,每一个服务器会共享分区进行数据请求的处理。每一个分区能够配置必定数量的副本分区以提供容错能力。
每一个分区都有一个服务器充当“leader”和零个或多个服务器充当“followers”。 leader处理全部的读取和写入分区的请求,而followers被动的从leader拷贝数据。若是leader失败了,followers之一将自动成为新的领导者。每一个服务器可能充当一些分区的leader和其余分区的follower,这样的负载就会在集群内很好的均衡分配。高并发
生产者发布数据到他们所选择的主题。生产者负责选择把记录分配到主题中的哪一个分区。这可使用轮询算法( round-robin)进行简单地平衡负载,也能够根据一些更复杂的语义分区算法(好比基于记录一些键值自定义)来完成。性能
消费者以消费群(consumer group )的名称来标识本身,每一个发布到主题的消息都会发送给订阅了这个主题的消费群里面的一个消费者的一个实例。消费者的实例能够在单独的进程或单独的机器上。
若是全部的消费者实例都属于相同的消费群,那么记录将有效地被均衡到每一个消费者实例。
若是全部的消费者实例有不一样的消费群,那么每一个消息将被广播到全部的消费者进程。
设计
两个服务器的Kafka集群具备四个分区(P0-P3)和两个消费群。A消费群有两个消费者,B群有四个。
更常见的是,咱们会发现主题有少许的消费群,每个都是“逻辑上的订阅者”。每组都是由不少消费者实例组成,从而实现可扩展性和容错性。这只不过是发布 – 订阅模式的再现,区别是这里的订阅者是一组消费者而不是一个单一的进程的消费者。
Kafka消费群的实现方式是经过分割日志的分区,分给每一个Consumer实例,使每一个实例在任什么时候间点的均可以“公平分享”独占的分区。维持消费群中的成员关系的这个过程是经过Kafka动态协议处理。若是新的实例加入该组,他将接管该组的其余成员的一些分区; 若是一个实例死亡,其分区将被分配到剩余的实例。
Kafka只保证一个分区内的消息有序,不能保证一个主题的不一样分区之间的消息有序。分区的消息有序与依靠主键进行数据分区的能力相结合足以知足大多数应用的要求。可是,若是你想要保证全部的消息都绝对有序能够只为一个主题分配一个分区,虽然这将意味着每一个消费群同时只能有一个消费进程在消费。
关于做者
爱编程、爱钻研、爱分享、爱生活
关注分布式、高并发、数据挖掘
如需捐赠,请扫码