Apache Kafka
早期的logo:
Apache Kafka is an open-source distributed event streaming platform used by thousands of companies for
high-performance data pipelines, streaming analytics, data integration, and mission-critical
applications.
Kafka 最初是由LinkedIn公司采用Scala语言开发的一个支持多分区,多副本且基于Zookeeper协调的分布式消息系统。
根据官方网站Apache kafka目前定位于分布式流处理平台( distributed event streaming platform),他以高性能,高吞吐,可持久化,可水平扩展 支持流数据处理等多种特性而被广泛使用。
Apache Kafka目前主要扮演三大角色:
1.消息系统(Message System):和传统的消息系统相比,除了都具备系统解耦,冗余存储,流量削峰填谷,缓冲,异步通信,扩展性和可恢复性等功能,Kafka还提供了多数消息系统难以实现的消息顺序性保障和回溯消费的功能
2.存储系统:kafka可以将消息持久化到磁盘,相比于内存存储系统则有效的降低了数据丢失的风险。得益于kafka的消息持久化功能和多副本机制,可以将kafka作为长期的数据存储系统来使用,只需要把对应的数据保留策略设置为 永久或者启用主题的日志压缩功能即可
3.流式处理平台:kafka为每个流行的流式处理框架提供了可靠的数据来源,还提供了一个完整的流式处理库,比如窗口,连接,变换和聚合等各类操作。
消息的传输方式:
点对点模式:消息队列模型,即一对一,消费者主动拉取数据,消息收到后消息清除
消息生产者生产消息发送到Queue中,然后消息消费者从Queue中取出并且消费消息。
消息被消费以后,queue中不再有存储,所以消息消费者不可能消费到已经被消费的消息。Queue支持存在多个消费者,但是对一个消息而言,只会有一个消费者可以消费。
日常生活的例子比如电话客服就属于这种模型:同一个客户呼入电话只能被一位客服人员处理,第二个客服人员不能为该客户服务。
发布订阅模型:一对多,消费者消费数据之后不会清除消息
消息生产者(发布)将消息发布到topic中,同时有多个消息消费者(订阅)消费该消息。和点对点方式不同,发布到topic的消息会被所有订阅者消费。
该模型也有发送方和接收方,只不过提法不同。发送方也称为发布者(Publisher),接收方称为订阅者(Subscriber)。和点对点模型不同的是,这个模型可能存在多个发布者向相同的主题发送消息,而订阅者也可能存在多个,它们都能接收到相同主题的消息。生活中的报纸订阅就是一种典型的发布 / 订阅模型。
Apache Kafka同时支持两种模型。
Kafka 术语:
典型的Kafka体系架构包括若干producer,若干Broker,若干Consumer和一个zookeeper集群。
Zookeeper:负责集群元数据的管理 和控制器的选举等操作。
Broker:服务代理节点。负责接收来自Producer的消息并存储到磁盘中。可以理解为一个kafka机器或者实例就是一个Broker,一个Kafka集群由多个broker组成。
Producer:消息的生产者,向Broker 发送消息的客户端。生产者负责将消息记录(message record)发送到Broker,分配到topic指定的分区中(partition)。
Consumer:消息的消费者,每个消费者自己维护自己的offset,读取来自broker发送的消息。
消费端也具有一定的容灾能力,Consumer使用pull模式从服务端拉取消息并保存消费的具体位置,当消费者宕机后恢复上线之时,可以根据之前保存的消费位置重新地拉取需要的消息进行消费,这样就不会造成消息的丢失。
Topic:主题,topic是一个逻辑概念,可以被细分为多个分区,一个分区只属于一个主题。同一个主题下的分区包含的消息是不同的,分区再存储层面可以看做是一个可追加的日志文件,消息被追加到分区日志文件的时候都会分配一个特定的偏移量(offset)。Offset是消息在分区中唯一标识,kafka通过offset来保证消息在分区内的顺序性,offset并不能跨越分区。即kafka保证的是分区有序,而不保证topic有序。
一个topic可以跨越多个broker。
Partition:分区 ,每个topic可以有多个分区,通过分区的设计,topic可以不断进行水平扩展!即一个Topic的多个分区分布式存储在多个broker。
每条消息在发送到broker之前,会根据分区规则选择存储到哪个具体的分区,若分区规则设置的合理则所有的消息可以均匀的分配在不同的分区中。若一个主题只对应一个文件则文件所在的磁盘IO将会成为此主题的性能瓶颈,而分区可解决此问题。分区的个数可以在创建分区的时候通过指定的参数设置分区的个数,也可以在主题创建完成之后修改分区的数量,通过增加分区的数量可以实现水平扩展。
此外通过分区还可以让一个topic被多个consumer进行消费!以达到并行处理!分区可以类比为数据库中的表!
kafka只保证按一个partition中的顺序将消息发给consumer,不保证一个topic的整体(多个partition间)的顺序。
简言之:一个topic 可以拥有若干个partition(从 0 开始标识partition ),分布在不同的broker 上, 实现发布与订阅时负载均衡。
producer 通过自定义的规则将消息发送到对应topic 下某个partition,以offset标识一条消息在一个partition的唯一性。
Replica:副本机制,kafka为分区引入了replica通过增加副本数量可以提升容灾的能力。同一分区再不同的副本中保存的是相同的消息(在同一时刻副本之间并非完全一样),副本之间是一主多从的关系。
Leader replica:负责处理读写请求。生成者和消费者只与leader副本进行交互。
Follower replica:只负责与Leader副本的消息同步,多数时候follower副本中的消息相对leader会有一定的滞后。
副本处于不同的broker之中,当leader副本出现故障的时候,从follower副本重新选举新的leader副本对外提供服务。kafka通过多副本机制实现了故障的自动转移,当kafka集群中某个broker失效的时候仍然保证服务的可用性。
AR(Assigned Replicas):分区中的所有副本称之为AR。所有与Leader副本保持一定程度的同步的副本(包括 leader replica)组成ISR(In-Sync Replicas),ISR集合是AR集合中的一个子集。消息会首先发送到leader replica 然后follower replica才能从leader replica 中拉取消息进行同步,同步期间follower副本相对于leader follower 会有一定的滞后。与Leader replica 同步滞后过多的副本(不含leader replica)组成OSR(Out-of-Sync Replica),由此可见AR=ISR+OSR。
在正常情况下所有的follower都应该与leader保持一致,即AR=ISR,OSR集合为空。
Leader 副本负责维护和追踪ISR集合中所有的follower副本的滞后状态,当follower副本落后太多或者失败,leader副本会把它从ISR集合中剔除,若OSR集合中follower副本追上了leader副本则leader会把它从OSR集合转义到ISR集合。默认情况下当leader副本发生故障的时候,只有在ISR集合中的副本才有资格当选为新的leader,而OSR集合中副本则没有任何机会(此原则可通过修改相应的参数配置来改变)
HW(High Watermark):高水位,标识了一个特定的消息偏移量(offset),消费者只能拉取到offset之前的消息。
LEO(Log End Offset):标识当前日志文件中的下一条待写入的消息的offset。LEO的大小相当于当前日志分区中最后一条消息的offset值加1,分区ISR集合中的每个副本都会维护自身的LEO,而ISR集合中的最小的LEO即为分区的HW,对消费者而言只消费HW之前的消息。
Kafka的复制机制:
事实上同步复制要求所有能工作的follower副本都复制完,这条消息才能被确认为已成功提交,这种复制方式极大的影响了性能。
异步复制方式下follower副本异步地从leader副本中复制数据,数据只能被leader副本写入就被认为成功提交。这种情况下,若follower副本都还没有复制完而落后于leader副本若leader副本突然宕机则会造成数据丢失。Kafka使用了ISR的方式则有效的权衡了数据可靠性和性能。kafka的复制机制既不是完全的同步复制也不是单纯的异步复制。
消费者组(Consumer Group):每个消费者都有一个对应的消费组,当消息被发布到主题后,只会投递给订阅它的么个消费组中的一个消费者。
指的是多个消费者实例共同组成一个组来消费一组主题。这组主题中的每个分区都只会被组内的一个消费者实例消费,
其他消费者实例不能消费它。为什么要引入消费者组呢?主要是为了提升消费者端的吞吐量。多个消费者实例同时消费,加速整个消费端的吞吐量(TPS)。
每个分区只能被一个消费者组中的一个消费者消费。
kafka同时支持两种消息投递方式 这得益于消费者与消费者组模型的契合:
若所有的消费者都隶属于同一个消费者组则所有的消息都会被均衡地投递给每一个消费者,即每条消息只会被一个消费者处理,即为点对点模式的应用(P2P,Point-to-Point)
若所有的消费者都隶属于不同的消费者组则所有的消息都会被广播给所有的消费者,即每条消息会被所有的消费者处理,即为发布订阅模式的应用(Publisher/Scribe)
消费者组是一个逻辑概念,它将旗下的消费者归为一类 每个消费者只隶属于一个消费者组。每一个消费者组都会有一个固定的名称,消费者在进行消费前需要指定其所属消费者的名称,通过参数group.id 配置,默认值是空字符串。
消费者并非逻辑上的概念,它是实际的应用案例,可以使一个线程也可以是一个进程,同一个消费者组内的消费者既可以部署于同一台服务器之上,也可以部署于不同的机器。
消费者和消费者组这种模型可以让整体的消费能力具备伸缩性,可以增加或者减少消费者个数来提高或者降低整体的消费能力。对于分区数固定的情况,一味增加消费者并不会让消费能力得到提升,若消费过多出现了消费者的个数大于分区个数就会有消费者分配不到任何分区。可以通过消费者客户端参数 partition.assignment.strategy 来设置消费者与订阅主题之间的分区策略。
重平衡(Rebalance):
消费者组里面的所有消费者实例不仅“瓜分”订阅主题的数据,而且更酷的是它们还能彼此协助。假设组内某个实例挂掉了,Kafka 能够自动检测到,然后把这个 Failed 实例之前负责的分区转移给其他活着的消费者。这个过程就是 Kafka 中大名鼎鼎的“重平衡”(Rebalance)。
Kafka适用场景:
1.消息系统:在此领域有传统的消息系统,如RabbitMQ 和ActiveMQ
2.网络行为追踪(Website Activity Tracking)
3.度量值(Metrics)
4.日志聚合(Log Aggregation)
5.流处理(Stream Processing) 类似的系统有:apache storm 和apache samza ,apache Flink
6.事件源(Event Sourcing)
7.提交的日志(Commit Log) 可以充分利用kafka的日志压缩功能(Log Compaction)
8. Internet of Things:适合于物联网的数据传递。
Kafka 的生态系统:
Kafka的生态系统日益丰富,成为大数据开发过程中必不可少的组件。
Kafka的竞品:
apache pulsar,apache Rabbit, apache RocketMQ 等