Kafka 初识

kafka 是由LinkedIn公司开发的,是一个分布式、支持分区的、多副本的,基于zookeeper协调的分布式消息系统,它的最大特点就是可以实时的处理大量数据以满足各种需求场景:比如基于Hadoop的批处理系统、低延迟的实时系统、storm/spark流式处理引擎,web/nginx日志、访问日志、消息服务等,用Scala语言编写,LinkedIn于2010年贡献给了Apache基金会并成立顶级开源项目;

1.1 kafka的特性

  • 高吞吐量、低延迟:kafka每秒可以处理几十万条消息;它的最低延迟只有几毫秒,每个topic可以分多个partition,consumer group 对partition进行consumer操作;
  • 可扩展性:kafka集群支持热扩展;
  • 持久性、可靠性:消息被持久化到本地磁盘,并支持数据备份防止数据丢失;
  • 容错性:允许集群节点失败(若副本数量为n,则允许n-1个节点失败)
  • 高并发:支持数千个客户端同时读写

1.2 kafka的使用场景

  • 日志收集
  • 消息系统
  • 用户活动跟踪
  • 运营指标
  • 流式处理
  • 事件源

1.3 kafka的设计思想

1.3.1、kafka Broker Leader 的选举
kafka集群受zookeeper管理,所有的kafka broker节点一起去zookeeper注册一个临时节点,只有一个kafka broker 会注册成功,其他的都会失败,这个成功的节点成为 kafka broker controller,其他的kafka broker叫 kafkabroker follower。(这个过程叫Controller在zookeeper注册watch)。这个Controller会监听其他的Kafka Broker的所有信息,如果这个kafka broker controller宕机了,在zookeeper上面的那个临时节点就会消失,此时所有的kafka broker又会一起去Zookeeper上重新注册一个临时节点,因为只有一个Kafka Broker会注册成功,其他的都会失败,所以这个成功在Zookeeper上注册临时节点的这个Kafka Broker会成为Kafka Broker Controller,其他的Kafka broker叫Kafka Broker follower。

1.3.2、Consumergroup
各个consumer(consumer 线程)可以组成一个组(cousumer group),partition中的每个message只能被组(consumer group)中的一个consumer(consumer 线程)消费,如果一个message可以被多个consumer(consumer 线程)消费的话,那么这些consumer必须在不同的组。Kafka不支持一个partition中的message由两个或两个以上的同一个consumer group下的consumer thread来处理,除非再启动一个新的consumer group。所以如果想同时对一个topic做消费的话,启动多个consumer group就可以了,但是要注意的是,这里的多个consumer的消费都必须是顺序读取partition里面的message,新启动的consumer默认从partition队列最头端最新的地方开始阻塞的读message。它不能像AMQ那样可以多个BET作为consumer去互斥的(for update悲观锁)并发处理message,这是因为多个BET去消费一个Queue中的数据的时候,由于要保证不能多个线程拿同一条message,所以就需要行级别悲观所(for update),这就导致了consume的性能下降,吞吐量不够。而kafka为了保证吞吐量,只允许同一个consumer group下的一个consumer线程去访问一个partition。如果觉得效率不高的时候,可以加partition的数量来横向扩展,那么再加新的consumer thread去消费。如果想多个不同的业务都需要这个topic的数据,起多个consumer group就好了,大家都是顺序的读取message,offsite的值互不影响。这样没有锁竞争,充分发挥了横向的扩展性,吞吐量极高。这也就形成了分布式消费的概念。

1.3.3、Consumer
Consumer处理partition里面的message的时候是O(1) 顺序读取的。所以必须维护着上一次读到哪里的offset信息,high level API offset存放于zookeeper中,low level API的offset由自己维护。一般都是使用high level api的。Consumer的delivery gurarantee,默认是读完message先commmit再处理message,autocommit默认是true,这时候先commit就会更新offsite+1,一旦处理失败,offsite已经+1,这个时候就会丢message;也可以配置成读完消息处理再commit,这种情况下consumer端的响应就会比较慢的,需要等处理完才行。

1.3.4、Topic & Partition
Topic相当于传统消息系统MQ中的一个队列queue,producer端发送的message必须指定是发送到哪个topic,但是不需要指定topic下的哪个partition,因为kafka会把收到的message进行load balance,均匀的分布在这个topic下的不同的partition上( hash(message) % [broker数量] )。物理上存储上,这个topic会分成一个或多个partition,每个partiton相当于是一个子queue。在物理结构上,每个partition对应一个物理的目录(文件夹),文件夹命名是[topicname][partition][序号],一个topic可以有无数多的partition,根据业务需求和数据量来设置。在kafka配置文件中可随时更高num.partitions参数来配置更改topic的partition数量,在创建Topic时通过参数指定parittion数量。Topic创建之后通过Kafka提供的工具也可以修改partiton数量。一般来说,(1)一个Topic的Partition数量大于等于Broker的数量,可以提高吞吐率。(2)同一个Partition的Replica尽量分散到不同的机器,高可用。当add a new partition的时候,partition里面的message不会重新进行分配,原来的partition里面的message数据不会变,新加的这个partition刚开始是空的,随后进入这个topic的message就会重新参与所有partition的load balance

参考文献:Kafka史上最详细原理总结

你可能感兴趣的:(消息中间件,kafka,分布式,消息中间件)