一、kafka概述
在流式计算中,kafka是用来缓存数据的,storm通过消费kafka的数据进行计算。kafka的初心是,为处理实时数据提供一个统一、高通量、低等待的平台;
1、kafka是一个分布式消息队列:kafka对消息保存是根据topic主题进行归类,发送消息者称为producer,消息接受者称为consumer,此外kafka集群有多个kafka实例组成,每个实例(server)称为broker;
2、kafka的结构关系:kafka集群是有多个broker实例组成,一个broker实例包含多个不同的topic主题,一个topic主题又有多个分区partition,一个partition分区就是一个消息队列,partition分区可以有0到多个备份,分布在broker集群上,partition分区有主从之分,是通过zookeeper选举来确定;
3、kafka的核心概念:
- Producer: 特指消息的生产者
- Consumer :特指消息的消费者
- Consumer Group :消费者组,可以并行消费Topic中partition的消息
- Broker:缓存代理,Kafa 集群中的一台或多台服务器统称为 broker
- Topic:特指 Kafka 处理的消息源(feeds of messages)的不同分类
- Partition:Topic 物理上的分组,一个 topic 可以分为多个 partition,每个 partition 是一个有序的队列。partition 中的每条消息都会被分配一个有序的 id(offset)
- Message:消息,是通信的基本单位,每个 producer 可以向一个 topic(主题)发布一些消息
- Producers(是个动词):消息和数据生产者,向 Kafka 的一个 topic 发布消息的过程叫做 producers
- Consumers(是个动词):消息和数据消费者,订阅 topics 并处理其发布的消息的过程叫做 consumers
二、kafka中核心概念和机构配图
1、Broker:每个kafka server称为一个Broker,多个borker组成kafka cluster。一个机器上可以部署一个或者多个Broker,这多个Broker连接到相同的ZooKeeper就组成了Kafka集群。
2、主题Topic
Kafka的核心抽象概念记录流 – 主题,主题是一种分类或发布的一系列记录的名义上的名字。Kafka的主题始终是支持多用户订阅的; 也就是说,一个主题可以有零个,一个或多个消费者订阅写入的数据。一个Broker上可以创建一个或者多个Topic。同一个topic可以在同一集群下的多个Broker中分布。当然,Topic只是一个名义上的组件,真正在Broker间分布式的Partition。
3、分区与日志
一个主题对应多个分区,一个分区对应一个日志,Kafka会为每个topic维护了多个分区(partition),每个分区会映射到一个逻辑的日志(log)文件。每个分区是一个有序的,不可变的消息序列,新的消息不断追加到这个有组织的有保证的日志上。分区会给每个消息记录分配一个顺序ID号 – 偏移量, 能够唯一地标识该分区中的每个记录。日志分区是分布式的存在于一个kafka集群的多个broker上。每个partition会被复制多份存在于不同的broker上。这样做是为了容灾。具体会复制几份,会复制到哪些broker上,都是可以配置的。经过相关的复制策略后,每个topic在每个broker上会驻留一到多个partition:
4、保留策略与Offset
Kafka集群保留所有发布的记录,不管这个记录有没有被消费过,Kafka提供可配置的保留策略去删除旧数据(还有一种策略根据分区大小删除数据)。例如,如果将保留策略设置为两天,在记录公布后两天内,它可用于消费,之后它将被丢弃以腾出空间。Kafka的性能跟存储的数据量的大小无关, 所以将数据存储很长一段时间是没有问题的。
事实上,保留在每个消费者元数据中的最基础的数据就是消费者正在处理的当前记录的偏移量(offset)或位置(position)。这种偏移是由消费者控制:通常偏移会随着消费者读取记录线性前进,但事实上,因为其位置是由消费者进行控制,消费者可以在任何它喜欢的位置读取记录。例如,消费者可以恢复到旧的偏移量对过去的数据再加工或者直接跳到最新的记录,并消费从“现在”开始的新的记录。
这些功能的结合意味着,实现Kafka的消费者的代价都是很小的,他们可以增加或者减少而不会对集群或其他消费者有太大影响。例如,你可以使用我们的命令行工具去追随任何主题,而且不会改变任何现有的消费者消费的记录。
5、Leader与Followers
一个Topic可能有很多分区,以便它能够支持海量的的数据,更重要的意义是分区是进行并行处理的基础单元。日志的分区会跨服务器的分布在Kafka集群中,每个分区可以配置一定数量的副本分区提供容错能力。为了保证较高的处理效率,消息的读写都是在固定的一个副本上完成。这个副本就是所谓的Leader,而其他副本则是Follower,而Follower则会定期地到Leader上同步数据。
(1)leader处理所有的读取和写入分区的请求,而followers被动的从领导者拷贝数据。
(2)如果leader失败了,followers之一将自动成为新的领导者。
(3)每个服务器可能充当一些分区的leader和其他分区的follower,这样的负载就会在集群内很好的均衡分配。
(4)一个分区在同一时刻只能有一个消费者实例进行消费。
可以看见我们一共有3个分区分别是0,1,2, replica 有2个:
partition 0 的leader在broker1, follower在broker2
partition 1 的leader在broker2, follower在broker0
partition 2 的leader在broker0, follower在brokder1
一个broker中不会出现两个一样的Partition,replica会被均匀的分布在各个kafka server(broker)上 。Kafka并不允许replicas 数设置大于 broker数,因为在一个broker上如果有2个replica其实是没有意义的,因为再多的replica同时在一台broker上,随着该broker的crash,一起不可用。
(1)Leader选举与ISR
如果某个分区所在的服务器除了问题,不可用,kafka会从该分区的其他的副本中选择一个作为新的Leader。之后所有的读写就会转移到这个新的Leader上。现在的问题是应当选择哪个作为新的Leader。显然,只有那些跟Leader保持同步的Follower才应该被选作新的Leader。
Kafka会在Zookeeper上针对每个Topic维护一个称为ISR(in-sync replica,已同步的副本)的集合,该集合中是一些分区的副本。只有当这些副本都跟Leader中的副本同步了之后,kafka才会认为消息已提交,并反馈给消息的生产者。如果这个集合有增减,kafka会更新zookeeper上的记录。如果某个分区的Leader不可用,Kafka就会从ISR集合中选择一个副本作为新的Leader。显然通过ISR,kafka需要的冗余度较低,可以容忍的失败数比较高。假设某个topic有f+1个副本,kafka可以容忍f个服务器不可用。
(2)为什么不用少数服从多数的方法
少数服从多数是一种比较常见的一致性算法和Leader选举法。它的含义是只有超过半数的副本同步了,系统才会认为数据已同步;选择Leader时也是从超过半数的同步的副本中选择。这种算法需要较高的冗余度。譬如只允许一台机器失败,需要有三个副本;而如果只容忍两台机器失败,则需要五个副本。而kafka的ISR集合方法,分别只需要两个和三个副本。
(3)如果所有的ISR副本都失败了怎么办
此时有两种方法可选,一种是等待ISR集合中的副本复活,一种是选择任何一个立即可用的副本,而这个副本不一定是在ISR集合中。这两种方法各有利弊,实际生产中按需选择。如果要等待ISR副本复活,虽然可以保证一致性,但可能需要很长时间。而如果选择立即可用的副本,则很可能该副本并不一致。
6 生产者和消费者
(1)生产者
生产者发布数据到他们所选择的主题。生产者负责选择把记录分配到主题中的哪个分区。这可以使用轮询算法( round-robin)进行简单地平衡负载,也可以根据一些更复杂的语义分区算法(比如基于记录一些键值)来完成。
(2)消费者
消费者以消费群(consumer group)的名称来标识自己,每个发布到主题的消息都会发送给订阅了这个主题的消费群里面的一个消费者实例,即一个消费群只发送一次。消费者的实例可以在单独的进程或单独的机器上。